libDC.cpp itpp/itbase.h libDC.h std::ostream & std::ostream& operator<< (std::ostream &os, const fsqmat &ld) operator<< std::ostream & os const fsqmat & ld std::ostream & std::ostream& operator<< (std::ostream &os, const ldmat &ld) operator<< std::ostream & os const ldmat & ld mat mat ltuinv (const mat &L) ltuinv const mat & L Auxiliary function ltuinv; inversion of a triangular matrix;. sqmat::dim ldmat::L void void dydr (double *r, double *f, double *Dr, double *Df, double *R, int jl, int jh, double *kr, int m, int mx) dydr double * r double * f double * Dr double * Df double * R int jl int jh double * kr int m int mx Auxiliary function dydr; dyadic reduction. #include<itpp/itbase.h> #include"libDC.h" usingnamespaceitpp; usingstd::endl; voidfsqmat::opupdt(constvec&v,doublew){M+=outer_product(v,v*w);}; matfsqmat::to_mat(){returnM;}; voidfsqmat::mult_sym(constmat&C){M=C*M*C.T();}; voidfsqmat::mult_sym_t(constmat&C){M=C.T()*M*C;}; voidfsqmat::mult_sym(constmat&C,fsqmat&U)const{U.M=(C*(M*C.T()));}; voidfsqmat::mult_sym_t(constmat&C,fsqmat&U)const{U.M=(C.T()*(M*C));}; voidfsqmat::inv(fsqmat&Inv){matIM=itpp::inv(M);Inv=IM;}; voidfsqmat::clear(){M.clear();}; fsqmat::fsqmat(constmat&M0):sqmat(M0.cols()) { it_assert_debug((M0.cols()==M0.rows()),"M0mustbesquare"); M=M0; }; //fsqmat::fsqmat(){}; fsqmat::fsqmat(constintdim0):sqmat(dim0),M(dim0,dim0){}; std::ostream&operator<< (std::ostream&os,constfsqmat&ld){ os<<ld.M<<endl; returnos; } ldmat::ldmat(constmat&exL,constvec&exD):sqmat(exD.length()){ D=exD; L=exL; } ldmat::ldmat():sqmat(0){} ldmat::ldmat(constintdim0):sqmat(dim0),D(dim0),L(dim0,dim0){} ldmat::ldmat(constvecD0):sqmat(D0.length()){ D=D0; L=eye(dim); } ldmat::ldmat(constmat&V):sqmat(V.cols()){ //TODOcheckifcorrect!!Basedonheuristicobservationoflu() it_assert_debug(dim==V.rows(),"ldmat::ldmatmatrixVisnotsquare!"); //LandDwillbeallocatedbyldform() //Cholisunstable this->ldform(chol(V),ones(dim)); //this->ldform(ul(V),ones(dim)); } voidldmat::opupdt(constvec&v,doublew){ intdim=D.length(); doublekr; vecr=v; //beware!itispotentionallydangerous,ifITppchange_behaviourof_data()! double*Lraw=L._data(); double*Draw=D._data(); double*rraw=r._data(); it_assert_debug(v.length()==dim,"LD::ldupdtvectorvisnotcompatiblewiththisld."); for(inti=dim-1;i>=0;i--){ dydr(rraw,Lraw+i,&w,Draw+i,rraw+i,0,i,&kr,1,dim); } } std::ostream&operator<< (std::ostream&os,constldmat&ld){ os<<"L:"<<ld.L<<endl; os<<"D:"<<ld.D<<endl; returnos; } matldmat::to_mat(){ intdim=D.length(); matV(dim,dim); doublesum; intr,c,cc; for(r=0;r<dim;r++){//rowcycle for(c=r;c<dim;c++){ //columncycle,usingsymmetricity=>c=r! sum=0.0; for(cc=c;cc<dim;cc++){//cycleovertheremainingpartofthevector sum+=L(cc,r)*D(cc)*L(cc,c); //hereL(cc,r)=L(r,cc)'; } V(r,c)=sum; //symmetricity if(r!=c){V(c,r)=sum;}; } } matV2=L.transpose()*diag(D)*L; returnV2; } voidldmat::add(constldmat&ld2,doublew){ intdim=D.length(); it_assert_debug(ld2.D.length()==dim,"LD.add()incompatiblesizesofLDs;"); //Fixmecanbedonemoreefficientlyeitherviadydrorldform for(intr=0;r<dim;r++){ //Addcolumnsofld2.L'(i.e.rowsofld2.L)asdyadsweightedbyld2.D this->opupdt(ld2.L.get_row(r),w*ld2.D(r)); } } voidldmat::clear(){L.clear();for(inti=0;i<L.cols();i++){L(i,i)=1;};D.clear();} voidldmat::inv(ldmat&Inv)const{ Inv.clear();//Inv=zeroinLD matU=ltuinv(L); Inv.ldform(U.transpose(),1.0/D); } voidldmat::mult_sym(constmat&C){ matA=L*C.T(); this->ldform(A,D); } voidldmat::mult_sym_t(constmat&C){ matA=L*C; this->ldform(A,D); } voidldmat::mult_sym(constmat&C,ldmat&U)const{ matA=L*C.T();//couldbedonemoreefficientlyusingBLAS U.ldform(A,D); } voidldmat::mult_sym_t(constmat&C,ldmat&U)const{ matA=L*C; /*vecnD=zeros(U.rows()); nD.replace_mid(0,D);//IcasethatD<nD*/ U.ldform(A,D); } doubleldmat::logdet()const{ doubleldet=0.0; inti; //sumlogarithmsofdiagobalelements for(i=0;i<D.length();i++){ldet+=log(D(i));}; returnldet; } doubleldmat::qform(constvec&v)const{ doublex=0.0,sum; inti,j; vecs(v.length()); vecS=L*v; for(i=0;i<D.length();i++){//rowsofL sum=0.0; for(j=0;j<=i;j++){sum+=L(i,j)*v(j);} x+=D(i)*sum*sum; s(i)=sum; }; returnx; } doubleldmat::invqform(constvec&v)const{ doublex=0.0; inti; vecpom(v.length()); backward_substitution(L.T(),v,pom); for(i=0;i<D.length();i++){//rowsofL x+=pom(i)*pom(i)/D(i); }; returnx; } ldmat&ldmat::operator *= (doublex){ D*=x; return*this; } vecldmat::sqrt_mult(constvec&x)const{ inti,j; vecres(dim); //doublesum; for(i=0;i<dim;i++){//foreachelementofresult res(i)=0.0; for(j=i;j<dim;j++){//sumD(j)*L(:,i).*x res(i)+=sqrt(D(j))*L(j,i)*x(j); } } //vecres2=L.transpose()*diag(sqrt(D))*x; returnres; } voidldmat::ldform(constmat&A,constvec&D0) { intm=A.rows(); intn=A.cols(); intmn=(m<n)?m:n; //it_assert_debug(A.cols()==dim,"ldmat::ldformAisnotcompatible"); it_assert_debug(D0.length()==A.rows(),"ldmat::ldformVectorDmusthavethelengthasrowcountofA"); L=concat_vertical(zeros(n,n),diag(sqrt(D0))*A); D=zeros(n+m); //unnecessarybigLandDwillbemadesmallerattheendoffile vecw=zeros(n+m); doublesum,beta,pom; intcc=0; inti=n;//indexovanio1niz,nezvmatlabu intii,j,jj; while((i>n-mn-cc)&&(i>0)) { i--; sum=0.0; intlast_v=m+i-n+cc+1; vecv=zeros(last_v+1);//preparev for(ii=n-cc-1;ii<m+i+1;ii++) { sum+=L(ii,i)*L(ii,i); v(ii-n+cc+1)=L(ii,i);//assignv } if(L(m+i,i)==0) beta=sqrt(sum); else beta=L(m+i,i)+sign(L(m+i,i))*sqrt(sum); if(std::fabs(beta)<eps) { cc++; L.set_row(n-cc,L.get_row(m+i)); L.set_row(m+i,zeros(L.cols())); D(m+i)=0;L(m+i,i)=1; L.set_submatrix(n-cc,m+i-1,i,i,0); continue; } sum-=v(last_v)*v(last_v); sum/=beta*beta; sum++; v/=beta; v(last_v)=1; pom=-2.0/sum; //echotovenca for(j=i;j>=0;j--) { doublew_elem=0; for(ii=n-cc;ii<=m+i+1;ii++) w_elem+=v(ii-n+cc)*L(ii-1,j); w(j)=w_elem*pom; } for(ii=n-cc-1;ii<=m+i;ii++) for(jj=0;jj<i;jj++) L(ii,jj)+=v(ii-n+cc+1)*w(jj); for(ii=n-cc-1;ii<m+i;ii++) L(ii,i)=0; L(m+i,i)+=w(i); D(m+i)=L(m+i,i)*L(m+i,i); for(ii=0;ii<=i;ii++) L(m+i,ii)/=L(m+i,i); } if(i>=0) for(ii=0;ii<i;ii++) { jj=D.length()-1-n+ii; D(jj)=0; L.set_row(jj,zeros(L.cols()));//TODO:set_rowacceptsNum_T L(jj,jj)=1; } L.del_rows(0,m-1); D.del(0,m-1); dim=L.rows(); } matltuinv(constmat&L){ intdim=L.cols(); matIl=eye(dim); inti,j,k,m; doubles; //Fixmeblindtranscriptionofltuinv.m for(k=1;k<(dim);k++){ for(i=0;i<(dim-k);i++){ j=i+k;//changein.m1+1=2,here0+0+1=1 s=L(j,i); for(m=i+1;m<(j);m++){ s+=L(m,i)*Il(j,m); } Il(j,i)=-s; } } returnIl; } voiddydr(double*r,double*f,double*Dr,double*Df,double*R,intjl,intjh,double*kr,intm,intmx) /******************************************************************** dydr=dyadicreduction,performstransformationofsumof 2dyadsr*Dr*r'+f*Df*f'sothattheelementofrpointed byRiszeroed.ThisversionallowsDrtobeNEGATIVE.Hencethenamenegdydrordydr_withneg. Parameters: r...pointertoreduceddyad f...pointertoreducingdyad Dr..pointertotheweightofreduceddyad Df..pointertotheweightofreducingdyad R...pointertotheelementofr,whichistobereducedto zero;thecorrespondingelementoffisassumedtobe1. jl..lowerindexoftherangewithinwhichthedyadsare modified ju..upperindexoftherangewithinwhichthedyadsare modified kr..pointertothecoefficientusedinthetransformationofr rnew=r+kr*f m..numberofrowsofmodifiedmatrix(partofwhichisr) Remark:Constantmzeromeansmachinezeroandshouldbemodified accordingtotheprecisionofparticularmachine V.Peterka17-7-89 Added: mx..numberofrowsofmodifiedmatrix(partofwhichisf)-PN ********************************************************************/ { intj,jm; doublekD,r0; doublemzero=2.2e-16; doublethreshold=1e-4; if(fabs(*Dr)<mzero)*Dr=0; r0=*R; *R=0.0; kD=*Df; *kr=r0**Dr; *Df=kD+r0*(*kr); if(*Df>mzero){ kD/=*Df; *kr/=*Df; }else{ kD=1.0; *kr=0.0; if(*Df<-threshold){ it_warning("Problemindydr:subractionofdyadresultsinnegativedefinitness.Likelymistakeincallingfunction."); } *Df=0.0; } *Dr*=kD; jm=mx*jl; for(j=m*jl;j<m*jh;j+=m){ r[j]-=r0*f[jm]; f[jm]+=*kr*r[j]; jm+=mx; } }