summaryrefslogtreecommitdiff
path: root/2.3-1/src/c/matrixOperations/expm/zexpma.c
diff options
context:
space:
mode:
Diffstat (limited to '2.3-1/src/c/matrixOperations/expm/zexpma.c')
-rw-r--r--2.3-1/src/c/matrixOperations/expm/zexpma.c178
1 files changed, 178 insertions, 0 deletions
diff --git a/2.3-1/src/c/matrixOperations/expm/zexpma.c b/2.3-1/src/c/matrixOperations/expm/zexpma.c
new file mode 100644
index 00000000..3de35e02
--- /dev/null
+++ b/2.3-1/src/c/matrixOperations/expm/zexpma.c
@@ -0,0 +1,178 @@
+/*
+ * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+ * Copyright (C) 2008-2008 - INRIA - Allan SIMON
+ *
+ * This file must be used under the terms of the CeCILL.
+ * This source file is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at
+ * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
+ *
+ */
+
+#include "matrixExponential.h"
+
+void zexpma(doubleComplex * in, doubleComplex * out, int _iLeadDim)
+{
+ int iIndex1 = 0;
+ int iMax = 0;
+ int iFlag = 0;
+ int iLoop1 = 0;
+ int iSquare = 0;
+
+
+ double dblExp = 0;
+ double dblS = 0;
+ double dblS2 = 0;
+ double dblCst = 0.5;
+
+ doubleComplex zdblCst ;
+
+ doubleComplex *pdblMatrixA = NULL;
+ doubleComplex *pdblMatrixX = NULL;
+ doubleComplex *pdblMatrixD = NULL;
+ doubleComplex *pdblMatrixcX = NULL;
+ doubleComplex *pdblMatrixcA = NULL;
+ doubleComplex *pdblMatrixEye = NULL;
+ doubleComplex *pdblMatrixTemp = NULL;
+ doubleComplex *pdblMatrixTemp2 = NULL;
+
+
+
+
+ iSquare = _iLeadDim * _iLeadDim;
+
+ pdblMatrixA = (doubleComplex*)malloc(sizeof(doubleComplex) * (unsigned int) iSquare);
+ pdblMatrixX = (doubleComplex*)malloc(sizeof(doubleComplex) * (unsigned int) iSquare);
+ pdblMatrixD = (doubleComplex*)malloc(sizeof(doubleComplex) * (unsigned int) iSquare);
+ pdblMatrixcX = (doubleComplex*)malloc(sizeof(doubleComplex) * (unsigned int) iSquare);
+ pdblMatrixcA = (doubleComplex*)malloc(sizeof(doubleComplex) * (unsigned int) iSquare);
+ pdblMatrixEye = (doubleComplex*)malloc(sizeof(doubleComplex) * (unsigned int) iSquare);
+ pdblMatrixTemp = (doubleComplex*)malloc(sizeof(doubleComplex) * (unsigned int) iSquare);
+ pdblMatrixTemp2 = (doubleComplex*)malloc(sizeof(doubleComplex) * (unsigned int) iSquare);
+
+ zdblCst = DoubleComplex ( 0.5 , 0 );
+
+ /*// Scale A by power of 2 so that its norm is < 1/2 .*/
+ dfrexps( zinfnorma( in, _iLeadDim, _iLeadDim) , &dblExp);
+ dblS = max(0, dblExp + 1);
+ dblS2 = pow(2, dblS);
+
+ /*A = A./2^s */
+
+ for ( iIndex1 = 0 ; iIndex1 < iSquare ; iIndex1++ )
+ pdblMatrixA[iIndex1] = zrdivs ( in[iIndex1] , DoubleComplex ( dblS2 , 0 ));
+
+
+ /* Pade approximation for exp(A)
+ //X = A */
+ /*C2F(zcopy)(&iSquare, pdblMatrixA, &iOne, pdblMatrixX, &iOne );*/
+ for ( iIndex1 = 0 ; iIndex1 < iSquare ; iIndex1++ )
+ pdblMatrixX[iIndex1] = pdblMatrixA[iIndex1] ;
+
+
+ zeyea(pdblMatrixEye, _iLeadDim, _iLeadDim);
+
+ /* zmulma ( & zdblCst , 1 ,1,
+ pdblMatrixA , _iLeadDim, _iLeadDim,
+ pdblMatrixcA);*/
+
+ for ( iIndex1 = 0 ; iIndex1 < iSquare ; iIndex1++ )
+ pdblMatrixcA[iIndex1] = zmuls ( pdblMatrixA[iIndex1] , zdblCst ) ;
+
+ /* cA = A * c */
+
+
+ /*E = Eye + cA*/
+
+ zadda (pdblMatrixEye , iSquare, pdblMatrixcA ,iSquare, out ) ;
+
+ /* D = Eye - cA */
+
+ zdiffa (pdblMatrixEye , iSquare, pdblMatrixcA ,iSquare,pdblMatrixD ) ;
+
+ iMax = 6;
+ iFlag = 1;
+
+ for(iLoop1 = 2 ; iLoop1 <= iMax ; iLoop1++)
+ {
+ dblCst = dblCst * (iMax - iLoop1 + 1 ) / (iLoop1 * (2 * iMax - iLoop1 + 1));
+ zdblCst = DoubleComplex( dblCst , 0);
+
+ /*Temp = X */
+ /*C2F(zcopy)(&iSquare, pdblMatrixX, &iOne, pdblMatrixTemp, &iOne);*/
+ for ( iIndex1 = 0 ; iIndex1 < iSquare ; iIndex1++ )
+ pdblMatrixTemp[iIndex1] = pdblMatrixX[iIndex1] ;
+ /* X = A * Temp; */
+
+ zmulma ( pdblMatrixA , _iLeadDim , _iLeadDim,
+ pdblMatrixTemp , _iLeadDim , _iLeadDim,
+ pdblMatrixX );
+ /* cX = c * X */
+
+ /* zmulma ( & zdblCst , 1 ,1,
+ pdblMatrixX , _iLeadDim, _iLeadDim,
+ pdblMatrixcX);*/
+
+ for ( iIndex1 = 0 ; iIndex1 < iSquare ; iIndex1++ )
+ pdblMatrixcX[iIndex1] = zmuls ( pdblMatrixX[iIndex1] , zdblCst ) ;
+
+ /* E = E + cX */
+
+ zadda ( out, iSquare , pdblMatrixcX , iSquare , out ) ;
+
+ if(iFlag == 1) /* D = D + cX */
+ {
+ zadda ( pdblMatrixD, iSquare , pdblMatrixcX , iSquare , pdblMatrixD ) ;
+ }
+ else /* D = D - cX */
+ {
+ zdiffa ( pdblMatrixD, iSquare , pdblMatrixcX , iSquare , pdblMatrixD );
+ }
+
+ /* Toggle iFlag */
+ iFlag = !iFlag;
+ }
+
+ /* Temp = E */
+ /*C2F(zcopy)(&iSquare, out, &iOne, pdblMatrixTemp, &iOne);*/
+ for ( iIndex1 = 0 ; iIndex1 < iSquare ; iIndex1++ )
+ pdblMatrixTemp[iIndex1] = out[iIndex1] ;
+
+ /* E = D\E */
+ zldivma ( pdblMatrixD , _iLeadDim , _iLeadDim , pdblMatrixTemp , _iLeadDim , _iLeadDim , out ) ;
+
+ /*/ Undo scaling by repeated squaring */
+ for(iLoop1 = 0 ; iLoop1 < dblS ; iLoop1++)
+ {
+ /*//Temp = E */
+ /*//Temp2 = E */
+
+ /*C2F(zcopy)(&iSquare, out, &iOne, pdblMatrixTemp, &iOne);
+ C2F(zcopy)(&iSquare, out, &iOne, pdblMatrixTemp2, &iOne);*/
+ for ( iIndex1 = 0 ; iIndex1 < iSquare ; iIndex1++ )
+ {
+ pdblMatrixTemp [iIndex1] = out[iIndex1] ;
+ pdblMatrixTemp2[iIndex1] = out[iIndex1] ;
+ }
+
+ /* E = E*E*/
+ zmulma ( pdblMatrixTemp , _iLeadDim , _iLeadDim,
+ pdblMatrixTemp2 , _iLeadDim , _iLeadDim,
+ out );
+
+ }
+
+ free(pdblMatrixA);
+ free(pdblMatrixX);
+ free(pdblMatrixD);
+ free(pdblMatrixcX);
+ free(pdblMatrixcA);
+ free(pdblMatrixEye);
+ free(pdblMatrixTemp);
+ free(pdblMatrixTemp2);
+
+
+
+ return ;
+}