【问题标题】:how to create a single float sparse matrix in mex files如何在 mex 文件中创建单个浮点稀疏矩阵
【发布时间】:2013-12-12 19:26:53
【问题描述】:

这个Creating sparse matrix in MEXmxCreateSparse 上有一个很好的例子。但是这个函数返回一个double 稀疏矩阵而不是single。如果我想返回一个稀疏矩阵,我该怎么办?谢谢!

【问题讨论】:

  • 显然你不能。见this
  • 有趣的问题。 Matlab 的sparse 函数烦人地只支持 double 类型,所以它可能是库级别的限制。例如,sparse(single(eye(3))) 返回“未定义函数 'sparse' 用于类型 'single' 的输入参数。”
  • 你可以看看SuiteSparse库本身是否支持单精度。
  • 由于 Matlab 不了解单个稀疏矩阵是什么,即使您可以“返回”一个,它也会一蹶不振。您需要重新考虑为什么要这样做——也许根本不依赖 Matlab(在 mex 中做所有事情,根据稀疏数学的需要利用其他库)。我假设您遇到了内存问题...您可以在较小的块中执行此操作(不是一次矩阵的所有行)吗?
  • 根据您的 Matlab 版本,您可以尝试未记录的 mxCreateSparseNumericMatrix 函数 (see here)。我在 OS X 上的 R2013a 中尝试过,但我不确定它是否仍然可用,所以我不能说它做了什么。

标签: matlab sparse-matrix mex


【解决方案1】:

正如@horchler 建议的那样,您可以使用未记录的函数mxCreateSparseNumericMatrix。示例:

singlesparse.c

#include "mex.h"
#include <string.h>    /* memcpy */

/* undocumented function prototype */
EXTERN_C mxArray *mxCreateSparseNumericMatrix(mwSize m, mwSize n, 
    mwSize nzmax, mxClassID classid, mxComplexity ComplexFlag);

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
    const float pr[] = {1.0, 7.0, 5.0, 3.0, 4.0, 2.0, 6.0};
    const mwIndex ir[] = {0, 2, 4, 2, 3, 0, 4};
    const mwIndex jc[] = {0, 3, 5, 5, 7};
    const mwSize nzmax = 10;
    const mwSize m = 5;
    const mwSize n = 4;

    plhs[0] = mxCreateSparseNumericMatrix(m, n, nzmax, mxSINGLE_CLASS, mxREAL);
    memcpy((void*)mxGetPr(plhs[0]), (const void*)pr, sizeof(pr));
    memcpy((void*)mxGetIr(plhs[0]), (const void*)ir, sizeof(ir));
    memcpy((void*)mxGetJc(plhs[0]), (const void*)jc, sizeof(jc));
}

用法:

>> mex -largeArrayDims singlesparse.c

>> s = singlesparse()
s =
   (1,1)        1
   (3,1)        7
   (5,1)        5
   (3,2)        3
   (4,2)        4
   (1,4)        2
   (5,4)        6
>> ss = double(s);
>> whos s ss
  Name      Size            Bytes  Class     Attributes

  s         5x4               160  single    sparse    
  ss        5x4               152  double    sparse    

>> f = full(s)
One or more output arguments not assigned during call to "full". 
>> f = full(ss)
f =
     1     0     0     2
     0     0     0     0
     7     3     0     0
     0     4     0     0
     5     0     0     6

>> s + s;
Undefined function 'plus' for input arguments of type 'single' and attributes 'sparse 2d real'. 
>> ss + ss;
>> 2 * s;
Error using  * 
Undefined function 'times' for input arguments of type 'single' and attributes 'sparse 2d real'. 
>> 2 * ss;
>> s * s';
Error using  * 
MTIMES is not supported for one sparse input and one single input. 
>> ss * ss';

>> nnz(s)
ans =
     7
>> nzmax(s)
ans =
    10

>> dmperm(s)
Undefined function 'dmperm' for input arguments of type 'single'. 
>> dmperm(ss)
ans =
     1     3     0     5

>> svds(s)
Error using horzcat
The following error occurred converting from double to single:
Error using single
Attempt to convert to unimplemented sparse type
Error in svds (line 64)
B = [sparse(m,m) A; A' sparse(n,n)]; 
>> svds(ss)
ans =
    9.9249
    5.5807
    3.2176
    0.0000

>> % abs(s), cos(s), sin(s), s.^2, s.*s, etc.. all give errors

如您所见,稀疏单个数组已成功创建,但是许多函数期望该数组的类型为double,因此缺少很多功能...

另一个限制是您不能在 MATLAB 中创建多维稀疏数组,它们必须是二维矩阵..

底线是:在 MATLAB 中坚持使用 双稀疏二维矩阵

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-09-20
    • 2012-01-10
    • 2017-03-31
    • 2019-05-06
    • 2018-12-14
    • 2016-10-23
    • 2017-04-21
    相关资源
    最近更新 更多