00001
00008 #include <stdio.h>
00009 #include <stdlib.h>
00010 #include <math.h>
00011 #include "ilsi.h"
00012 #include "ilsi_vec.h"
00013
00014 double nextDouble(void) {
00015 return (rand()%8192)*(1.0/8192.0);
00016 }
00017
00019 class serial_comm : public ILSI_Comm {
00020 int n;
00021 const double *matrix;
00022 double at(int r,int c) const {
00023 return matrix[r*n+c];
00024 }
00025 public:
00026 serial_comm(int n_,const double *matrix_)
00027 :n(n_), matrix(matrix_) {}
00028
00029 virtual void matrixVectorProduct(const double *src,double *dest) {
00030 for (int r=0;r<n;r++) {
00031 double sum=0;
00032 for (int c=0;c<n;c++)
00033 sum+=at(r,c)*src[c];
00034 dest[r]=sum;
00035 }
00036 }
00037
00038 virtual double dotProduct(const double *a,const double *b) {
00039 double sum=0;
00040 for (int r=0;r<n;r++) sum+=a[r]*b[r];
00041 return sum;
00042 }
00043 };
00044
00045 int main(int argc,char *argv[]) {
00046 int n=4;
00047 if (argc>1) n=atoi(argv[1]);
00048 int r,c;
00049
00050 double *A=new double[n*n], *true_x=new double[n];
00051 srand(2);
00052 for (r=0;r<n;r++) {
00053 for (c=0;c<n;c++) {
00054 if (c<r)
00055 A[r*n+c]=A[c*n+r];
00056 else
00057 A[r*n+c]=nextDouble();
00058 }
00059 true_x[r]=nextDouble();
00060 }
00061 serial_comm comm(n,A);
00062
00063
00064 double *b=new double[n], *x=new double[n];
00065 comm.matrixVectorProduct(true_x,b);
00066
00067
00068 ILSI_Param param;
00069 ILSI_Param_new(¶m);
00070 const double tolerance=1.0e-5;
00071 param.maxResidual=tolerance;
00072
00073 printf("Solving...\n");
00074 ILSI_CG_Solver(¶m,&comm, n,b,x);
00075
00076
00077 double totalErr=0;
00078 for (r=0;r<n;r++) {
00079 double err=fabs(x[r]-true_x[r]);
00080 if (err>tolerance) {
00081 printf("Big difference %g found at position %d!\n",err,r);
00082 exit(1);
00083 }
00084 totalErr+=err;
00085 }
00086 printf("Solved: est. res=%g, err=%g, iter=%d\n",
00087 param.residual, totalErr, (int)param.iterations);
00088
00089 exit(0);
00090 }
00091