00001
00002
00003 #ifndef CH_MATRIX_CLASSES__SYMMAT_HXX
00004 #define CH_MATRIX_CLASSES__SYMMAT_HXX
00005
00014 #ifndef CH_MATRIX_CLASSES__MATRIX_HXX
00015 #include "matrix.hxx"
00016 #endif
00017
00018 namespace CH_Matrix_Classes {
00019
00020
00021
00022
00023
00024
00028
00043 class Symmatrix: protected Memarrayuser
00044 {
00045 friend class Matrix;
00046 friend class Sparsesym;
00047 friend class Sparsemat;
00048
00049 private:
00050
00051 static const Mtype mtype;
00052 Integer mem_dim;
00053 Integer nr;
00054 Real *m;
00055
00056 bool is_init;
00057
00059 inline void init_to_zero();
00060
00062 Integer tred2(Integer nm, Integer n, Real *a, Real *d, Real *e, Real *z) const;
00064 Integer imtql2(Integer nm, Integer n, Real *d, Real *e, Real *z) const;
00065
00066 public:
00067
00068
00069
00070
00071
00072
00076
00078 inline Symmatrix();
00080 inline Symmatrix(const Symmatrix& A,double d=1.);
00087 inline Symmatrix(Integer nr);
00089 inline Symmatrix(Integer nr,Real d);
00091 inline Symmatrix(Integer nr,Real* dp);
00093 inline ~Symmatrix();
00094
00095 #if (CONICBUNDLE_DEBUG>=1)
00097 void set_init(bool i){is_init=i;}
00099 int get_init() const {return is_init;}
00100 #else
00102 void set_init(bool ){}
00104 bool get_init() const {return true;}
00105 #endif
00106
00108 inline Symmatrix& init(const Symmatrix& A,double d=1.);
00110 inline Symmatrix& init(const Matrix& A,double d=1.);
00112 inline Symmatrix& init(const Indexmatrix& A,double d=1.);
00114 inline Symmatrix& init(const Sparsesym& A,Real d=1.);
00116 inline Symmatrix& init(Integer nr,Real d);
00118 inline Symmatrix& init(Integer nr,Real* dp);
00119
00126 void newsize(Integer n);
00127
00128
00130
00134
00136 inline Symmatrix(const Matrix&,double d=1.);
00138 inline Symmatrix(const Indexmatrix&,double d=1.);
00140 inline Symmatrix(const Sparsesym& A,Real d=1.);
00141
00143
00144
00145
00146
00147
00151
00153 void dim(Integer& _nr, Integer& _nc) const {_nr=nr; _nc=nr;}
00154
00156 Integer dim() const {return nr;}
00157
00159 Integer rowdim() const {return nr;}
00160
00162 Integer coldim() const {return nr;}
00163
00165 Mtype get_mtype() const {return mtype;}
00166
00168
00169
00170
00171
00172
00173
00177
00179 inline Real& operator()(Integer i,Integer j);
00180
00182 inline Real& operator()(Integer i);
00183
00185 inline Real operator()(Integer i,Integer j) const;
00186
00188 inline Real operator()(Integer i) const;
00189
00191 Matrix col(Integer i) const;
00193 Matrix row(Integer i) const;
00194
00196 Real* get_store() {return m;}
00198 const Real* get_store() const {return m;}
00199
00201
00202
00206
00208 friend Matrix diag(const Symmatrix& A);
00210 friend Symmatrix Diag(const Matrix& A);
00211
00213 friend inline void swap(Symmatrix& A,Symmatrix& B);
00214
00216
00217
00218
00219
00220
00224
00226 Symmatrix& xeya(const Symmatrix& A,Real d=1.);
00228 Symmatrix& xpeya(const Symmatrix& A,Real d=1.);
00229
00230
00232
00236
00238 friend Symmatrix& rankadd(const Matrix& A,Symmatrix& C,
00239 Real alpha=1.,Real beta=0.,int trans=0);
00241 friend Symmatrix& rank2add(const Matrix& A, const Matrix& B, Symmatrix& C,
00242 Real alpha=1.,Real beta=0.,int trans=0);
00243
00244
00246 friend inline Symmatrix& xbpeya(Symmatrix& x,const Symmatrix& y,Real alpha=1.,Real beta=0.);
00247
00248
00250 friend inline Symmatrix& xeyapzb(Symmatrix& x,const Symmatrix& y,const Symmatrix& z,Real alpha=1.,Real beta=1.);
00251
00253 friend Matrix& genmult(const Symmatrix& A,const Matrix& B,Matrix& C,
00254 Real alpha=1., Real beta=0., int btrans=0);
00255
00257 friend Matrix& genmult(const Matrix& A,const Symmatrix& B,Matrix& C,
00258 Real alpha=1., Real beta=0., int atrans=0);
00259
00261
00262
00263
00264
00265
00269
00271 inline Symmatrix& operator=(const Symmatrix &A);
00273 inline Symmatrix& operator+=(const Symmatrix &A);
00275 inline Symmatrix& operator-=(const Symmatrix &A);
00277 inline Symmatrix& operator%=(const Symmatrix &A);
00279 inline Symmatrix operator-() const;
00280
00282 inline Symmatrix& operator*=(Real d);
00284 inline Symmatrix& operator/=(Real d);
00286 inline Symmatrix& operator+=(Real d);
00288 inline Symmatrix& operator-=(Real d);
00289
00291 Symmatrix& transpose(){return *this;}
00292
00294
00298
00300 friend inline Matrix operator*(const Symmatrix &A,const Symmatrix &B);
00302 friend inline Symmatrix operator%(const Symmatrix &A,const Symmatrix &B);
00304 friend inline Symmatrix operator+(const Symmatrix &A,const Symmatrix &B);
00306 friend inline Symmatrix operator-(const Symmatrix &A,const Symmatrix &B);
00308 friend inline Matrix operator*(const Symmatrix &A,const Matrix &B);
00310 friend inline Matrix operator*(const Matrix &A,const Symmatrix &B);
00312 friend inline Matrix operator+(const Symmatrix &A,const Matrix &B);
00314 friend inline Matrix operator+(const Matrix &A,const Symmatrix &B);
00316 friend inline Matrix operator-(const Symmatrix &A,const Matrix &B);
00318 friend inline Matrix operator-(const Matrix &A,const Symmatrix &B);
00319
00321 friend inline Symmatrix operator*(const Symmatrix &A,Real d);
00323 friend inline Symmatrix operator*(Real d,const Symmatrix &A);
00325 friend inline Symmatrix operator/(const Symmatrix &A,Real d);
00327 friend inline Symmatrix operator+(const Symmatrix &A,Real d);
00329 friend inline Symmatrix operator+(Real d,const Symmatrix &A);
00331 friend inline Symmatrix operator-(const Symmatrix &A,Real d);
00333 friend inline Symmatrix operator-(Real d,const Symmatrix &A);
00334
00336 friend inline Symmatrix transpose(const Symmatrix& A);
00337
00339
00340
00341
00342
00343
00347
00349 Symmatrix& xeya(const Matrix& A,Real d=1.);
00351 Symmatrix& xpeya(const Matrix& A,Real d=1.);
00353 Symmatrix& xeya(const Indexmatrix& A,Real d=1.);
00355 Symmatrix& xpeya(const Indexmatrix& A,Real d=1.);
00357 Symmatrix& xeya(const Sparsesym& A,Real d=1.);
00359 Symmatrix& xpeya(const Sparsesym& A,Real d=1.);
00360
00362 Symmatrix& xetriu_yza(const Matrix& A,const Matrix& B,Real d=1.);
00364 Symmatrix& xpetriu_yza(const Matrix& A,const Matrix& B,Real d=1.);
00366 Symmatrix& xetriu_yza(const Sparsemat& A,const Matrix& B,Real d=1.);
00368 Symmatrix& xpetriu_yza(const Sparsemat& A,const Matrix& B,Real d=1.);
00369
00371 inline Symmatrix& operator=(const Sparsesym& A);
00373 inline Symmatrix& operator+=(const Sparsesym& A);
00375 inline Symmatrix& operator-=(const Sparsesym& A);
00376
00378
00382
00384 friend Matrix& genmult(const Symmatrix& A,const Sparsemat& B,Matrix& C,
00385 Real alpha=1.,Real beta=0., int btrans=0);
00386
00388 friend Matrix& genmult(const Sparsemat& A,const Symmatrix& B,Matrix& C,
00389 Real alpha=1.,Real beta=0., int atrans=0);
00390
00392 friend Symmatrix& rankadd(const Sparsemat& A,Symmatrix& C,
00393 Real alpha=1.,Real beta=0.,int trans=0);
00394
00396 friend Symmatrix& rank2add(const Sparsemat& A,const Matrix& B,Symmatrix& C,
00397 Real alpha=1.,Real beta=0.,int trans=0);
00398
00400
00401
00402
00403
00404
00405
00409
00410 friend Symmatrix abs(const Symmatrix& A);
00411
00413
00414
00415
00416
00417
00421
00423 Symmatrix& shift_diag(Real s);
00424
00425
00427 int LDLfactor(Real tol=1e-10);
00429 int LDLsolve(Matrix& x) const;
00431 int LDLinverse(Symmatrix& S) const;
00432
00433
00435 int Chol_factor(Real tol=1e-10);
00437 int Chol_solve(Matrix& x) const;
00439 int Chol_inverse(Symmatrix& S) const;
00441 int Chol_Lsolve(Matrix& rhs) const;
00443 int Chol_scaleLi(Symmatrix& S) const;
00445 int Chol_Ltmult(Matrix& rhs) const;
00447 int Chol_factor(Indexmatrix &piv, Real tol=1e-10);
00449 int Chol_solve(Matrix& x,const Indexmatrix& piv) const;
00451 int Chol_inverse(Symmatrix& S,const Indexmatrix & piv) const;
00452
00453
00455 Integer eig(Matrix& P,Matrix& d,bool sort_non_decreasingly=true) const;
00456
00457
00458
00460
00464
00466 friend Real trace(const Symmatrix& A);
00468 friend Real ip(const Symmatrix& A, const Symmatrix& B);
00470 friend Real ip(const Matrix& A, const Symmatrix& B);
00472 friend Real ip(const Symmatrix& A, const Matrix& B);
00474 friend inline Real norm2(const Symmatrix& A);
00475
00477 friend Matrix sumrows(const Symmatrix& A);
00479 friend Matrix sumcols(const Symmatrix& A);
00481 friend Real sum(const Symmatrix& A);
00482
00483
00485 friend void svec(const Symmatrix& A,Matrix& v);
00487 friend inline Matrix svec(const Symmatrix& A);
00489 friend void sveci(const Matrix& v,Symmatrix& A);
00490
00492 friend inline Symmatrix skron(const Symmatrix& A,const Symmatrix& B);
00494 friend void skron(const Symmatrix& A,const Symmatrix& B,Symmatrix& S);
00495
00497
00498
00499
00500
00501
00505
00507 friend Matrix minrows(const Symmatrix& A);
00509 friend Matrix mincols(const Symmatrix& A);
00511 friend Real min(const Symmatrix& A);
00513 friend Matrix maxrows(const Symmatrix& A);
00515 friend Matrix maxcols(const Symmatrix& A);
00517 friend Real max(const Symmatrix& A);
00518
00519
00521
00522
00523
00524
00525
00526
00530
00533 void display(std::ostream& out,
00534 int precision=0,
00535 int width=0,
00536 int screenwidth=0
00537 ) const;
00538
00540
00544
00546 friend std::ostream& operator<<(std::ostream& o,const Symmatrix &A);
00547
00549 friend std::istream& operator>>(std::istream& i,Symmatrix &A);
00550
00552
00553
00554 };
00555
00556
00558
00559
00560
00561
00562
00563 Matrix diag(const Symmatrix& A);
00564 Symmatrix Diag(const Matrix& A);
00565 Symmatrix& rankadd(const Matrix& A,Symmatrix& C,
00566 Real alpha,Real beta,int trans);
00567 Symmatrix& rank2add(const Matrix& A, const Matrix& B, Symmatrix& C,
00568 Real alpha,Real beta,int trans);
00569 Matrix& genmult(const Symmatrix& A,const Matrix& B,Matrix& C,
00570 Real alpha, Real beta, int btrans);
00571 Matrix& genmult(const Matrix& A,const Symmatrix& B,Matrix& C,
00572 Real alpha, Real beta, int atrans);
00573 Matrix& genmult(const Symmatrix& A,const Sparsemat& B,Matrix& C,
00574 Real alpha,Real beta, int btrans);
00575 Matrix& genmult(const Sparsemat& A,const Symmatrix& B,Matrix& C,
00576 Real alpha,Real beta, int atrans);
00577 Symmatrix& rankadd(const Sparsemat& A,Symmatrix& C,
00578 Real alpha,Real beta,int trans);
00579 Symmatrix& rank2add(const Sparsemat& A,const Matrix& B,Symmatrix& C,
00580 Real alpha,Real beta,int trans);
00581 Symmatrix abs(const Symmatrix& A);
00582 Real trace(const Symmatrix& A);
00583 Real ip(const Symmatrix& A, const Symmatrix& B);
00584 Real ip(const Matrix& A, const Symmatrix& B);
00585 Real ip(const Symmatrix& A, const Matrix& B);
00586 Matrix sumrows(const Symmatrix& A);
00587 Matrix sumcols(const Symmatrix& A);
00588 Real sum(const Symmatrix& A);
00589 void svec(const Symmatrix& A,Matrix& sv);
00590 void sveci(const Matrix& sv,Symmatrix& A);
00591 void skron(const Symmatrix& A,const Symmatrix& B,Symmatrix& S);
00592 Matrix minrows(const Symmatrix& A);
00593 Matrix mincols(const Symmatrix& A);
00594 Real min(const Symmatrix& A);
00595 Matrix maxrows(const Symmatrix& A);
00596 Matrix maxcols(const Symmatrix& A);
00597 Real max(const Symmatrix& A);
00598 std::ostream& operator<<(std::ostream& o,const Symmatrix &A);
00599 std::istream& operator>>(std::istream& i,Symmatrix &A);
00600
00601
00602
00603
00604
00605
00606 inline void Symmatrix::init_to_zero()
00607 {
00608 nr=0;mem_dim=0;m=0;
00609 #if (CONICBUNDLE_DEBUG>=1)
00610 is_init=1;
00611 #endif
00612 }
00613
00614 inline Symmatrix& Symmatrix::init(const Symmatrix& A,double d)
00615 { return xeya(A,d); }
00616
00617 inline Symmatrix& Symmatrix::init(const Matrix& A,double d)
00618 { return xeya(A,d); }
00619
00620 inline Symmatrix& Symmatrix::init(const Indexmatrix& A,double d)
00621 { return xeya(A,d); }
00622
00623 inline Symmatrix& Symmatrix::init(Integer inr,Real d)
00624 {
00625 newsize(inr);
00626 mat_xea((nr*(nr+1))/2,m,d);
00627 chk_set_init(*this,1);
00628 return *this;
00629 }
00630
00631 inline Symmatrix& Symmatrix::init(Integer inr,Real* pd)
00632 {
00633 newsize(inr);
00634 mat_xey((nr*(nr+1))/2,m,pd);
00635 chk_set_init(*this,1);
00636 return *this;
00637 }
00638
00639 inline Symmatrix::Symmatrix()
00640 { init_to_zero(); }
00641
00642 inline Symmatrix::Symmatrix(const Symmatrix& A,double d):Memarrayuser()
00643 {init_to_zero(); xeya(A,d);}
00644
00645 inline Symmatrix::Symmatrix(const Matrix &M,double d)
00646 { init_to_zero(); xeya(M,d); }
00647
00648 inline Symmatrix::Symmatrix(const Indexmatrix &M,double d)
00649 { init_to_zero(); xeya(M,d); }
00650
00651 inline Symmatrix::Symmatrix(Integer i)
00652 { init_to_zero(); newsize(i); }
00653
00654 inline Symmatrix::Symmatrix(Integer i,Real d)
00655 { init_to_zero(); init(i,d); }
00656
00657 inline Symmatrix::Symmatrix(Integer i,Real *pd)
00658 { init_to_zero(); init(i,pd); }
00659
00660 inline Symmatrix::~Symmatrix()
00661 {memarray->free(m);}
00662
00663 inline Real& Symmatrix::operator()(Integer i,Integer j)
00664 {
00665 chk_range(i,j,nr,nr);
00666 if (j>=i) return m[((i*((nr<<1)-(i+1)))>>1)+j];
00667 return m[((j*((nr<<1)-(j+1)))>>1)+i];
00668 }
00669
00670 inline Real Symmatrix::operator()(Integer i,Integer j) const
00671 {
00672 chk_range(i,j,nr,nr);
00673 if (j>=i) return m[((i*((nr<<1)-(i+1)))>>1)+j];
00674 return m[((j*((nr<<1)-(j+1)))>>1)+i];
00675 }
00676
00677 inline Real& Symmatrix::operator()(Integer i)
00678 {
00679 chk_range(i,0,nr*nr,1);
00680 Integer j=i/nr;
00681 i=i%nr;
00682 if (j>=i) return m[((i*((nr<<1)-(i+1)))>>1)+j];
00683 return m[((j*((nr<<1)-(j+1)))>>1)+i];
00684 }
00685
00686 inline Real Symmatrix::operator()(Integer i) const
00687 {
00688 chk_range(i,0,nr*nr,1);
00689 Integer j=i/nr;
00690 i=i%nr;
00691 if (j>=i) return m[((i*((nr<<1)-(i+1)))>>1)+j];
00692 return m[((j*((nr<<1)-(j+1)))>>1)+i];
00693 }
00694
00695 inline void swap(Symmatrix &A,Symmatrix &B)
00696 {
00697 Real *hm=A.m;A.m=B.m;B.m=hm;
00698 Integer hi=A.nr;A.nr=B.nr;B.nr=hi;
00699 hi=A.mem_dim;A.mem_dim=B.mem_dim;B.mem_dim=hi;
00700 #if (CONICBUNDLE_DEBUG>=1)
00701 hi=A.is_init;A.is_init=B.is_init;B.is_init=hi;
00702 #endif
00703 }
00704
00705 inline Symmatrix& xbpeya(Symmatrix& x,const Symmatrix& y,Real alpha,Real beta)
00706
00707
00708 {
00709 if (beta==0.){
00710 chk_init(y);
00711 x.init(y,alpha);
00712 }
00713 else {
00714 chk_add(x,y);
00715 mat_xbpeya((x.rowdim()*(x.rowdim()+1))/2,
00716 x.get_store(),y.get_store(),alpha,beta);
00717 }
00718 return x;
00719 }
00720
00721 inline Symmatrix& xeyapzb(Symmatrix& x,const Symmatrix& y,const Symmatrix& z,Real alpha,Real beta)
00722
00723
00724 {
00725 chk_add(y,z);
00726 x.newsize(y.rowdim()); chk_set_init(x,1);
00727 mat_xeyapzb((x.rowdim()*(x.rowdim()+1))/2,
00728 x.get_store(),y.get_store(),z.get_store(),alpha,beta);
00729 return x;
00730 }
00731
00732 inline Symmatrix& Symmatrix::operator=(const Symmatrix &A)
00733 {return xeya(A);}
00734 inline Symmatrix& Symmatrix::operator+=(const Symmatrix &A)
00735 {return xpeya(A);}
00736 inline Symmatrix& Symmatrix::operator-=(const Symmatrix &A)
00737 {return xpeya(A,-1.);}
00738 inline Symmatrix& Symmatrix::operator%=(const Symmatrix &A)
00739 { chk_add(*this,A); mat_xhadey((nr*(nr+1))/2,m,A.m); return *this; }
00740 inline Symmatrix Symmatrix::operator-() const
00741 {return Symmatrix(*this,-1.);}
00742
00743 inline Symmatrix& Symmatrix::operator*=(Real d)
00744 {chk_init(*this); mat_xmultea(nr*(nr+1)/2,m,d); return *this;}
00745 inline Symmatrix& Symmatrix::operator/=(Real d)
00746 {chk_init(*this); mat_xmultea(nr*(nr+1)/2,m,1./d); return *this;}
00747 inline Symmatrix& Symmatrix::operator+=(Real d)
00748 {chk_init(*this); mat_xpea(nr*(nr+1)/2,m,d); return *this;}
00749 inline Symmatrix& Symmatrix::operator-=(Real d)
00750 {chk_init(*this); mat_xpea(nr*(nr+1)/2,m,-d); return *this;}
00751
00752 inline Matrix operator*(const Symmatrix &A,const Symmatrix &B)
00753 {Matrix C;return genmult(Matrix(A),B,C);}
00754 inline Symmatrix operator%(const Symmatrix &A,const Symmatrix &B)
00755 {Symmatrix C(A);C%=B;return C;}
00756 inline Symmatrix operator+(const Symmatrix &A,const Symmatrix &B)
00757 {Symmatrix C(A);return C.xpeya(B);}
00758 inline Symmatrix operator-(const Symmatrix &A,const Symmatrix &B)
00759 {Symmatrix C(A);return C.xpeya(B,-1.);}
00760 inline Matrix operator*(const Symmatrix &A,const Matrix &B)
00761 {Matrix C; return genmult(A,B,C);}
00762 inline Matrix operator*(const Matrix &A,const Symmatrix &B)
00763 {Matrix C; return genmult(A,B,C);}
00764 inline Matrix operator+(const Symmatrix &A,const Matrix &B)
00765 {Matrix C(A);return C.xpeya(B);}
00766 inline Matrix operator+(const Matrix &A,const Symmatrix &B)
00767 {Matrix C(A);return C.xpeya(B);}
00768 inline Matrix operator-(const Symmatrix &A,const Matrix &B)
00769 {Matrix C(A);return C.xpeya(B,-1);}
00770 inline Matrix operator-(const Matrix &A,const Symmatrix &B)
00771 {Matrix C(A);return C.xpeya(B,-1);}
00772
00773 inline Symmatrix operator*(const Symmatrix& A,Real d)
00774 { return Symmatrix(A,d);}
00775 inline Symmatrix operator*(Real d,const Symmatrix &A)
00776 { return Symmatrix(A,d);}
00777 inline Symmatrix operator/(const Symmatrix& A,Real d)
00778 { return Symmatrix(A,1./d);}
00779 inline Symmatrix operator+(const Symmatrix& A,Real d)
00780 { Symmatrix B(A); return B+=d;}
00781 inline Symmatrix operator+(Real d,const Symmatrix &A)
00782 {Symmatrix B(A); return B+=d;}
00783 inline Symmatrix operator-(const Symmatrix& A,Real d)
00784 { Symmatrix B(A); return B-=d;}
00785 inline Symmatrix operator-(Real d,const Symmatrix &A)
00786 { Symmatrix B(A,-1.);return B+=d;}
00787
00788
00789 inline Matrix svec(const Symmatrix& A)
00790 {Matrix sv;svec(A,sv);return sv;}
00791 inline Symmatrix skron(const Symmatrix& A,const Symmatrix& B)
00792 {Symmatrix S;skron(A,B,S);return S;}
00793
00794 inline Real norm2(const Symmatrix& A)
00795 {return ::sqrt(ip(A,A));}
00796 inline Symmatrix transpose(const Symmatrix& A)
00797 {return Symmatrix(A);}
00798
00799
00800 inline Matrix::Matrix(const Symmatrix &A,Real d)
00801
00802 {init_to_zero(); xeya(A,d);}
00803
00804 inline Matrix& Matrix::init(const Symmatrix &A,Real d)
00805
00806 { return xeya(A,d); }
00807
00808 inline Matrix& Matrix::operator=(const Symmatrix &A)
00809
00810 { return xeya(A); }
00811
00812 inline Matrix& Matrix::operator*=(const Symmatrix &A)
00813
00814 { Matrix C; return *this=genmult(*this,A,C);}
00815
00816 inline Matrix& Matrix::operator+=(const Symmatrix &A)
00817
00818 { return xpeya(A); }
00819
00820 inline Matrix& Matrix::operator-=(const Symmatrix &A)
00821
00822 { return xpeya(A,-1.); }
00823
00824
00825 }
00826
00827 #ifndef CH_MATRIX_CLASSES__SPARSMAT_HXX
00828 #include "sparsmat.hxx"
00829 #endif
00830
00831 #endif
00832