Luzuk
03-10-2008, 06:24
Помогите пожалуйста написать функция для вычисления матричной экспоненты.
Ни как не могу полностью разобраться, как она вообще считается и по этому и сам алгоритм её расчёта написать не могу.
Нашёл готовую функцию, в которой вроде бы это уже реализовано. только с ней я полностью тоже разобраться не смог, слишком много непонятных входных данных.
Исходники нашёл вот в этом документе: http://www.rosavtodor.ru/doc/STO/STO_MADI.doc
Ниже привожу функцию, из этого файла, которая судя по описанию вычисляет матричную экспоненту и матрицу Аа
#define EPS 0.1e-15
#define Max(A,B) (((A)>(B))?(A):(B))
#define Min(A,B) (((A)<(B))?(A):(B))
#define Abs(A) (((A) > 0.)?(A): -(A))
expmm(double **a, double dt, int n, double **ea, double **aa, double **wm, double *w)
{
double am, em, emi;
int i, j, k, ii;
em = 0.;
for( i = 0; i < n; i++ ){
for( j = 0; j < n; j++ ){
ea[i][j] = 0.;
aa[i][j] = 0.;
wm[i][j] = 0.;
a[i][j] *= dt;
am = Abs(a[i][j]);
em = Max(am,em);
}
ea[i][i] = 1.;
aa[i][i] = 1.;
wm[i][i] = 1.;
}
emi = 1.;
ii = 0;
while( emi > EPS ){
ii++;
if( ii >= 40 ) break;
emi = 0.;
for( j = 0; j < n; j++ ){
for( i = 0; i < n; i++ )
w[i] = wm[i][j];
for( i = 0; i < n; i++ ){
wm[i][j] = 0.;
for( k = 0; k < n; k++ )
wm[i][j] += a[i][k] * w[k];
}
}
for( i = 0; i < n; i++ )
for( j = 0; j < n; j++ ){
wm[i][j] /= (double)ii;
ea[i][j] += wm[i][j];
aa[i][j] += wm[i][j] / (double)(ii + 1);
am = Abs(wm[i][j]);
emi = Max(am,emi);
}
}
return ii;
}
Ни как не могу полностью разобраться, как она вообще считается и по этому и сам алгоритм её расчёта написать не могу.
Нашёл готовую функцию, в которой вроде бы это уже реализовано. только с ней я полностью тоже разобраться не смог, слишком много непонятных входных данных.
Исходники нашёл вот в этом документе: http://www.rosavtodor.ru/doc/STO/STO_MADI.doc
Ниже привожу функцию, из этого файла, которая судя по описанию вычисляет матричную экспоненту и матрицу Аа
#define EPS 0.1e-15
#define Max(A,B) (((A)>(B))?(A):(B))
#define Min(A,B) (((A)<(B))?(A):(B))
#define Abs(A) (((A) > 0.)?(A): -(A))
expmm(double **a, double dt, int n, double **ea, double **aa, double **wm, double *w)
{
double am, em, emi;
int i, j, k, ii;
em = 0.;
for( i = 0; i < n; i++ ){
for( j = 0; j < n; j++ ){
ea[i][j] = 0.;
aa[i][j] = 0.;
wm[i][j] = 0.;
a[i][j] *= dt;
am = Abs(a[i][j]);
em = Max(am,em);
}
ea[i][i] = 1.;
aa[i][i] = 1.;
wm[i][i] = 1.;
}
emi = 1.;
ii = 0;
while( emi > EPS ){
ii++;
if( ii >= 40 ) break;
emi = 0.;
for( j = 0; j < n; j++ ){
for( i = 0; i < n; i++ )
w[i] = wm[i][j];
for( i = 0; i < n; i++ ){
wm[i][j] = 0.;
for( k = 0; k < n; k++ )
wm[i][j] += a[i][k] * w[k];
}
}
for( i = 0; i < n; i++ )
for( j = 0; j < n; j++ ){
wm[i][j] /= (double)ii;
ea[i][j] += wm[i][j];
aa[i][j] += wm[i][j] / (double)(ii + 1);
am = Abs(wm[i][j]);
emi = Max(am,emi);
}
}
return ii;
}