2014-10-06 68 views
1

我有一個接受雙矩陣作爲輸入的mex函數,但我只是意識到這個函數用於代碼,也可以有單精度矩陣。是否有可能允許函數接受?MATLAB Mex函數可以接受單個和雙重嗎?

如果不是,那麼解決此問題的另一種方法是什麼?

+0

轉換的輸入端,具有不同的代碼路徑在MEX,和/或試圖使用C++模板。你能提供更多細節嗎? – chappjc 2014-10-06 16:39:20

+0

@chappjc它就像聽起來一樣,我有一個mex函數,它應該採取單個或雙重,但我不知道如何讓它接受兩個。例如,截至目前它只接受雙打作爲輸入,這意味着如果我嘗試輸入一個單精度矩陣,它將會出錯。 – 2014-10-06 17:09:00

回答

1

簡單的解決方案是將MATLAB中的輸入轉換爲一致的類型(假設是雙精度型),但是如果您希望讓MEX函數處理多種類型,這裏有一種方法。

檢查輸入類型爲mxIsSinglemxIsDouble(或mxIsClass)並相應地處理它。您可能在mexFunction中有if語句,它們設置輸入和輸出,然後調用模板函數。請參閱下面的示例,該閾值使用C++標準庫函數模板std::min<T>閾值數組中的所有值,而不需要任何數據轉換。

flexibleFunction.cpp

#include "mex.h" 
#include <algorithm> // std::min 

template <typename T> 
void threshArrayLT(T *out, const T *arr, mwSize n, T c) 
{ // you allocate out 
    for (mwSize i = 0; i < n; ++i) 
     out[i] = std::min<T>(arr[i], c); 
} 

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) 
{ 
    if (nlhs > 1 || nrhs != 2) 
     mexErrMsgTxt("Syntax:\n\tH = flexibleFunction(arr,c)"); 

    if (!mxIsDouble(prhs[0]) && !mxIsSingle(prhs[0])) 
     mexErrMsgTxt("Array must be double or single."); 

    if ((mxIsDouble(prhs[0]) && !mxIsDouble(prhs[1])) || 
      (mxIsSingle(prhs[0]) && !mxIsSingle(prhs[1]))) 
     mexErrMsgTxt("Arguments must have same type."); 

    const mwSize* dims = mxGetDimensions(prhs[0]); 
    int ndims = static_cast<int>(mxGetNumberOfDimensions(prhs[0])); 
    size_t numel = mxGetNumberOfElements(prhs[0]); 

    if (mxIsDouble(prhs[0])) { 
     double *arr = mxGetPr(prhs[0]); 
     double c = mxGetScalar(prhs[1]); 
     plhs[0] = mxCreateNumericArray(ndims,dims,mxDOUBLE_CLASS,mxREAL); 
     threshArrayLT(mxGetPr(plhs[0]),arr,numel,c); 
     // In reality, if it's this simple, use std::transform with lambda or bind: 
     //std::transform(arr, arr+numel, mxGetPr(plhs[0]), 
     // [&](double s){ return std::min(s,c); }); 
    } else if (mxIsSingle(prhs[0])) { 
     float *arr = (float*)mxGetData(prhs[0]); 
     float c = static_cast<float>(mxGetScalar(prhs[1])); 
     plhs[0] = mxCreateNumericArray(ndims,dims,mxSINGLE_CLASS,mxREAL); 
     threshArrayLT((float*)mxGetData(plhs[0]),arr,numel,c); 
    } 
} 

您也可以使用C++(名稱相同,不同的參數類型)函數重載。

>> v = rand(1,8); c = 0.5; 
>> whos v c 
    Name  Size   Bytes Class  Attributes 

    c   1x1     8 double    
    v   1x8    64 double   


>> flexibleFunction(v,c) 
ans = 
    0.2760 0.5000 0.5000 0.1626 0.1190 0.4984 0.5000 0.3404 
>> flexibleFunction(single(v),single(c)) 
ans = 
    0.2760 0.5000 0.5000 0.1626 0.1190 0.4984 0.5000 0.3404 
+0

但是如果我正在使用MATLAB的編碼器工具包直接從matlab代碼創建mex文件會怎麼樣。構建器要求我定義一個輸入類型,然後才能將其轉換爲mex。有沒有辦法做你所描述的,但與編碼器工具包?消除中間的C++部分。 – 2014-10-06 18:21:08

+0

@GBoggs我對編碼器不是很熟悉,但它聽起來好像無法處理它。在你的問題中,你沒有提到編碼器,所以我認爲你正在編寫MEX功能。我不會破解編碼器輸出源。 – chappjc 2014-10-06 18:33:16

相關問題