/*
* Copyright (c) 2002-2006 Samit Basu
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include "Array.hpp"
#include "mex.h"
#include "MexInterface.hpp"
template <class T, class S>
void ArrayComplexToMexComplex(T*src, S*dst_real, S*dst_imag, int count) {
for (int i=0;i<count;i++) {
dst_real[i] = (S) src[2*i];
dst_imag[i] = (S) src[2*i+1];
}
}
template <class T, class S>
void MexComplexToArrayComplex(T*src_real, T*src_imag, S*dst, int count) {
for (int i=0;i<count;i++) {
dst[2*i] = (S) src_real[i];
dst[2*i+1] = (S) src_imag[i];
}
}
template <class T, class S>
void ArrayRealToMexReal(T*src, S*dst, int count) {
for (int i=0;i<count;i++)
dst[i] = (S) src[i];
}
template <class T, class S>
void MexRealToArrayReal(T*src, S*dst, int count) {
for (int i=0;i<count;i++)
dst[i] = (S) src[i];
}
Array ArrayFromMexArrayReal(mxArray *array_ptr) {
Class cls;
Dimensions dim;
void *dp;
for (int i=0;i<array_ptr->number_of_dims;i++)
dim.set(i,array_ptr->dims[i]);
int count = mxGetNumberOfElements(array_ptr);
switch (array_ptr->classID) {
case mxUINT32_CLASS:
cls = FM_UINT32;
dp = Array::allocateArray(cls,count);
MexRealToArrayReal<uint32,uint32>((uint32*)array_ptr->realdata,
(uint32*)dp,count);
break;
case mxINT32_CLASS:
cls = FM_INT32;
dp = Array::allocateArray(cls,count);
MexRealToArrayReal<int32,int32>((int32*)array_ptr->realdata,
(int32*)dp,count);
break;
case mxUINT16_CLASS:
cls = FM_UINT16;
dp = Array::allocateArray(cls,count);
MexRealToArrayReal<uint16,uint16>((uint16*)array_ptr->realdata,
(uint16*)dp,count);
break;
case mxINT16_CLASS:
cls = FM_INT16;
dp = Array::allocateArray(cls,count);
MexRealToArrayReal<int16,int16>((int16*)array_ptr->realdata,
(int16*)dp,count);
break;
case mxUINT8_CLASS:
cls = FM_UINT8;
dp = Array::allocateArray(cls,count);
MexRealToArrayReal<uint8,uint8>((uint8*)array_ptr->realdata,
(uint8*)dp,count);
break;
case mxINT8_CLASS:
cls = FM_INT8;
dp = Array::allocateArray(cls,count);
MexRealToArrayReal<int8,int8>((int8*)array_ptr->realdata,
(int8*)dp,count);
break;
case mxSINGLE_CLASS:
cls = FM_FLOAT;
dp = Array::allocateArray(cls,count);
MexRealToArrayReal<float,float>((float*)array_ptr->realdata,
(float*)dp,count);
break;
case mxDOUBLE_CLASS:
cls = FM_DOUBLE;
dp = Array::allocateArray(cls,count);
MexRealToArrayReal<double,double>((double*)array_ptr->realdata,
(double*)dp,count);
}
return Array::Array(cls,dim,dp);
}
Array ArrayFromMexArrayComplex(mxArray *array_ptr) {
Class cls;
Dimensions dim;
void *dp;
for (int i=0;i<array_ptr->number_of_dims;i++)
dim.set(i,array_ptr->dims[i]);
int count = mxGetNumberOfElements(array_ptr);
if (array_ptr->classID != mxDOUBLE_CLASS) {
cls = FM_COMPLEX;
switch(array_ptr->classID) {
case mxUINT32_CLASS:
dp = Array::allocateArray(FM_COMPLEX,count);
MexComplexToArrayComplex<uint32,float>((uint32*)array_ptr->realdata,
(uint32*)array_ptr->imagdata,
(float*)dp,count);
break;
case mxINT32_CLASS:
dp = Array::allocateArray(FM_COMPLEX,count);
MexComplexToArrayComplex<int32,float>((int32*)array_ptr->realdata,
(int32*)array_ptr->imagdata,
(float*)dp,count);
case mxUINT16_CLASS:
dp = Array::allocateArray(FM_COMPLEX,count);
MexComplexToArrayComplex<uint16,float>((uint16*)array_ptr->realdata,
(uint16*)array_ptr->imagdata,
(float*)dp,count);
break;
case mxINT16_CLASS:
dp = Array::allocateArray(FM_COMPLEX,count);
MexComplexToArrayComplex<int16,float>((int16*)array_ptr->realdata,
(int16*)array_ptr->imagdata,
(float*)dp,count);
case mxUINT8_CLASS:
dp = Array::allocateArray(FM_COMPLEX,count);
MexComplexToArrayComplex<uint8,float>((uint8*)array_ptr->realdata,
(uint8*)array_ptr->imagdata,
(float*)dp,count);
break;
case mxINT8_CLASS:
dp = Array::allocateArray(FM_COMPLEX,count);
MexComplexToArrayComplex<int8,float>((int8*)array_ptr->realdata,
(int8*)array_ptr->imagdata,
(float*)dp,count);
break;
case mxSINGLE_CLASS:
dp = Array::allocateArray(FM_COMPLEX,count);
MexComplexToArrayComplex<float,float>((float*)array_ptr->realdata,
(float*)array_ptr->imagdata,
(float*)dp,count);
}
} else {
cls = FM_DCOMPLEX;
dp = Array::allocateArray(FM_DCOMPLEX,count);
MexComplexToArrayComplex<double,double>((double*)array_ptr->realdata,
(double*)array_ptr->imagdata,
(double*)dp,count);
}
return Array::Array(cls,dim,dp);
}
Array ArrayFromMexArray(mxArray *array_ptr) {
if (array_ptr->classID == mxCELL_CLASS) {
Dimensions dim;
for (int i=0;i<array_ptr->number_of_dims;i++)
dim.set(i,array_ptr->dims[i]);
int N = mxGetNumberOfElements(array_ptr);
mxArray** dp = (mxArray**) array_ptr->realdata;
Array* cp = new Array[N];
for (int i=0;i<N;i++)
cp[i] = ArrayFromMexArray(dp[i]);
return Array(FM_CELL_ARRAY,dim,cp);
} else {
if (array_ptr->iscomplex) {
return ArrayFromMexArrayComplex(array_ptr);
} else {
return ArrayFromMexArrayReal(array_ptr);
}
}
}
template <class mxType, class fmType>
mxArray* MexArrayFromRealArray(Array array, mxClassID classID) {
// Convert array dimensions into a simple integer array
int num_dim = array.dimensions().getLength();
int *dim_vec = (int*) malloc(sizeof(int)*num_dim);
for (int i=0;i<num_dim;i++)
dim_vec[i] = array.dimensions().get(i);
mxArray *ret = mxCreateNumericArray(num_dim,dim_vec,classID,mxREAL);
fmType *sp = (fmType*) array.getDataPointer();
mxType *dp = (mxType*) ret->realdata;
int N = mxGetNumberOfElements(ret);
for (int i=0;i<N;i++)
dp[i] = (mxType) sp[i];
free(dim_vec);
return ret;
}
template <class mxType, class fmType>
mxArray* MexArrayFromComplexArray(Array array, mxClassID classID) {
// Convert array dimensions into a simple integer array
int num_dim = array.dimensions().getLength();
int *dim_vec = (int*) malloc(sizeof(int)*num_dim);
for (int i=0;i<num_dim;i++)
dim_vec[i] = array.dimensions().get(i);
mxArray *ret = mxCreateNumericArray(num_dim,dim_vec,classID,mxCOMPLEX);
fmType *sp = (fmType*) array.getDataPointer();
mxType *dp_r = (mxType*) ret->realdata;
mxType *dp_i = (mxType*) ret->imagdata;
int N = mxGetNumberOfElements(ret);
for (int i=0;i<N;i++) {
dp_r[i] = (mxType) sp[2*i];
dp_i[i] = (mxType) sp[2*i+1];
}
free(dim_vec);
return ret;
}
mxArray* MexArrayFromCellArray(Array array) {
// Convert array dimensions into a simple integer array
int num_dim = array.dimensions().getLength();
int *dim_vec = (int*) malloc(sizeof(int)*num_dim);
for (int i=0;i<num_dim;i++)
dim_vec[i] = array.dimensions().get(i);
mxArray *ret = mxCreateCellArray(num_dim,dim_vec);
Array *sp = (Array*) array.getDataPointer();
mxArray **dp = (mxArray **) ret->realdata;
int N = mxGetNumberOfElements(ret);
for (int i=0;i<N;i++)
dp[i] = MexArrayFromArray(sp[i]);
free(dim_vec);
return ret;
}
mxArray* MexArrayFromArray(Array array) {
switch(array.dataClass()) {
case FM_FUNCPTR_ARRAY:
return NULL;
case FM_CELL_ARRAY:
return MexArrayFromCellArray(array);
case FM_STRUCT_ARRAY:
return NULL;
case FM_LOGICAL:
return MexArrayFromRealArray<mxLogical,logical>(array,mxLOGICAL_CLASS);
case FM_UINT8:
return MexArrayFromRealArray<uint8,uint8>(array,mxUINT8_CLASS);
case FM_INT8:
return MexArrayFromRealArray<int8,int8>(array,mxINT8_CLASS);
case FM_UINT16:
return MexArrayFromRealArray<uint16,uint16>(array,mxUINT16_CLASS);
case FM_INT16:
return MexArrayFromRealArray<int16,int16>(array,mxINT16_CLASS);
case FM_UINT32:
return MexArrayFromRealArray<uint32,uint32>(array,mxUINT32_CLASS);
case FM_INT32:
return MexArrayFromRealArray<int32,int32>(array,mxINT32_CLASS);
case FM_FLOAT:
return MexArrayFromRealArray<float,float>(array,mxSINGLE_CLASS);
case FM_DOUBLE:
return MexArrayFromRealArray<double,double>(array,mxDOUBLE_CLASS);
case FM_COMPLEX:
return MexArrayFromComplexArray<float,float>(array,mxSINGLE_CLASS);
case FM_DCOMPLEX:
return MexArrayFromComplexArray<double,double>(array,mxDOUBLE_CLASS);
case FM_STRING:
return MexArrayFromRealArray<mxChar,char>(array,mxCHAR_CLASS);
}
return NULL;
}
syntax highlighted by Code2HTML, v. 0.9.1