#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define N 10
#define TMAX 100
#define EPS (10e-6)
void init_vector();
double cg_method(double **matrix_a, double *vector_x, double *vector_b);
void init_vector(double *vector_x);
void vector_x_matrix(double *vector_y, double **matrix_a,double *vector_x);
double dot_product(double *vector_x, double *vector_y);
double vector_norm(double *vector_x);
int main (void){
FILE *fin, *fout;
static double **matrix_a;
static double *vector_b;
static double *vector_x;
int i,j;
matrix_a
= (double**)malloc(sizeof(double*)*N
); for(i=0;i<N;i++){
matrix_a
[i
] = (double*)malloc(sizeof(double)*N
); }
vector_b
= (double*)malloc(sizeof(double)*N
); vector_x
= (double*)malloc(sizeof(double)*N
);
if((fin
= fopen("input_sp.dat","r"))==NULL
) {
printf("no file :input_sp.dat\n"); }
if((fout
= fopen("output_sp.dat","w"))==NULL
) {
printf("do not maike file : output_sp.dat\n"); }
for( i = 0 ; i < N ; i++)
{
for( j = 0 ; j < N ; j++)
{
fscanf(fin
, "%lf", &matrix_a
[i
][j
]); fprintf(fout
, "%5.2f\t", matrix_a
[i
][j
]); printf("%lf\n",matrix_a
[i
][j
]); }
}
for( i = 0 ; i < N ; i++)
{
fscanf(fin
, "%lf", &vector_b
[i
]); fprintf(fout
, "%5.2f\t", vector_b
[i
]); }
for( i = 0 ; i < N ; i++)
{
fscanf(fin
, "%lf", &vector_x
[i
]); fprintf(fout
, "%5.2f\t", vector_x
[i
]); }
cg_method(matrix_a, vector_x, vector_b);
fprintf( fout
, "Ax=b is solved\n"); for( i = 1 ; i <= N ; i++ )
{
fprintf(fout
, "%f\n", vector_x
[i
]); }
return 0;
}
void init_vector(double *vector_x)
{
int i;
for(i = 0; i < N; i++){
vector_x[i] = 0;
}
}
void vector_x_matrix(double *vector_y,double **matrix_a,double *vector_x)
{
int i, j;
double vxm;
for(i = 0; i < N; i++){
vxm = 0;
for(j = 0; j < N; j++){
vxm += matrix_a[i][j] * vector_x[i];
}
vector_y[i] = vxm;
}
}
double dot_product(double *vector_x,double *vector_y)
{
int i;
double dot_p = 0;
for(i = 0; i < N; i++){
dot_p += vector_x[i] * vector_y[i];
}
return dot_p;
}
double vector_norm(double *vector_x)
{
int i;
double norm = 0;
for(i = 0; i < N; i++){
norm
+= fabs(vector_x
[i
]); }
return norm;
}
double cg_method(double **matrix_a, double *vector_x, double *vector_b)
{
double *vector_p;
double *vector_r;
double *vector_ax;
double *vector_ap;
int i, iter;
vector_p
= (double*)malloc(sizeof(double)*N
); vector_r
= (double*)malloc(sizeof(double)*N
); vector_ax
= (double*)malloc(sizeof(double)*N
); vector_ap
= (double*)malloc(sizeof(double)*N
);
vector_x_matrix(vector_ax, matrix_a, vector_x);
for(i = 0; i < N; i++){
vector_p[i] = vector_b[i] - vector_ax[i];
vector_r[i] = vector_p[i];
}
for(iter = 1; iter < TMAX; iter++){
double alpha, beta, err = 0;
vector_x_matrix(vector_ap, matrix_a, vector_p);
alpha = dot_product(vector_p, vector_r)/dot_product(vector_p, vector_ap);
for(i = 0; i < N; i++){
vector_x[i] += +alpha * vector_p[i];
vector_r[i] += -alpha * vector_ap[i];
}
err = vector_norm(vector_r);
printf("LOOP : %d\t Error : %g\n", iter
, err
); if(EPS > err) break;
beta = -dot_product(vector_r, vector_ap)/dot_product(vector_p, vector_ap);
for(i = 0; i < N; i++){
vector_p[i] = vector_r[i] + beta * vector_p[i];
}
}
}
I2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPG1hdGguaD4KCiNkZWZpbmUgTiAxMAojZGVmaW5lIFRNQVggMTAwCiNkZWZpbmUgRVBTICgxMGUtNikKCnZvaWQgaW5pdF92ZWN0b3IoKTsKZG91YmxlIGNnX21ldGhvZChkb3VibGUgKiptYXRyaXhfYSwgZG91YmxlICp2ZWN0b3JfeCwgZG91YmxlICp2ZWN0b3JfYik7CnZvaWQgaW5pdF92ZWN0b3IoZG91YmxlICp2ZWN0b3JfeCk7CnZvaWQgdmVjdG9yX3hfbWF0cml4KGRvdWJsZSAqdmVjdG9yX3ksIGRvdWJsZSAqKm1hdHJpeF9hLGRvdWJsZSAqdmVjdG9yX3gpOwpkb3VibGUgZG90X3Byb2R1Y3QoZG91YmxlICp2ZWN0b3JfeCwgZG91YmxlICp2ZWN0b3JfeSk7CmRvdWJsZSB2ZWN0b3Jfbm9ybShkb3VibGUgKnZlY3Rvcl94KTsKCmludCBtYWluICh2b2lkKXsKICAgIEZJTEUgKmZpbiwgKmZvdXQ7CiAgICBzdGF0aWMgZG91YmxlICoqbWF0cml4X2E7CiAgICBzdGF0aWMgZG91YmxlICp2ZWN0b3JfYjsKICAgIHN0YXRpYyBkb3VibGUgKnZlY3Rvcl94OwogICAgaW50IGksajsKCiAgICBtYXRyaXhfYSA9IChkb3VibGUqKiltYWxsb2Moc2l6ZW9mKGRvdWJsZSopKk4pOwogICAgZm9yKGk9MDtpPE47aSsrKXsKICAgICAgICBtYXRyaXhfYVtpXSA9IChkb3VibGUqKW1hbGxvYyhzaXplb2YoZG91YmxlKSpOKTsKICAgIH0KCiAgICB2ZWN0b3JfYiA9IChkb3VibGUqKW1hbGxvYyhzaXplb2YoZG91YmxlKSpOKTsKICAgIHZlY3Rvcl94ID0gKGRvdWJsZSopbWFsbG9jKHNpemVvZihkb3VibGUpKk4pOwoKICAgIGlmKChmaW4gPSBmb3BlbigiaW5wdXRfc3AuZGF0IiwiciIpKT09TlVMTCkKICAgIHsKICAgICAgICBwcmludGYoIm5vIGZpbGUgOmlucHV0X3NwLmRhdFxuIik7CiAgICB9ICAgICAgIAogICAgaWYoKGZvdXQgPSBmb3Blbigib3V0cHV0X3NwLmRhdCIsInciKSk9PU5VTEwpCiAgICB7CiAgICAgICAgcHJpbnRmKCJkbyBub3QgbWFpa2UgZmlsZSA6IG91dHB1dF9zcC5kYXRcbiIpOwogICAgICAgIGV4aXQoMSk7CiAgICB9CgogICAgZnByaW50ZiggZm91dCwgIkFcbiIpOwogICAgcHJpbnRmKCJtYXRyaXhfYVxuIik7CiAgICBmb3IoIGkgPSAwIDsgaSA8IE4gOyBpKyspCiAgICB7CiAgICAgICAgZm9yKCBqID0gMCA7IGogPCBOIDsgaisrKQogICAgICAgIHsKICAgICAgICAgICAgZnNjYW5mKGZpbiwgIiVsZiIsICZtYXRyaXhfYVtpXVtqXSk7CiAgICAgICAgICAgIGZwcmludGYoZm91dCwgIiU1LjJmXHQiLCBtYXRyaXhfYVtpXVtqXSk7CiAgICAgICAgICAgIHByaW50ZigiJWxmXG4iLG1hdHJpeF9hW2ldW2pdKTsKICAgICAgICB9CiAgICAgICAgcHJpbnRmKCJcbiIpOwogICAgICAgIGZwcmludGYoIGZvdXQsICJcbiIpOwogICAgfQoKICAgIGZwcmludGYoIGZvdXQsICJiXG4iKTsKICAgIHByaW50ZigidmVjdG9yX2JcbiIpOwogICAgZm9yKCBpID0gMCA7IGkgPCBOIDsgaSsrKQogICAgewogICAgICAgIGZzY2FuZihmaW4sICIlbGYiLCAmdmVjdG9yX2JbaV0pOwogICAgICAgIGZwcmludGYoZm91dCwgIiU1LjJmXHQiLCB2ZWN0b3JfYltpXSk7CiAgICAgICAgZnByaW50ZiggZm91dCwgIlxuIik7CiAgICAgICAgcHJpbnRmKCIlbGZcbiIsdmVjdG9yX2JbaV0pOwogICAgfQoKICAgIHByaW50ZigiXG4iKTsKCiAgICBmcHJpbnRmKCBmb3V0LCAieFxuIik7CiAgICBwcmludGYoInZlY3Rvcl94XG4iKTsKICAgIGZvciggaSA9IDAgOyBpIDwgTiA7IGkrKykKICAgIHsKICAgICAgICBmc2NhbmYoZmluLCAiJWxmIiwgJnZlY3Rvcl94W2ldKTsKICAgICAgICBmcHJpbnRmKGZvdXQsICIlNS4yZlx0IiwgdmVjdG9yX3hbaV0pOwogICAgICAgIGZwcmludGYoIGZvdXQsICJcbiIpOwogICAgICAgIHByaW50ZigiJWxmXG4iLHZlY3Rvcl94W2ldKTsKICAgIH0KCiAgICBwcmludGYoIlxuIik7CgogICAgY2dfbWV0aG9kKG1hdHJpeF9hLCB2ZWN0b3JfeCwgdmVjdG9yX2IpOwoKICAgIGZwcmludGYoIGZvdXQsICJBeD1iIGlzIHNvbHZlZFxuIik7CiAgICBmb3IoIGkgPSAxIDsgaSA8PSBOIDsgaSsrICkKICAgIHsKICAgICAgICBmcHJpbnRmKGZvdXQsICIlZlxuIiwgdmVjdG9yX3hbaV0pOwogICAgfQogICAgZmNsb3NlKGZpbik7IAogICAgZmNsb3NlKGZvdXQpOwoKCiAgICByZXR1cm4gMDsKfQoKdm9pZCBpbml0X3ZlY3Rvcihkb3VibGUgKnZlY3Rvcl94KQp7CiAgICBpbnQgaTsKICAgIGZvcihpID0gMDsgaSA8IE47IGkrKyl7CiAgICAgICAgdmVjdG9yX3hbaV0gPSAwOwogICAgfQp9Cgp2b2lkIHZlY3Rvcl94X21hdHJpeChkb3VibGUgKnZlY3Rvcl95LGRvdWJsZSAqKm1hdHJpeF9hLGRvdWJsZSAqdmVjdG9yX3gpCnsKICAgIGludCAgICBpLCBqOwogICAgZG91YmxlIHZ4bTsKICAgIGZvcihpID0gMDsgaSA8IE47IGkrKyl7CiAgICAgICAgdnhtID0gMDsKICAgICAgICBmb3IoaiA9IDA7IGogPCBOOyBqKyspewogICAgICAgICAgICB2eG0gKz0gbWF0cml4X2FbaV1bal0gKiB2ZWN0b3JfeFtpXTsKICAgICAgICB9CiAgICAgICAgdmVjdG9yX3lbaV0gPSB2eG07CiAgICB9Cn0KCmRvdWJsZSBkb3RfcHJvZHVjdChkb3VibGUgKnZlY3Rvcl94LGRvdWJsZSAqdmVjdG9yX3kpCnsKICAgIGludCAgICBpOwogICAgZG91YmxlIGRvdF9wID0gMDsKICAgIGZvcihpID0gMDsgaSA8IE47IGkrKyl7CiAgICAgICAgZG90X3AgKz0gdmVjdG9yX3hbaV0gKiB2ZWN0b3JfeVtpXTsKICAgIH0KICAgIHJldHVybiBkb3RfcDsKfQoKZG91YmxlIHZlY3Rvcl9ub3JtKGRvdWJsZSAqdmVjdG9yX3gpCnsKICAgIGludCBpOwogICAgZG91YmxlIG5vcm0gPSAwOwogICAgZm9yKGkgPSAwOyBpIDwgTjsgaSsrKXsKICAgICAgICBub3JtICs9IGZhYnModmVjdG9yX3hbaV0pOwogICAgfQogICAgcmV0dXJuIG5vcm07Cn0KCmRvdWJsZSBjZ19tZXRob2QoZG91YmxlICoqbWF0cml4X2EsIGRvdWJsZSAqdmVjdG9yX3gsIGRvdWJsZSAqdmVjdG9yX2IpCnsKICAgIGRvdWJsZSAqdmVjdG9yX3A7CiAgICBkb3VibGUgKnZlY3Rvcl9yOwogICAgZG91YmxlICp2ZWN0b3JfYXg7CiAgICBkb3VibGUgKnZlY3Rvcl9hcDsKICAgIGludCBpLCBpdGVyOwoKICAgIHZlY3Rvcl9wID0gKGRvdWJsZSopbWFsbG9jKHNpemVvZihkb3VibGUpKk4pOyAKICAgIHZlY3Rvcl9yID0gKGRvdWJsZSopbWFsbG9jKHNpemVvZihkb3VibGUpKk4pOwogICAgdmVjdG9yX2F4ID0gKGRvdWJsZSopbWFsbG9jKHNpemVvZihkb3VibGUpKk4pOwogICAgdmVjdG9yX2FwID0gKGRvdWJsZSopbWFsbG9jKHNpemVvZihkb3VibGUpKk4pOwoKICAgIHZlY3Rvcl94X21hdHJpeCh2ZWN0b3JfYXgsIG1hdHJpeF9hLCB2ZWN0b3JfeCk7CgogICAgZm9yKGkgPSAwOyBpIDwgTjsgaSsrKXsKICAgICAgICB2ZWN0b3JfcFtpXSA9IHZlY3Rvcl9iW2ldIC0gdmVjdG9yX2F4W2ldOwogICAgICAgIHZlY3Rvcl9yW2ldID0gdmVjdG9yX3BbaV07CiAgICB9CgogICAgZm9yKGl0ZXIgPSAxOyBpdGVyIDwgVE1BWDsgaXRlcisrKXsKICAgICAgICBkb3VibGUgYWxwaGEsIGJldGEsIGVyciA9IDA7CgogICAgICAgIHZlY3Rvcl94X21hdHJpeCh2ZWN0b3JfYXAsIG1hdHJpeF9hLCB2ZWN0b3JfcCk7CiAgICAgICAgYWxwaGEgPSBkb3RfcHJvZHVjdCh2ZWN0b3JfcCwgdmVjdG9yX3IpL2RvdF9wcm9kdWN0KHZlY3Rvcl9wLCB2ZWN0b3JfYXApOwoKICAgICAgICBmb3IoaSA9IDA7IGkgPCBOOyBpKyspewogICAgICAgICAgICB2ZWN0b3JfeFtpXSArPSArYWxwaGEgKiB2ZWN0b3JfcFtpXTsKICAgICAgICAgICAgdmVjdG9yX3JbaV0gKz0gLWFscGhhICogdmVjdG9yX2FwW2ldOwogICAgICAgIH0KCiAgICAgICAgZXJyID0gdmVjdG9yX25vcm0odmVjdG9yX3IpOwogICAgICAgIHByaW50ZigiTE9PUCA6ICVkXHQgRXJyb3IgOiAlZ1xuIiwgaXRlciwgZXJyKTsKICAgICAgICBpZihFUFMgPiBlcnIpIGJyZWFrOwoKICAgICAgICBiZXRhID0gLWRvdF9wcm9kdWN0KHZlY3Rvcl9yLCB2ZWN0b3JfYXApL2RvdF9wcm9kdWN0KHZlY3Rvcl9wLCB2ZWN0b3JfYXApOwogICAgICAgIGZvcihpID0gMDsgaSA8IE47IGkrKyl7CiAgICAgICAgICAgIHZlY3Rvcl9wW2ldID0gdmVjdG9yX3JbaV0gKyBiZXRhICogdmVjdG9yX3BbaV07CiAgICAgICAgfQogICAgfQp9