00001
00004
00005
00006 #ifndef TBCI_SOLVER_EXPM_H
00007 #define TBCI_SOLVER_EXPM_H
00008
00009 #include "../basics.h"
00010 #include "../matrix.h"
00011
00012 NAMESPACE_TBCI
00013
00014 INST(template < Matrix<T> > class NN friend double norm_1 (const Matrix<T>&);)
00015 INST(template <BdMatrix<T> > class NN friend double norm_1 (const BdMatrix<T>&);)
00016
00017 template <typename Matrix>
00018 double norm_1(const Matrix& mat)
00019 {
00020 double max = 0;
00021 double sum;
00022
00023 for (unsigned int i=0; i<mat.rows(); ++i) {
00024 sum = MATH__ fabs(mat.get(i, 0));
00025 for (unsigned int j=1; j<mat.columns(); ++j)
00026 sum += MATH__ fabs(mat.get(i, j));
00027 max = MAX(max, sum);
00028 }
00029 return max;
00030 }
00031
00033 INST(template <typename T> class TMatrix friend double norm_1 (const TMatrix<T>&);)
00034 template <typename T>
00035 double norm_1 (const TMatrix<T>& mat)
00036 {
00037 double max = 0;
00038 double sum;
00039
00040 for (unsigned int i=0; i<mat.rows(); ++i) {
00041 sum = MATH__ fabs(mat.get(i, 0));
00042 for (unsigned int j=1; j<mat.columns(); ++j)
00043 sum += MATH__ fabs(mat.get(i, j));
00044 max = MAX(max, sum);
00045 }
00046 mat.mark_destroy();
00047 return max;
00048 }
00049
00050 INST(template < Matrix<T> > class NN friend void expm (const Matrix<T>&, Matrix<T>&);)
00051
00052
00053
00054
00055
00056 template<typename Matrix>
00057 void expm (const Matrix& exponent, Matrix& E)
00058 {
00059
00060 Matrix temp(exponent);
00061
00062 unsigned int dim = exponent.rows();
00063 int e,p,q,k;
00064
00065
00066
00067
00068 Matrix eye(0.0, dim,dim);
00069 for(unsigned int j=0;j<dim;j++) eye(j,j)=1.0;
00070
00071
00072 double z_norm = norm_1(exponent);
00073 frexp(z_norm,&e);
00074 int s = MAX(0, e+1);
00075 temp /= (pow(2.0, s));
00076
00077
00078 Matrix X(temp);
00079 Matrix cX(dim,dim);
00080 double c=0.5;
00081 Matrix D (eye-temp*c);
00082 E = eye+temp*c;
00083 q = 6;
00084 p = 1;
00085
00086 for(k=2;k<=q;k++)
00087 {
00088 c = c*(q-k+1)/(k*(2*q-k+1));
00089 X = X*temp;
00090 cX = X*c;
00091 E += cX;
00092 if(p)
00093 D += cX;
00094 else
00095 D -= cX;
00096 p = !p;
00097 }
00098
00099
00100 E = TBCI__ lu_solve(D,E);
00101
00102
00103 for(k=1;k<=s;k++) E = E*E;
00104 }
00105
00106
00107 INST2(template < Matrix<T>, Matrix<T> > class NN friend \
00108 void expm2 (const Matrix<T>& exponent, Matrix<T>& erg, double);)
00109 INST2(template < BdMatrix<T>, Matrix<T> > class NN friend \
00110 void expm2 (const BdMatrix<T>& exponent, Matrix<T>& erg, double);)
00111
00112
00113
00114
00115 template<typename MatrixIn, typename MatrixOut>
00116 void expm2 (const MatrixIn& exponent, MatrixOut& erg, double ERROR=1e-3)
00117 {
00118 unsigned int dim=exponent.rows();
00119
00120
00121 int e;
00122 double z_norm=norm_1(exponent);
00123 frexp(z_norm,&e);
00124 int s = MAX(0, e+1);
00125 MatrixIn scaled(exponent);
00126 double scale_factor = (pow(2.0, s));
00127 scaled/=scale_factor;
00128
00129
00130
00131
00132
00133
00134 MatrixOut temp(scaled);
00135 double error=1;
00136
00137
00138 erg = temp;
00139 for (unsigned int j=0; j<dim; j++) erg(j,j) += 1;
00140
00141
00142 int i;
00143 for(i=2; i<100 && error>ERROR; i++)
00144 {
00145 temp = (temp/i)*scaled;
00146 erg += temp;
00147
00148 error /= i;
00149
00150 }
00151
00152
00153
00154 for(int k=1;k<=s;k++) erg = erg*erg;
00155 }
00156
00157
00158
00159 INST2(template <Matrix<T>, Matrix<T> > class NN friend \
00160 void expm3 (const Matrix<T>& exponent, Matrix<T>& erg, double);)
00161 INST2(template <BdMatrix<T>, Matrix<T> > class NN friend \
00162 void expm3 (const BdMatrix<T>& exponent, Matrix<T>& erg, double);)
00163
00164
00165
00166 template<typename MatrixIn, typename MatrixOut>
00167 void expm3 (const MatrixIn& exponent, MatrixOut& erg, double ERROR=1e-3)
00168 {
00169 unsigned int dim=exponent.rows();
00170 double z_norm=0;
00171
00172
00173 for (unsigned int i=0; i<dim; i++)
00174 for (unsigned int j=0; j<dim; j++)
00175 z_norm=MAX(z_norm, (double)MATH__ fabs(exponent(i,j)));
00176
00177 z_norm /= 0.1;
00178
00179 int e;
00180 frexp(z_norm,&e);
00181 int s = MAX(0, e+1);
00182 double scale_factor = (pow(2.0, s));
00183 double error = 10;
00184
00185 MatrixOut temp(exponent);
00186
00187
00188
00189 for(int iter=0; iter<100 && error>ERROR; iter+=4)
00190 {
00191
00192
00193 scale_factor = (pow(2.0, s));
00194 erg = exponent/(scale_factor);
00195 for(unsigned int j=0; j<dim; j++) erg(j,j) += 1;
00196 for(int k=1;k<=s;k++)
00197 erg = erg*erg;
00198 error = norm_1 (erg - temp);
00199
00200 STD__ cout << error << STD__ endl;
00201 temp=erg;
00202 s++;
00203 }
00204
00205 }
00206
00207 NAMESPACE_END
00208
00209 #endif