Sunday, February 1, 2015
Inverse Matrix with Marquardt method in C
Kode C berikut adalah fungsi untuk melakukan inversi matrix singular dengan Metoda Marquardt untuk floating point matrix 2x2. Input: matrixA.txt dan matrixX.txt, dimana matrixA.txt adalah matrix singular atau ill-conditioned.
Di bagian bawah kode ini terdapat kode utama untuk perkalian matrix dan inversi marquardt dan membandingkan hasilnya.
Anda dapat melakukan test dimana:
matrixA.txt
2.0 2.0
3.0 3.0
matrixX.txt
0.5 0.5
0.5 0.5
#include<stdio.h>
void marquardt(float A[10][10],float X[10][10],float B[10][10],float lamda)
{
//compute AT=A'
float AT[10][10] ;
int i,j,k;
for(i=0;i<2;i++)
for(i=0;i<2;i++){
for(j=0;j<2;j++){
AT[j][i]=A[i][j];
}
}
//compute AAT=A'*A
float AAT[10][10];
float sum=0.0;
for(i=0;i<2;i++)
for(j=0;j<2;j++)
AAT[i][j]=0.0;
for(i=0;i<2;i++){
for(j=0;j<2;j++){
sum=0.0;
for(k=0;k<2;k++)
sum=sum+AT[i][k]*A[k][j];
AAT[i][j]=sum;
}
}
//create lamda*I
float LI[10][10];
for(i=0;i<2;i++)
{
for(j=0;j<2;j++)
{
if(i==j)
{
LI[i][j]=lamda;
}
else
{
LI[i][j]=0.0;
}
}
}
//compute AATLI=A'*A+lamda*I=AAT+LI
float AATLI[10][10];
for(i=0;i<2;i++)
{
for(j=0;j<2;j++)
{
AATLI[i][j] = (AAT[i][j] + LI[i][j]);
}
}
float ratio,a;
//compute inverse AATLI
{
for(i = 0; i < 2; i++){
for(j = 2; j < 2*2; j++){
if(i==(j-2))
AATLI[i][j] = 1.0;
else
AATLI[i][j] = 0.0;
}
}
for(i = 0; i < 2; i++){
for(j = 0; j < 2; j++){
if(i!=j){
ratio = AATLI[j][i]/AATLI[i][i];
for(k = 0; k < 2*2; k++){
AATLI[j][k] -= ratio * AATLI[i][k];
}
}
}
}
for(i = 0; i < 2; i++){
a = AATLI[i][i];
for(j = 2; j < 2*2; j++){
AATLI[i][j] /= a;
}
}
for(i = 0; i < 2; i++){
for(j = 0; j < 2; j++){
AATLI[i][j] = AATLI[i][2+j] ;
}
}
}
//compute C=inv(AATLI)*A'
float C[10][10];
for(i=0;i<2;i++)
for(j=0;j<2;j++)
C[i][j]=0.0;
for(i=0;i<2;i++){
for(j=0;j<2;j++){
sum=0.0;
for(k=0;k<2;k++)
sum=sum+AATLI[i][k]*AT[k][j];
C[i][j]=sum;
}
}
//compute B=inv(A'*A+lamda*I)*A'*X=C*X
//float B[10][10];
for(i=0;i<2;i++)
for(j=0;j<2;j++)
B[i][j]=0.0;
for(i=0;i<2;i++){
for(j=0;j<2;j++){
sum=0.0;
for(k=0;k<2;k++)
sum=sum+C[i][k]*X[k][j];
B[i][j]=sum;
}
}
}
//read matrix A
void readA(float A[10][10])
{
int i,j;
FILE *inputA=fopen("matrixA.txt","r");
for(i=0;i<2;++i){
for(j=0;j<2;++j){
fscanf(inputA,"%f",&A[i][j]);
}
}
fclose(inputA);
}
//read matrix X
void readX(float X[10][10])
{
int i,j;
FILE *inputX=fopen("matrixX.txt","r");
for(i=0;i<2;++i){
for(j=0;j<2;++j){
fscanf(inputX,"%f",&X[i][j]);
}
}
fclose(inputX);
}
//mult
void mult(float A[10][10],float B[10][10],float C[10][10])
{
int i,j,k;
float sum=0.0;
for(i=0;i<2;i++)
for(j=0;j<2;j++)
C[i][j]=0.0;
for(i=0;i<2;i++){
for(j=0;j<2;j++){
sum=0.0;
for(k=0;k<2;k++)
sum=sum+A[i][k]*B[k][j];
C[i][j]=sum;
}
}
}
//print
void print(float D[10][10])
{
int i,j;
for(i=0;i<2;++i)
{
for(j=0;j<2;++j)
{
printf("%f ",D[i][j]);
}
printf("\n");
}
}
main()
{
float A1[10][10],B1[10][10],C1[10][10],D1[10][10],X1[10][10];
int i,j,k;
readA(A1);//call matrix A
readX(X1);//call matrix X
mult(A1,X1,C1);//C=A*X
marquardt(A1,C1,D1,0.001);
print(X1); //print original input
print(D1); //print predicted input
}
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment