#include #include #include #include #include "belasolv.h" #include "belasolvDlg.h" #include "spars.h" #define KLUDGE CEntry::CEntry() { next=NULL; x=0; c=0; } CBigLinProb::CBigLinProb() { n=0; } CBigLinProb::~CBigLinProb() { if (n==0) return; int i; CEntry *uo,*ui; free(b); free(P); free(R); free(V); free(U); free(Z); free(Q); for(i=0;inext; delete uo; } while(ui!=NULL); } free(M); n=0; } int CBigLinProb::Create(int d, int bw) { int i; bdw=bw; b=(double *)calloc(d,sizeof(double)); V=(double *)calloc(d,sizeof(double)); P=(double *)calloc(d,sizeof(double)); R=(double *)calloc(d,sizeof(double)); U=(double *)calloc(d,sizeof(double)); Z=(double *)calloc(d,sizeof(double)); Q=(BOOL *) calloc(d,sizeof(BOOL)); M=(CEntry **)calloc(d,sizeof(CEntry *)); n=d; for(i=0;ic = i; } return 1; } void CBigLinProb::Put(double v, int p, int q) { CEntry *e,*l; int i; if(qc < q) && (e->next != NULL)) { l=e; e=e->next; } if(e->c == q){ e->x=v; return; } CEntry *m = new CEntry; if((e->next == NULL) && (q > e->c)){ e->next = m; m->c = q; m->x = v; } else{ l->next=m; m->next=e; m->c=q; m->x=v; } return; } double CBigLinProb::Get(int p, int q) { CEntry *e; if(qc < q) && (e->next != NULL)) e=e->next; if(e->c == q) return e->x; return 0; } void CBigLinProb::MultA(double *X, double *Y) { int i; CEntry *e; for(i=0;ix*X[i]; e=M[i]->next; while(e!=NULL) { Y[i]+=e->x*X[e->c]; Y[e->c]+=e->x*X[i]; e=e->next; } } } double CBigLinProb::Dot(double *X, double *Y) { int i; double z; for(i=0,z=0;ix; // SSOR preconditioner: int i; double c; CEntry *e; c= Lambda*(2-Lambda); for(i=0;ix; e=M[i]->next; while(e!=NULL) { Y[e->c] -= e->x * Y[i] * Lambda; e=e->next; } } for(i=0;ix; // invert Upper Triangle for(i=n-1;i>=0;i--){ e=M[i]->next; while(e!=NULL) { Y[i] -= e->x * Y[e->c] * Lambda; e=e->next; } Y[i]/= M[i]->x; } } int CBigLinProb::PCGSolve(int flag) { int i; double res,res_o,res_new; double er,del,rho,pAp; // quick check for most obvious sign of singularity; for(i=0;ix==0){ MsgBox("singular flag tripped at %i of %i",i,n); return FALSE; } // initialize progress bar; TheView->SetDlgItemText(IDC_FRAME1,"Conjugate Gradient Solver"); TheView->m_prog1.SetPos(0); int prg1=0; int prg2; // Best guess for relaxation parameter Lambda=1.5; // residual with V=0 MultPC(b,Z); res_o=Dot(Z,b); if(res_o==0) return 1; // if flag is false, initialize V with zeros; if (flag==0) for(i=0;iprg1){ prg1=prg2; prg2=(prg1*5); if(prg2>100) prg2=100; TheView->m_prog1.SetPos(prg2); TheView->InvalidateRect(NULL, FALSE); TheView->UpdateWindow(); } } while(er>Precision); return 1; } void CBigLinProb::SetValue(int i, double x) { int k,fst,lst; double z; if(bdw==0){ fst=0; lst=n; } else{ fst=i-bdw; if (fst<0) fst=0; lst=i+bdw; if (lst>n) lst=n; } for(k=fst;kx=0; e=e->next; } while(e!=NULL); } } void CBigLinProb::AntiPeriodicity(int i, int j) { int k,fst,lst; double v1,v2,c; #ifdef KLUDGE int tmpbdw=bdw; bdw=0; #endif if (jn) lst=n; } for(k=fst;kn) lst=n; } for(k=fst;k