42 using namespace Eigen;
93 void CSparse::setupBlockStructure(
int n)
107 for (
int i=0; i<(int)diag.size(); i++)
109 for (
int i=0; i<(int)cols.size(); i++)
111 map<int,Matrix<double,6,6>, less<int>,
112 aligned_allocator<Matrix<double,6,6> > > &col = cols[i];
115 map<int,Matrix<double,6,6>, less<int>,
116 aligned_allocator<Matrix<double,6,6> > >::iterator it;
117 for (it = col.begin(); it != col.end(); it++)
118 it->second.setZero();
123 void CSparse::incDiagBlocks(
double lam)
125 for (
int i=0; i<(int)diag.size(); i++)
126 diag[i].diagonal() *= lam;
130 void CSparse::addOffdiagBlock(Matrix<double,6,6> &m,
int ii,
int jj)
133 map<int,Matrix<double,6,6>, less<int>,
134 aligned_allocator<Matrix<double,6,6> > > &col = cols[jj];
136 map<int,Matrix<double,6,6>, less<int>,
137 aligned_allocator<Matrix<double,6,6> > >::iterator it;
140 col.insert(pair<
int,Matrix<double,6,6> >(ii,m));
150 void CSparse::setupCSstructure(
double diaginc,
bool init)
154 cholmod_start(&Common);
160 if (
init || useCholmod)
164 for (
int i=0; i<(int)cols.size(); i++)
166 map<int,Matrix<double,6,6>, less<int>,
167 aligned_allocator<Matrix<double,6,6> > > &col = cols[i];
168 nnz += 36 * col.size();
177 chA = cholmod_allocate_sparse(csize,csize,nnz,
true,
true,1,CHOLMOD_REAL,&Common);
183 A = cs_spalloc(csize,csize,nnz,1,0);
201 for (
int i=0; i<(int)cols.size(); i++)
204 map<int,Matrix<double,6,6>, less<int>,
205 aligned_allocator<Matrix<double,6,6> > > &col = cols[i];
208 for (
int k=0; k<6; k++)
217 map<int,Matrix<double,6,6>, less<int>,
218 aligned_allocator<Matrix<double,6,6> > >::iterator it;
221 for (it = col.begin(); it != col.end(); it++)
224 for (
int j=0; j<6; j++)
231 for (
int kk=0; kk<k+1; kk++)
245 Ax = (
double *)chA->x;
249 for (
int i=0; i<(int)cols.size(); i++)
252 map<int,Matrix<double,6,6>, less<int>,
253 aligned_allocator<Matrix<double,6,6> > > &col = cols[i];
256 for (
int k=0; k<6; k++)
262 map<int,Matrix<double,6,6>, less<int>,
263 aligned_allocator<Matrix<double,6,6> > >::iterator it;
266 for (it = col.begin(); it != col.end(); it++)
268 Matrix<double,6,6> &m = it->second;
269 for (
int j=0; j<6; j++)
275 Matrix<double,6,6> &m = diag[i];
276 for (
int kk=0; kk<k+1; kk++)
277 Ax[colp++] = m(kk,k);
278 Ax[colp-1] *= diaginc;
286 void CSparse::uncompress(MatrixXd &m)
289 m.setZero(csize,csize);
295 for (
int i=0; i<csize; i++)
300 for (
int j=rbeg; j<rend; j++)
306 bool CSparse::doChol()
311 cholmod_dense *x, b, *R, *R2;
313 double *Xx, *Rx, *bb;
314 double one [2], minusone [2];
321 cholmod_print_sparse (chA, (
char *)
"A", &Common) ;
326 b.xtype = CHOLMOD_REAL;
327 b.dtype = CHOLMOD_DOUBLE;
330 L = cholmod_analyze (chA, &Common) ;
332 cholmod_factorize (chA, L, &Common) ;
334 x = cholmod_solve (CHOLMOD_A, L, &b, &Common) ;
340 R = cholmod_copy_dense (&b, &Common) ;
341 cholmod_sdmult(chA, 0, minusone, one, x, R, &Common) ;
343 R2 = cholmod_solve (CHOLMOD_A, L, R, &Common) ;
345 Xx = (
double *)x->x ;
346 Rx = (
double *)R2->x ;
347 for (
int i=0 ; i<csize ; i++)
349 Xx[i] = Xx[i] + Rx[i] ;
351 cholmod_free_dense (&R2, &Common) ;
352 cholmod_free_dense (&R, &Common) ;
355 for (
int i=0; i<csize; i++)
357 cholmod_free_factor (&L, &Common) ;
358 cholmod_free_dense (&x, &Common) ;
359 cholmod_free_sparse(&chA, &Common);
360 cholmod_finish (&Common) ;
370 if (csize > 400) order = 1;
371 bool ok = (bool)cs_cholsol(order,A,B.data());
383 CSparse::doBPCG(
int iters,
double tol,
int sba_iter)
389 if (sba_iter > 0) abstol =
true;
391 ret = bpcg.doBPCG2(iters, tol, diag, cols, x, B, abstol);
401 CSparse2d::CSparse2d()
417 CSparse2d::~CSparse2d()
420 if (AF) cs_spfree(AF);
425 void CSparse2d::setupBlockStructure(
int n,
bool eraseit)
432 for (
int i=0; i<(int)cols.size(); i++)
434 map<int,Matrix<double,3,3>, less<int>,
435 aligned_allocator< Matrix <double,3,3> > > &col = cols[i];
446 for (
int i=0; i<(int)diag.size(); i++)
448 for (
int i=0; i<(int)cols.size(); i++)
450 map<int,Matrix<double,3,3>, less<int>,
451 aligned_allocator<Matrix<double,3,3> > > &col = cols[i];
454 map<int,Matrix<double,3,3>, less<int>,
455 aligned_allocator<Matrix<double,3,3> > >::iterator it;
456 for (it = col.begin(); it != col.end(); it++)
457 it->second.setZero();
465 if (Bprev.size() > 0)
466 B.head(Bprev.size()) = Bprev;
472 void CSparse2d::addOffdiagBlock(Matrix<double,3,3> &m,
int ii,
int jj)
475 map<int,Matrix<double,3,3>, less<int>,
476 aligned_allocator<Matrix<double,3,3> > > &col = cols[jj];
478 map<int,Matrix<double,3,3>, less<int>,
479 aligned_allocator<Matrix<double,3,3> > >::iterator it;
482 col.insert(pair<
int,Matrix<double,3,3> >(ii,m));
488 void CSparse2d::incDiagBlocks(
double lam)
490 for (
int i=0; i<(int)diag.size(); i++)
491 diag[i].diagonal() *= lam;
501 void CSparse2d::setupCSstructure(
double diaginc,
bool init)
505 cholmod_start(&Common);
511 if (
init || useCholmod)
517 for (
int i=0; i<(int)cols.size(); i++)
519 map<int,Matrix<double,3,3>, less<int>,
520 aligned_allocator<Matrix<double,3,3> > > &col = cols[i];
521 nnz += 9 * col.size();
529 chA = cholmod_allocate_sparse(csize,csize,nnz,
true,
true,1,CHOLMOD_REAL,&Common);
534 A = cs_spalloc(csize,csize,nnz,1,0);
553 for (
int i=0; i<(int)cols.size(); i++)
556 map<int,Matrix<double,3,3>, less<int>,
557 aligned_allocator<Matrix<double,3,3> > > &col = cols[i];
560 for (
int k=0; k<3; k++)
569 map<int,Matrix<double,3,3>, less<int>,
570 aligned_allocator<Matrix<double,3,3> > >::iterator it;
573 for (it = col.begin(); it != col.end(); it++)
576 for (
int j=0; j<3; j++)
583 for (
int kk=0; kk<k+1; kk++)
595 Ax = (
double *)chA->x;
600 for (
int i=0; i<(int)cols.size(); i++)
603 map<int,Matrix<double,3,3>, less<int>,
604 aligned_allocator<Matrix<double,3,3> > > &col = cols[i];
607 for (
int k=0; k<3; k++)
613 map<int,Matrix<double,3,3>, less<int>,
614 aligned_allocator<Matrix<double,3,3> > >::iterator it;
617 for (it = col.begin(); it != col.end(); it++)
619 Matrix<double,3,3> &m = it->second;
620 for (
int j=0; j<3; j++)
626 Matrix<double,3,3> &m = diag[i];
627 for (
int kk=0; kk<k+1; kk++)
628 Ax[colp++] = m(kk,k);
629 Ax[colp-1] *= diaginc;
640 void CSparse2d::uncompress(MatrixXd &m)
643 m.setZero(csize,csize);
649 for (
int i=0; i<csize; i++)
654 for (
int j=rbeg; j<rend; j++)
660 bool CSparse2d::doChol()
665 cholmod_dense *x, b, *R, *R2;
667 double *Xx, *Rx, *bb;
668 double one [2], minusone [2];
675 cholmod_print_sparse (chA, (
char *)
"A", &Common) ;
680 b.xtype = CHOLMOD_REAL;
681 b.dtype = CHOLMOD_DOUBLE;
684 L = cholmod_analyze (chA, &Common) ;
686 cholmod_factorize (chA, L, &Common) ;
688 x = cholmod_solve (CHOLMOD_A, L, &b, &Common) ;
694 R = cholmod_copy_dense (&b, &Common) ;
695 cholmod_sdmult(chA, 0, minusone, one, x, R, &Common) ;
697 R2 = cholmod_solve (CHOLMOD_A, L, R, &Common) ;
699 Xx = (
double *)x->x ;
700 Rx = (
double *)R2->x ;
701 for (
int i=0 ; i<csize ; i++)
703 Xx[i] = Xx[i] + Rx[i] ;
705 cholmod_free_dense (&R2, &Common) ;
706 cholmod_free_dense (&R, &Common) ;
709 for (
int i=0; i<csize; i++)
711 cholmod_free_factor (&L, &Common) ;
712 cholmod_free_dense (&x, &Common) ;
713 cholmod_free_sparse(&chA, &Common);
714 cholmod_finish (&Common) ;
725 if (csize > 100) order = 1;
726 bool ok = (bool)cs_cholsol(order,A,B.data());
738 CSparse2d::doBPCG(
int iters,
double tol,
int sba_iter)
744 if (sba_iter > 0) abstol =
true;
746 ret = bpcg.doBPCG2(iters, tol, diag, cols, x, B, abstol);
755 int CSparse2d::doPCG(
int iters)
762 AT = cs_transpose(A,1);
763 cs_fkeep (AT, &dropdiag, NULL);
764 if (AF) cs_spfree(AF);
765 AF = cs_add (A, AT, 1, 1);
769 CompCol_Mat_double Ap(csize, csize, AF->nzmax, AF->x, AF->i, AF->p);
770 VECTOR_double b(B.data(),csize);
771 VECTOR_double x(csize, 0.0);
776 ICPreconditioner_double D(Ap);
777 res = CG(Ap,x,b,D,iters,tol);
779 for (
int i=0; i<csize; i++)