/*------------------------------------------------------------------------------* * File Name: matrix.h * * Creation: TCZ 07/22/2001 * * Purpose: Origin C internal utility classes * * Copyright (c) OriginLab Corp.2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 * * All Rights Reserved * * * * Modification Log: * * ER 01/29/03 QA70_3802 ADD_VECTOR_FFT_IFFT * *------------------------------------------------------------------------------*/ #ifndef _MATRIX_H #define _MATRIX_H /* ////////////////////////////////////////////////////////////////////////////////////// This header file will contain some matrix related global functions implemented in originC level. We already have some functions implemented as member functions of the matrix class internally. To complement those functions, we add some necessary but not as basic as the member functions here. */ //declare error here #define FFT_ERROR_COULUMN_ROW_NUMBER_NEGATIVE (-1) #define FFT_ERROR_SOURCE_MATRIX_EMPTY (-2) #define FFT_ERROR_GETSUBMATRIX_FUNCTION_ERROR (-3) #define FFT_ERROR_GETREAL_FUNCTION_FAIL (-4) /** >Analysis This function performs a 2-dimensional Fast Fourier Transform. Remarks: Data matrix should be of type double. If user have the data matrix in integer form, user should first transform it to double using the member function of matrixbase "CastToDouble". Example: This example computes the 2 dimension fast fourier transform of the matrix mRe. #include void test_FFT2() { matrix mRe = {{-1.486782,-0.530723,0.139563,-1.018762}, {-0.831440 ,0.938971,-0.760729,1.620196}, {- 0.7794,-0.5500 ,0.6640, -0.4333}, {-2.0366,1.9275,0.3313,1.1098}}; matrix mResult; int ii,jj,Err; //test function FFT2 for arbitrary source matrix Err = FFT2(mRe, mResult); if ( 0 != Err ) { ASSERT(false); printf("two-dimension FFT2 fails\n"); } else { for(ii = 0; ii < mResult.GetNumRows(); ii++) { for(jj = 0; jj < mResult.GetNumCols(); jj++) printf("(%f, %fi) ",mResult[ii][jj].m_re,mResult[ii][jj].m_im); printf("\n"); } } } The output is as following: (-0.424101, 0.000000i) (-1.377089, -0.126954i) (-1.955942, 0.000000i) (-1.377089, 0.126954i) (-0.449501, 0.091251i) (0.328995, -0.725482i) (-0.166409, -0.147816i) (-0.420468, -0.423113i) (-1.573601, 0.000000i) (-0.157784, -0.058716i) (2.491026, 0.000000i) (-0.157784, 0.058716i) (-0.449501, -0.091251i) (-0.420468, 0.423113i) (-0.166409, 0.147816i) (0.328995, 0.725482i) Parameters: matSource: The data source matrix matFFT2Result: The matrix containing the 2 dimension FFT results nRowProcess: nColProcess: The number of rows or columns user provided. If they are -1, there is no padding or truncating. If they are more than the sizes of the matrix, the function will pad zero to meet the size If less than, it will truncate the data matrix. Return: If succeed, it will return 0; Otherwise it returns error indications. Error: -1: Provided column number or row number. Must be -1 or positive integer -2: The data source matrix is empty -3: When calling member function, it fails. -4: When calling GetReal or GetImage member function of matrix class, it failed. Nag Error: 11: The column or the row size of matrix is less then 1 73: System failed to allocate memory */ int FFT2(matrix& matSource, matrix& matFFT2Result, int nRowProcess = -1, int nColProcess = -1); /** >Analysis This function performs a 2-dimensional Fast Fourier Transform. Remarks: Data matrix should be of type complex. If user have the data matrix in integer form, user should first transform it to complex. Example: This example computes the 2 dimension fast fourier transform of the matrix mSource. void test_FFT2() { matrix mRe = {{-1.486782,-0.530723,0.139563,-1.018762}, {-0.831440 ,0.938971,-0.760729,1.620196}, {- 0.7794,-0.5500 ,0.6640, -0.4333}, {-2.0366,1.9275,0.3313,1.1098}}; matrix mIm = {{2.482,3.5723,0.9553,-1.01842}, {-1.8317 ,4.38271,-1.0729,1.226}, {0.7724,-0.5540 ,1.540, -1.333}, {2.0456,-1.935,2.6513,1.2708}}; matrix mSource, mResult; mSource.MakeComplex(mRe,mIm); int ii,jj,Err; //test function FFT2 for arbitrary source matrix Err = FFT2(mSource, mResult); if ( 0 != Err ) { ASSERT(false); printf("two-dimension FFT2 fails\n"); } else { for(ii = 0; ii < mResult.GetNumRows(); ii++) { for(jj = 0; jj < mResult.GetNumCols(); jj++) printf("(%f, %fi) ",mResult[ii][jj].m_re,mResult[ii][jj].m_im); printf("\n"); } } } The output is as following: (-0.424101, 3.288348i) (-0.046932, -0.278304i) (-1.955942, 0.482652i) (-2.707247, -0.024397i) (-0.781648, 1.482696i) (1.243650, -1.742534i) (-3.635011, -0.976811i) (-1.411672, 1.741090i) (-1.573601, -0.080057i) (1.196919, 0.472184i) (2.491026, 2.058758i) (-1.512486, 0.589616i) (-0.117354, 1.300194i) (0.570738, 2.587315i) (3.302194, -0.681179i) (-0.585660, -0.291571i) Parameters: matSource: The data source matrix matFFT2Result: The matrix containing the 2 dimension FFT results nRowProcess: nColProcess: The number of rows or columns user provided. If they are -1, there is no padding or truncating. If they are more than the sizes of the matrix, the function will pad zero to meet the size If less than, it will truncate the data matrix. Return: If succeed, it will return 0; Otherwise it returns error indications. Error: -1: Provided column number or row number. Must be -1 or positive integer -2: The data source matrix is empty -3: When calling member function, it fails. -4: When calling GetReal or GetImage member function of matrix class, it failed. Nag Error: 11: The column or the row size of matrix is less then 1 73: System failed to allocate memory */ int FFT2(matrix& matSource, matrix& matFFT2Result, int nRowProcess = -1, int nColProcess = -1); /** >Analysis This function performs a 2-dimensional inverse Fast Fourier Transform. Remarks: Data matrix should be of type complex. If user have the data matrix in integer form, user should first transform it to complex. Example: This example computes the 2 dimension inverse fast fourier transform of the matrix mSource. void test_IFFT2() { matrix mRe = {{-1.486782,-0.530723,0.139563,-1.018762}, {-0.831440 ,0.938971,-0.760729,1.620196}, {- 0.7794,-0.5500 ,0.6640, -0.4333}, {-2.0366,1.9275,0.3313,1.1098}}; matrix mIm = {{2.482,3.5723,0.9553,-1.01842}, {-1.8317 ,4.38271,-1.0729,1.226}, {0.7724,-0.5540 ,1.540, -1.333}, {2.0456,-1.935,2.6513,1.2708}}; matrix mSource, mResult; mSource.MakeComplex(mRe,mIm); int ii,jj,Err; Err = IFFT2(mSource, mResult); if ( 0 != Err ) { ASSERT(false); printf("two-dimension IFFT2 fails\n"); } else { for(ii = 0; ii < mResult.GetNumRows(); ii++) { for(jj = 0; jj < mResult.GetNumCols(); jj++) printf("(%f, %fi) ",mResult[ii][jj].m_re,mResult[ii][jj].m_im); printf("\n"); } } } The output is as following: (-0.424101, 3.288348i) (-2.707247, -0.024397i) (-1.955942, 0.482652i) (-0.046932, -0.278304i) (-0.117354, 1.300194i) (-0.585660, -0.291571i) (3.302194, -0.681179i) (0.570738, 2.587315i) (-1.573601, -0.080057i) (-1.512486, 0.589616i) (2.491026, 2.058758i) (1.196919, 0.472184i) (-0.781648, 1.482696i) (-1.411672, 1.741090i) (-3.635011, -0.976811i) (1.243650, -1.742534i) Parameters: matSource: The data source matrix matIFFT2Result: The matrix containing the 2 dimension inverse FFT results nRowProcess: nColProcess:The number of rows or columns user provided. if they are -1, there are no padding or truncating. if they are larger than the size of the matrix, the function will pad zero to meet the size. If less than, it will truncate the data matrix. Return: If succeed, it will return 0; Otherwise it returns error indications. Error: -1: Provided column number or row number. Must be -1 or positive integer -2: The data source matrix is empty -3: When calling member function, it fails. -4: When calling GetReal or GetImage member function of matrix class, it failed. Nag Error: 11: The column or the row size of matrix is less then 1 73: System failed to allocate memory */ int IFFT2(matrix& matSource, matrix& matIFFT2Result, int nRowProcess = -1, int nColProcess = -1); /** >Analysis These two Functions will do the 1 dimension Fast Fourier Transform. Remarks: Data matrix should be of type double. If user have the data matrix in integer form, user should first transform it to double using the member function of matrixbase "CastToDouble". Example: This example computes the 1 dimension fast fourier transform on each row of the matrix mRe. void test_FFT() { matrix mRe = {{1,2.5,3.5,2,1.0,2.3},{3.2,4.1,2.2,1.0,4,2}}; int ii , jj; matrix mResult; //test 1d fft function for arbitrary source matrix.// int Err = FFT(mRe, mResult, -1); if ( 0 != Err ) { ASSERT(false); printf("one-dimension FFT fails.\n"); } else { for(ii = 0; ii < mResult.GetNumRows(); ii++) { for(jj = 0; jj < mResult.GetNumCols(); jj++) printf("(%f, %fi) ",mResult[ii][jj].m_re,mResult[ii][jj].m_im); printf("\n"); } } } The output is as following: (5.021454, 0.000000i) (-0.347011, -0.954594i) (-0.673610, 0.813173i) (-0.530723, 0.000000i) (-0.673610, -0.813173i) (-0.347011, 0.954594i) (6.736097, 0.000000i) (0.877734, -0.106066i) (-0.796084, -1.378858i) (0.938971, 0.000000i) (-0.796084, 1.378858i) (0.877734, 0.106066i) Parameters: matSource: The data source matrix matFFTResult: The matrix containing the 1 dimension FFT results nColProcess: The number of columns user provided. If it is -1, function will not do any padding or truncating. But if it is larger than the size of the matrix, it will pad zero to meet the size if less than, it will truncate the data matrix. Return: If succeed, it will return 0; Otherwise it returns error indications. Error: -1: Provided column number or row number. Must be -1 or positive integer -2: The data source matrix is empty -3: When calling member function, it fails. -4: When calling GetReal or GetImage member function of matrix class, it failed. Nag Error: 11: The column or the row size of matrix is less then 1 73: System failed to allocate memory */ int FFT(matrix& matSource, matrix& matFFTResult, int nColProcess = -1); /** >Analysis This function performs 1-dimensional Fast Fourier Transform on each row of data in a matrix. Remarks: Data matrix should be of type complex. If user have the data matrix in integer form, user should first transform it to complex. Example: This example computes the 1 dimension fast fourier transform on each row of the matrix mSource. void FFT_test() { matrix mRe = {{1,2.5,3.5,2,1.0,2.3},{3.2,4.1,2.2,1.0,4,2}}; matrix mIm = {{1,0.5,1.0,0.8,3.1,0.3},{2.2,3.2,3.0,1.5,2,2.1}}; int ii , jj; matrix mSource, mResult; mSource.MakeComplex(mRe,mIm); //test 1d fft function for complex source matrix.// int Err = FFT(mSource, mResult); if ( 0 != Err ) { ASSERT(false); printf("one-dimension FFT fails\n"); } else { for(ii = 0; ii < mResult.GetNumRows(); ii++) { for(jj = 0; jj < mResult.GetNumCols(); jj++) printf("(%f, %fi) ",mResult[ii][jj].m_re,mResult[ii][jj].m_im); printf("\n"); } } } The output is as following: (5.021454, 2.735264i) (-1.018762, -1.546554i) (0.139563, 0.547811i) (-0.530723, 1.428869i) (-1.486782, -1.078534i) (0.324740, 0.362634i) (6.736097, 5.715476i) (1.620196, 0.240945i) (-0.760729, -1.970818i) (0.938971, 0.163299i) (-0.831440, 0.786898i) (0.135272, 0.453077i) Parameters: matSource: The data source matrix matFFTResult: The matrix containing the 1 dimension FFT results nColProcess: The number of columns user provided. If it is -1, function will not do any padding or truncating. But if it is larger than the size of the matrix, it will pad zero to meet the size if less than, it will truncate the data matrix. Return: If succeed, it will return 0; Otherwise it returns error indications. Error: -1: Provided column number or row number. Must be -1 or positive integer -2: The data source matrix is empty -3: When calling member function, it fails. -4: When calling GetReal or GetImage member function of matrix class, it failed. Nag Error: 11: The column or the row size of matrix is less then 1 73: System failed to allocate memory */ int FFT(matrix& matSource, matrix& matFFTResult, int nColProcess = -1); /** >Analysis This function performs 1-dimensional inverse Fast Fourier Transform on each row of data in a matrix. Remarks: Data matrix should be of type complex. If user have the data matrix in integer form, user should first transform it to complex. Example: int test_IFFT() { matrix matSource = {{1,2,3,4,5},{6,7,8,9,10}}; int nRet; matrix matResult; nRet = FFT(matSource,matResult, -1); if(nRet) return nRet; int nNumCols = matResult.GetNumCols(); int nNumRows = matResult.GetNumRows(); int ii, jj; for( ii = 0; ii < nNumRows; ii++) { for(jj = 0; jj < nNumCols; jj++) printf("%f + %f i",matResult[ii][jj].m_re, matResult[ii][jj].m_im); printf("\n"); } printf("now do the padding\n"); nRet = FFT(matSource,matResult, 14); if(nRet) return nRet; //after The padding nNumCols = matResult.GetNumCols(); nNumRows = matResult.GetNumRows(); for( ii = 0; ii < nNumRows; ii++) { for(jj = 0; jj < nNumCols; jj++) printf("%f + %f i",matResult[ii][jj].m_re, matResult[ii][jj].m_im); printf("\n"); } printf("now do the truncting\n"); //after truncting nRet = FFT(matSource,matResult, 6); if(nRet) return nRet; nNumCols = matResult.GetNumCols(); nNumRows = matResult.GetNumRows(); for( ii = 0; ii < nNumRows; ii++) { for(jj = 0; jj < nNumCols; jj++) printf("%f + %fi ",matResult[ii][jj].m_re, matResult[ii][jj].m_im); printf("\n"); } return nRet; } Parameters: matSource:The data source matrix matIFFT2Result: The matrix containing the 1 dimension inverse FFT results nColProcess:The number of columns user provided. if it is -1, there is no padding or truncating. if it is more than the size of the matrix, it will pad zero to meet the size if less than, it will truncate the data matrix. Return: If succeed, it will return 0; Otherwise it returns error indications. Error: -1: Provided column number or row number must be -1 or positve integer -2: The data source matrix is empty -3: When calling member function, it fails. -4: When calling GetReal or GetImage member function of matrix class, it failed. Nag Error: 11: The coloumn or the row size of matrix is less then 1; 73: System failed to allocate memory */ // ER 01/29/03 QA70_3802 ADD_VECTOR_FFT_IFFT int IFFT(matrix& matSource, matrix& matFFTResult, int nColProcess = -1); /** >Analysis This function performs 1-dimensional Fast Fourier Transform on data in a complex vector. Remarks: Data vector should be of type complex. If user have the data vector in integer or double form, user should first transform it or copy it to a complex vector. This function in turn calls the matrix-based FFT function. Example: This example computes the 1-dimensional Fast Fourier Transform on a complex vector void FFT_test() { vector vR = { 1,2.5,3.5,2,1.0,2.3 }; vector vI = { 1,0.5,1.0,0.8,3.1,0.3 }; vector vC(vR, vI), vResult(vC.GetSize()); //tedt 1d fft function on data in a complex vector int Err = FFT(vC, vResult); if ( 0 != Err ) { ASSERT(false); printf("one-dimension FFT fails\n"); } else { for(int ii = 0; ii < vResult.GetSize(); ii++) { printf("(%f, %fi) ",vResult[ii].m_re,vResult[ii].m_im); printf("\n"); } } } The output is as following: (5.021454, 2.735264i) (-1.018762, -1.546554i) (0.139563, 0.547811i) (-0.530723, 1.428869i) (-1.486782, -1.078534i) (0.324740, 0.362634i) Parameters: vecSource: The data source vector vecFFTResult: The vector containing the 1-dimensional FFT result Return: If succeed, it will return 0; Otherwise it returns error indications. Error: -5: source vector is of zero length n: other error codes returned by matrix-based FFT function */ // ER 01/29/03 QA70_3802 ADD_VECTOR_FFT_IFFT int FFT(vector& vecSource, vector& vecFFTResult); /** >Analysis This function performs 1-dimensional inverse Fast Fourier Transform on data in a complex vector. Remarks: Data vector should be of type complex. If user have the data vector in integer or double form, user should first transform it or copy it to a complex vector. This function in turn calls the matrix-based FFT function. Example: int test_IFFT() { vector vR = { 1,2.5,3.5,2,1.0,2.3 }; vector vI = { 1,0.5,1.0,0.8,3.1,0.3 }; vector vC(vR, vI), vResult(vC.GetSize()); //tedt 1d ifft function on data in a complex vector int Err = IFFT(vC, vResult); if ( 0 != Err ) { ASSERT(false); printf("one-dimension IFFT fails\n"); } else { for(int ii = 0; ii < vResult.GetSize(); ii++) { printf("(%f, %fi) ",vResult[ii].m_re,vResult[ii].m_im); printf("\n"); } } } The output is as following: (5.021454, 2.735264i) (0.324740, 0.362634i) (-1.486782, -1.078534i) (-0.530723, 1.428869i) (0.139563, 0.547811i) (-1.018762, -1.546554i) Parameters: vecSource:The data source vector vecIFFTResult: The vector containing the 1-dimensional inverse FFT results Return: If succeed, it will return 0; Otherwise it returns error indications. Error: -5: source vector is of zero length n: other error codes returned by matrix-based FFT function */ int IFFT(vector& vecSource, vector& vecFFTResult); /** >Analysis These four functions are used to do the singular value decomposition. matSource = matU* matS* matV' Example: int test_SVD() { matrix matData= { { 2, 2.5, 2.5}, {2.0, 2.5, 2.5}, {1.6, -0.4, 2.8}, {2.0, -0.5, 0.5}, {1.2, -0.3, -2.9}}; printf("The source data\n"); int nNumCols = matData.GetNumCols(); int nNumRows = matData.GetNumRows(); int ii, jj; for( ii = 0; ii < nNumRows; ii++) { for(jj = 0; jj < nNumCols; jj++) printf("%f ",matData[ii][jj]); printf("\n"); } matrix matS; printf("Find the singular value\n"); int nRet; if(nRet = SVD(matData, matS)) return nRet; nNumCols = matS.GetNumCols(); nNumRows = matS.GetNumRows(); for( ii = 0; ii < nNumRows; ii++) { for(jj = 0; jj < nNumCols; jj++) printf("%f ",matS[ii][jj]); printf("\n"); } printf("Find the U and V\n"); matrix matU, matV; if(nRet = SVD(matData, matS, matU, matV)) return nRet; printf("U is\n"); nNumCols = matU.GetNumCols(); nNumRows = matU.GetNumRows(); for( ii = 0; ii < nNumRows; ii++) { for(jj = 0; jj < nNumCols; jj++) printf("%f ",matU[ii][jj]); printf("\n"); } printf("V is \n"); nNumCols = matV.GetNumCols(); nNumRows = matV.GetNumRows(); for( ii = 0; ii < nNumRows; ii++) { for(jj = 0; jj < nNumCols; jj++) printf("%f ",matV[ii][jj]); printf("\n"); } return nRet; } Parameters: matSource: The m * n source data matrix matS: The min(m, n) diaganol sigular matrix matU: The left side m * m unitary matrix matV: The right side n* n unitary matrix return: if succeed, it will return 0 */ int SVD(matrix& matSource, matrix& matS, matrix& matU, matrix& matV); /** >Analysis */ int SVD(matrix& matSource, matrix& matS); /** >Analysis */ int SVD(matrix& matSource, matrix& matS); /** >Analysis */ int SVD(matrix& matSource, matrix& matS, matrix& matU, matrix& matV); /** >Analysis These four functions will give the trace of a matrix Remarks: we do not support every matrix type. Example: int test_Trace() { matrix matSource = {{1,2,3},{5,6,7},{9,10,11}}; printf("the source matrix\n"); int ii, jj; int nNumCols = matSource.GetNumCols(); int nNumRows = matSource.GetNumRows(); for(ii = 0; ii < nNumRows; ii++) { for(jj = 0; jj < nNumCols; jj++) printf("%f ",matSource[ii][jj]); printf("\n"); } int nRet; double dTrace; if(nRet = Trace(matSource, dTrace)) return nRet; printf("The trace is: %f",dTrace); return nRet; } Parameters: matSource: The source matrix nSum: dSum: cSum: These are the variables to store the trace. Return: if succeed, it will return 0 */ int Trace(matrix & matSource, int & nSum); /** >Analysis */ int Trace(matrix & matSource, int & nSum); /** >Analysis */ int Trace(matrix & matSource, double & dSum); /** >Analysis */ int Trace(matrix & matSource, complex & cSum); //define a structure here to hold the summary results from the nag typedef struct tagMatrixStats { int nMissingValue; //hold the number of missing value double dMean;//hold the mean value; double dSD; //hold the standard deviation double dMax; //hold the maximun value; double dMin; //hold the minimum value; double dMedian;//hold the median value double dLowHinge; //hold the lower hinge double dUpHinge; //hold the upper hinge double dWSum; //hold the sum of the weights }MatrixStats; #define MAT_ERR_WEIGHTS_DATA_SIZE_NOT_MATCH (-5) /** >Statistics This function will give the summary of the statistics of a source data contained in a matrix Remarks: If data does not have the weight, then the default weight 1 will be used Example: int test_Matrix_Stat_summary() { MatrixStats sMatStatsSum; matrix mData = {{193.0, 215.0, 112.0, 161.0}, {92.0, 140.0, 38.0, 33.3}, {279.0, 249.0, 473.0, 339.0}, {60.0, 130.0, 20.0, 50.0}, {257.0, 284.0, 447.0, 52.0}, {67.0, 61.0, 150.0, 2220.0}}; matrix mWeights; int nNumCols = mData.GetNumCols(); int nNumRows = mData.GetNumRows(); mWeights.SetSize(nNumRows, nNumCols); mWeights = 1; int nRet; if(nRet = MatrixBasicStats(mData, sMatStatsSum, &mWeights)) return nRet; printf("Number of cases is %d\n", sMatStatsSum.nMissingValue); printf("And there is no weight\n"); printf("The input is following : x=\n"); for(int ii = 0; ii < nNumRows; ii++) { for(int jj = 0; jj < nNumCols; jj++) printf("%10.1f", mData[ii][jj]); printf("\n"); } printf("\nsucess is%d\n", nRet); if(nRet == 0) { printf("\nsucessfully call of the nag_summary_stats_1var function\n"); printf("the output is following:\n"); printf("No of missing cases %10d\n", sMatStatsSum.nMissingValue); printf("mean %10.1f\n", sMatStatsSum.dMean); printf("std devn %10.1f\n", sMatStatsSum.dSD); printf("Minimun %10.1f\n", sMatStatsSum.dMin); printf("Maximum %10.1f\n", sMatStatsSum.dMax); printf("Sum of weights %10.1f\n", sMatStatsSum.dWSum); } else { printf(" \n There are some problems."); } return nRet; } Parameters: mData: The Data Source sMatStatsSum: The Results mpWeights: The pointer to a weight matrix if any Return: Return 0 if succeed. MAT_ERR_WEIGHTS_DATA_SIZE_NOT_MATCH: The weight matrix sizes do not match those of the source */ int MatrixBasicStats(matrix & mData, MatrixStats & sMatStatsSum, matrix * mpWeights = NULL); #endif //_MATRIX_H