ConicBundle
CMsymsparse.hxx
Go to the documentation of this file.
1 
2 #ifndef CONICBUNDLE_CMSYMSPARSE_HXX
3 #define CONICBUNDLE_CMSYMSPARSE_HXX
4 
13 #include "CMsymdense.hxx"
14 #include "sparssym.hxx"
15 
16 namespace ConicBundle {
17 
21 
26  class CMsymsparse: public Coeffmat
27  {
28  private:
31  public:
34  {A=Ain;CM_type=CM_symsparse;infop=cip; use_sparsemult=false;
35  if (A.get_suppcol().rowdim()<A.rowdim()/2) use_sparsemult=true; }
37  virtual ~CMsymsparse(){}
38 
39  //virtual CM_type get_type() const {return CM_type;} //no need to overload
40  //virtual CH_Matrix_Classes::Integer get_userkey() const {return userkey;}
41  //virtual void set_userkey(CH_Matrix_Classes::Integer k) const {userkey=k;}
42 
44  virtual Coeffmat* clone() const
45  { return new CMsymsparse(A,ConicBundle::clone(infop)); }
46 
48  virtual CH_Matrix_Classes::Integer dim() const {return A.rowdim();}
49 
52 
54  virtual void make_symmatrix(CH_Matrix_Classes::Symmatrix& S) const {S=A;}
55 
57  virtual CH_Matrix_Classes::Real norm(void) const {return CH_Matrix_Classes::norm2(A);}
58 
60  virtual Coeffmat* subspace(const CH_Matrix_Classes::Matrix& P) const
61  {
63  if (use_sparsemult) S.xetriu_yza(A.sparsemult(P),P);
64  else S.xetriu_yza(A*P,P);
65  return new CMsymdense(S,ConicBundle::clone(infop));
66  }
67 
70  {A*=d; if (infop) infop->multiply(d);}
71 
74 
77  {if (use_sparsemult) return CH_Matrix_Classes::ip(A.sparsemult(P),P); return CH_Matrix_Classes::ip(A*P,P);}
78 
81  {
84  CH_Matrix_Classes::Matrix B(suppcol.dim(),P.coldim(),0.);
86  const CH_Matrix_Classes::Integer brd=B.rowdim();
87  const CH_Matrix_Classes::Integer pcd=P.coldim();
88  const CH_Matrix_Classes::Integer prd=P.rowdim();
89  const CH_Matrix_Classes::Real *pp=P.get_store()+start_row;
90  const CH_Matrix_Classes::Real *vp=(A.get_colval()).get_store();
91  const CH_Matrix_Classes::Integer *ip=(A.get_colindex()).get_store();
92  const CH_Matrix_Classes::Integer *sip=(A.get_suppind()).get_store();
93  for(CH_Matrix_Classes::Integer j=0;j<colinfo.rowdim();j++){
94  CH_Matrix_Classes::Integer indj=colinfo(j,0);
95  if (indj<0){ //"column" is the diagonal
96  for(CH_Matrix_Classes::Integer i=colinfo(j,1);--i>=0;){
97  CH_Matrix_Classes::mat_xpeya(pcd,bp+(*sip++),brd,pp+(*ip++),prd,(*vp++));
98  }
99  continue;
100  }
101  //offdiagonal
102  CH_Matrix_Classes::Integer sindj=colinfo(j,3);
103  for(CH_Matrix_Classes::Integer i=colinfo(j,1);--i>=0;){
104  CH_Matrix_Classes::mat_xpeya(pcd,bp+sindj,brd,pp+(*ip++)+indj,prd,(*vp));
105  CH_Matrix_Classes::mat_xpeya(pcd,bp+(*sip++)+sindj,brd,pp+indj,prd,(*vp++));
106  }
107  }
108  //take inner product
109  CH_Matrix_Classes::Real trval=0.;
110  if (Lam==0){
111  for(CH_Matrix_Classes::Integer i=0;i<brd;i++){
112  const CH_Matrix_Classes::Real* pp2=pp+suppcol(i);
113  const CH_Matrix_Classes::Real* bp=B.get_store()+i;
114  trval+=CH_Matrix_Classes::mat_ip(pcd,bp,brd,pp2,prd);
115  }
116  }
117  else {
118  assert(Lam->dim()==P.coldim());
119  for(CH_Matrix_Classes::Integer i=0;i<brd;i++){
120  const CH_Matrix_Classes::Real* pp2=pp+suppcol(i);
121  const CH_Matrix_Classes::Real* bp=B.get_store()+i;
122  trval+=CH_Matrix_Classes::mat_ip(pcd,bp,brd,pp2,prd,Lam->get_store(),1);
123  }
124  }
125  return trval;
126  }
127 
130 
133  {if (use_sparsemult) B.xpeya(A.sparsemult(C),d); else B.xpeya(A*C,d); }
134 
137  { CH_Matrix_Classes::genmult(A,C,B,d,1.); }
138 
141  {
142  if (A.get_suppcol().dim()>A.rowdim()/2){
143  if (P.coldim()<Q.coldim()){
145  CH_Matrix_Classes::genmult(A,P,tmp1,1.,0.,0);
146  CH_Matrix_Classes::genmult(tmp1,Q,R,1.,0.,1,0);
147  }
148  else {
150  CH_Matrix_Classes::genmult(A,Q,tmp1,1.,0.,0);
151  CH_Matrix_Classes::genmult(P,tmp1,R,1.,0.,1,0);
152  }
153  }
154  else {
155  if (P.coldim()<Q.coldim()) CH_Matrix_Classes::genmult(A.sparsemult(P),Q,R,1.,0.,1,0);
156  else CH_Matrix_Classes::genmult(P,A.sparsemult(Q),R,1.,0.,1,0);
157  }
158  }
159 
162  { return 2*A.nonzeros(); }
163 
165  virtual int dense() const
166  {return 0;}
167 
169  virtual int sparse() const
170  { return 1;}
171 
174  { A.get_edge_rep(I,J,val); val*=d; return 1;}
175 
177  virtual int support_in(const CH_Matrix_Classes::Sparsesym& S) const
178  {return S.contains_support(A);}
179 
182  {return CH_Matrix_Classes::ip(A,S);}
183 
186  {
187  if (use_sparsemult) S.xetriu_yza(A.sparsemult(P),P);
188  else S.xetriu_yza(A*P,P);
189  }
190 
193  {
194  const CH_Matrix_Classes::Indexmatrix &colinfo=A.get_colinfo();
195  const CH_Matrix_Classes::Indexmatrix &suppcol=A.get_suppcol();
196  CH_Matrix_Classes::Matrix B(suppcol.dim(),P.coldim(),0.);
198  const CH_Matrix_Classes::Integer brd=B.rowdim();
199  const CH_Matrix_Classes::Integer pcd=P.coldim();
200  const CH_Matrix_Classes::Integer prd=P.rowdim();
201  const CH_Matrix_Classes::Real *pp=P.get_store()+start_row;
202  const CH_Matrix_Classes::Real *vp=(A.get_colval()).get_store();
203  const CH_Matrix_Classes::Integer *ip=(A.get_colindex()).get_store();
204  const CH_Matrix_Classes::Integer *sip=(A.get_suppind()).get_store();
205  for(CH_Matrix_Classes::Integer j=0;j<colinfo.rowdim();j++){
206  CH_Matrix_Classes::Integer indj=colinfo(j,0);
207  if (indj<0){ //"column" is the diagonal
208  for(CH_Matrix_Classes::Integer i=colinfo(j,1);--i>=0;){
209  CH_Matrix_Classes::mat_xpeya(pcd,bp+(*sip++),brd,pp+(*ip++),prd,(*vp++));
210  }
211  continue;
212  }
213  //offdiagonal
214  CH_Matrix_Classes::Integer sindj=colinfo(j,3);
215  for(CH_Matrix_Classes::Integer i=colinfo(j,1);--i>=0;){
216  CH_Matrix_Classes::mat_xpeya(pcd,bp+sindj,brd,pp+(*ip++)+indj,prd,(*vp));
217  CH_Matrix_Classes::mat_xpeya(pcd,bp+(*sip++)+sindj,brd,pp+indj,prd,(*vp++));
218  }
219  }
220  //add to S
221  for(CH_Matrix_Classes::Integer i=0;i<brd;i++){
223  const CH_Matrix_Classes::Real* pp2=pp+suppcol(i);
224  const CH_Matrix_Classes::Real* bp=B.get_store()+i;
225  for(CH_Matrix_Classes::Integer j=pcd;j>0;--j){
226  CH_Matrix_Classes::mat_xpeya(j,sp,1,bp,brd,alpha*(*pp2));
227  sp+=j;
228  bp+=brd;
229  pp2+=prd;
230  }
231  }
232  }
233  // S=P^t*A*P
234 
237  CH_Matrix_Classes::Real alpha=1.,CH_Matrix_Classes::Real beta=0.,int btrans=0) const
238  {
239  return CH_Matrix_Classes::genmult(A,B,C,alpha,beta,btrans);
240  }
241 
244  CH_Matrix_Classes::Real alpha=1.,CH_Matrix_Classes::Real beta=0.,int btrans=0) const
245  {
247  return CH_Matrix_Classes::genmult(B,A,C,alpha,beta,btrans);
248  }
249 
251  virtual int equal(const Coeffmat* p,double tol=1e-6) const
252  {
253  const CMsymsparse *pp=dynamic_cast<const CMsymsparse *>(p);
254  if (pp==0)
255  return 0;
256  return CH_Matrix_Classes::equal(A,pp->A,tol);
257  }
258 
260  virtual std::ostream& display(std::ostream& o) const
261  {o<<"CMsymsparse\n";A.display(o); return o;}
262 
264  virtual std::ostream& out(std::ostream& o) const
265  {return o<<"SYMMETRIC_SPARSE\n"<<A;}
266 
268  virtual std::istream& in(std::istream& i)
269  {return i>>A;}
270 
272  CMsymsparse(std::istream& is,CoeffmatInfo* cip=0)
273  {CM_type=CM_symsparse;infop=cip;in(is);use_sparsemult=false;
274  if (A.get_suppcol().rowdim()<A.rowdim()/2) use_sparsemult=true;
275  }
276 
277  //--- specific routines
279  const CH_Matrix_Classes::Sparsesym& get_A() const{return A;}
280 
281  };
282 
283 }
284 
285 #endif
286 
int Integer
all integer numbers in calculations and indexing are of this type
Definition: matop.hxx:40
virtual void addmeto(CH_Matrix_Classes::Symmatrix &S, CH_Matrix_Classes::Real d=1.) const
computes S+=d*(*this);
Definition: CMsymsparse.hxx:129
const Indexmatrix & get_colindex() const
returns the index vector of the column representation holding the row index for each element ...
Definition: sparssym.hxx:246
virtual void multiply(CH_Matrix_Classes::Real d)
multiply constraint permanentely by d; this is to allow scaling or sign changes in the constraints ...
Definition: CMsymsparse.hxx:69
Matrix & xpeya(const Matrix &A, Real d=1.)
sets *this+=d*A and returns *this
virtual std::ostream & out(std::ostream &o) const
put entire contents onto outstream with the class type in the beginning so that the derived class can...
Definition: CMsymsparse.hxx:264
Integer rowdim() const
returns the row dimension
Definition: matrix.hxx:215
double Real
all real numbers in calculations are of this type
Definition: matop.hxx:50
allows to memorize the scalings applied to a Coeffmat and offers the basis for storing further user d...
Definition: Coeffmat.hxx:52
Sparsemat sparsemult(const Matrix &A) const
compute (*this)*A and return the result in a Sparsemat
virtual Coeffmat * subspace(const CH_Matrix_Classes::Matrix &P) const
delivers a new object on the heap corresponding to the matrix P^T(*this)P, the caller is responsible ...
Definition: CMsymsparse.hxx:60
Real * get_store()
returns the current address of the internal value array; use cautiously, do not use delete! ...
Definition: symmat.hxx:224
const Indexmatrix & get_colinfo() const
returns information on nozero diagonal/columns, k by 4, listing: index (<0 for diagonal), # nonzeros, first index in colindex/colval, index in suppport submatrix
Definition: sparssym.hxx:243
CMsymsparse(std::istream &is, CoeffmatInfo *cip=0)
constructor with instream and possibly additional user information
Definition: CMsymsparse.hxx:272
defines a base class for coefficient matrices in semidefinite programming, in particular for use with...
Definition: Coeffmat.hxx:125
CMsymsparse(const CH_Matrix_Classes::Sparsesym &Ain, CoeffmatInfo *cip=0)
copy Ain and possibly store the user information, set use_sparsemult to true if at least half the row...
Definition: CMsymsparse.hxx:33
Matrix class for integral values of type Integer
Definition: indexmat.hxx:195
int contains_support(const Sparsesym &A) const
returns 1 if A is of the same dimension and the support of A is contained in the support of *this...
virtual CH_Matrix_Classes::Real norm(void) const
returns the Frobenius norm of the matrix
Definition: CMsymsparse.hxx:57
virtual void left_right_prod(const CH_Matrix_Classes::Matrix &P, const CH_Matrix_Classes::Matrix &Q, CH_Matrix_Classes::Matrix &R) const
computes R=P^T*(*this)*Q
Definition: CMsymsparse.hxx:140
Real norm2(const Matrix &A)
returns the Frobenius norm of A, i.e., the square root of the sum of A(i,j)*A(i,j) over all i...
Definition: matrix.hxx:1235
Integer rowdim() const
returns the row dimension
Definition: sparssym.hxx:212
virtual CH_Matrix_Classes::Real gramip(const CH_Matrix_Classes::Matrix &P, CH_Matrix_Classes::Integer start_row, const CH_Matrix_Classes::Matrix *Lam=0) const
returns ip(*this,QQ^T)=trace Q^T(*this)Q for Q=P.rows(start_row,start_row+dim-1)
Definition: CMsymsparse.hxx:80
virtual CH_Matrix_Classes::Integer prodvec_flops() const
returns an estimate of number of flops to compute addprodto for a vector
Definition: CMsymsparse.hxx:161
Symmatrix & xetriu_yza(const Matrix &A, const Matrix &B, Real d=1.)
sets *this(i,j), i<=j to the upper triangle of the matrix product d*transpose(A)*B ...
Real * get_store()
returns the current address of the internal value array; use cautiously, do not use delete! ...
Definition: matrix.hxx:326
Matrix class of symmetric matrices with real values of type Real
Definition: symmat.hxx:43
for CMsymsparse
Definition: Coeffmat.hxx:32
virtual void make_symmatrix(CH_Matrix_Classes::Symmatrix &S) const
returns a dense symmetric constraint matrix
Definition: CMsymsparse.hxx:54
bool use_sparsemult
if the result of a product is likely sparse, exploit this
Definition: CMsymsparse.hxx:30
conic bundle method solver for sum of convex functions. See the ConicBundle_Manual for a quick introd...
Definition: CBSolver.hxx:22
implements a general sparse symmetric Coeffmat based on CH_Matrix_Classes::Sparsesym (for use with Ma...
Definition: CMsymsparse.hxx:26
Coeffmattype CM_type
in order to enable type identification
Definition: Coeffmat.hxx:134
CoeffmatInfo * infop
allows the user to specify and output additional information
Definition: Coeffmat.hxx:135
implements a general dense symmetric Coeffmat based on CH_Matrix_Classes::Symmatrix (for use with Mat...
Definition: CMsymdense.hxx:27
virtual void project(CH_Matrix_Classes::Symmatrix &S, const CH_Matrix_Classes::Matrix &P) const
computes S=P^T*(*this)*P
Definition: CMsymsparse.hxx:185
const Indexmatrix & get_suppind() const
returns the index vector of the column representation holding the row index w.r.t. the principal support submatrix for each element
Definition: sparssym.hxx:250
Matrix class of symmetric matrices with real values of type Real
Definition: sparssym.hxx:89
virtual std::istream & in(std::istream &i)
counterpart to out(), does not read the class type, though. This is assumed to have been read in orde...
Definition: CMsymsparse.hxx:268
void multiply(CH_Matrix_Classes::Real sf)
scales the scale factor
Definition: Coeffmat.hxx:70
virtual const CH_Matrix_Classes::Matrix & pregenmult(const CH_Matrix_Classes::Matrix &B, CH_Matrix_Classes::Matrix &C, CH_Matrix_Classes::Real alpha=1., CH_Matrix_Classes::Real beta=0., int btrans=0) const
computes C= alpha*B^(T if btrans)*(*this) + beta*C, C is also returned
Definition: CMsymsparse.hxx:243
virtual int support_in(const CH_Matrix_Classes::Sparsesym &S) const
returns 0 if the support of the costraint matrix is not contained in the support of the sparse symmet...
Definition: CMsymsparse.hxx:177
Integer coldim() const
returns the column dimension
Definition: matrix.hxx:218
CH_Matrix_Classes::Sparsesym A
the sparse coefficient matrix
Definition: CMsymsparse.hxx:29
Integer nonzeros() const
returns the number of nonzeros in the lower triangle (including diagonal)
Definition: sparssym.hxx:218
void get_edge_rep(Indexmatrix &I, Indexmatrix &J, Matrix &val) const
stores the nz nonzero values of the lower triangle of *this in I,J,val so that this(I(i),J(i))=val(i) for i=0,...,nz-1 and dim(I)=dim(J)=dim(val)=nz (ordered as in row representation)
Matrix class for real values of type Real
Definition: matrix.hxx:74
void display(std::ostream &out, int precision=0, int width=0, int screenwidth=0) const
displays a matrix in a pretty way for bounded screen widths; for variables of value zero default valu...
const Matrix & get_colval() const
returns the value vector of the column representation holding the value for each element ...
Definition: sparssym.hxx:248
virtual CH_Matrix_Classes::Real gramip(const CH_Matrix_Classes::Matrix &P) const
returns ip(*this,PP^T)=trace P^T(*this)P
Definition: CMsymsparse.hxx:76
Val mat_ip(Integer len, const Val *x, const Val *y, const Val *d=0)
return sum(x[i]*y[i]) summing over len elements of the arrays x and y.
Definition: matop.hxx:1096
Matrix class of sparse matrices with real values of type Real
Definition: sparsmat.hxx:74
void mat_xpeya(Integer len, Val *x, const Val *y, const Val a)
Set x[i]+=a*y[i] for len elements of the arrays x and y.
Definition: matop.hxx:543
const Indexmatrix & get_suppcol() const
returns the vector listing in ascending order the original column indices of the principal support su...
Definition: sparssym.hxx:252
const CH_Matrix_Classes::Sparsesym & get_A() const
return the const reference to the internal sparse matrix
Definition: CMsymsparse.hxx:279
virtual int equal(const Coeffmat *p, double tol=1e-6) const
returns 1, if p is the same derived class and entries differ by less than tol, otherwise zero ...
Definition: CMsymsparse.hxx:251
virtual void add_projection(CH_Matrix_Classes::Symmatrix &S, const CH_Matrix_Classes::Matrix &P, CH_Matrix_Classes::Real alpha=1., CH_Matrix_Classes::Integer start_row=0) const
computes S+=Q^T(*this)Q for Q=P.rows(start_row,start_row+dim-1)
Definition: CMsymsparse.hxx:192
virtual int dense() const
returns 1 if its structure is as bad as its dense symmetric representation, otherwise 0 ...
Definition: CMsymsparse.hxx:165
virtual void addprodto(CH_Matrix_Classes::Matrix &B, const CH_Matrix_Classes::Sparsemat &C, CH_Matrix_Classes::Real d=1.) const
computes B+=d*(*this)*C
Definition: CMsymsparse.hxx:136
virtual int sparse() const
returns 0 if not sparse, otherwise 1
Definition: CMsymsparse.hxx:169
Integer rowdim() const
returns the row dimension
Definition: indexmat.hxx:321
virtual CH_Matrix_Classes::Real operator()(CH_Matrix_Classes::Integer i, CH_Matrix_Classes::Integer j) const
returns the value of the matrix element (i,j)
Definition: CMsymsparse.hxx:51
virtual int sparse(CH_Matrix_Classes::Indexmatrix &I, CH_Matrix_Classes::Indexmatrix &J, CH_Matrix_Classes::Matrix &val, CH_Matrix_Classes::Real d=1.) const
returns 0 if not sparse. If it is sparse it returns 1 and the nonzero structure in I...
Definition: CMsymsparse.hxx:173
virtual const CH_Matrix_Classes::Matrix & postgenmult(const CH_Matrix_Classes::Matrix &B, CH_Matrix_Classes::Matrix &C, CH_Matrix_Classes::Real alpha=1., CH_Matrix_Classes::Real beta=0., int btrans=0) const
computes C= alpha*(*this)*B^(T if btrans) + beta*C, C is also returned
Definition: CMsymsparse.hxx:236
Indexmatrix & genmult(const Indexmatrix &A, const Indexmatrix &B, Indexmatrix &C, Integer alpha=1, Integer beta=0, int atrans=0, int btrans=0)
returns C=beta*C+alpha*A*B, where A and B may be transposed; C must not be equal to A and B; if beta=...
virtual Coeffmat * clone() const
makes an explicit copy of itself and returns a pointer to it
Definition: CMsymsparse.hxx:44
void dim(Integer &_nr, Integer &_nc) const
returns the number of rows in _nr and the number of columns in _nc
Definition: indexmat.hxx:315
virtual std::ostream & display(std::ostream &o) const
display constraint information
Definition: CMsymsparse.hxx:260
virtual CH_Matrix_Classes::Integer dim() const
returns the order of the represented symmetric matrix
Definition: CMsymsparse.hxx:48
bool equal(const Matrix &A, const Matrix &B)
returns true if both matrices have the same size and the same elements
Definition: matrix.hxx:1433
Header declaring the class CH_Matrix_Classes::Sparsesym for sparse symmetric matrices with Real eleme...
Header declaring the class ConicBundle::CMsymdense (needed for ConicBundle::AffineMatrixFunction) ...
CoeffmatInfo * clone(const CoeffmatInfo *cip)
if cip is not zero, it calls and returns cip->clone() and 0 otherwise
Definition: Coeffmat.hxx:106
Real ip(const Matrix &A, const Matrix &B)
returns the usual inner product of A and B, i.e., the sum of A(i,j)*B(i,j) over all i...
Definition: matrix.hxx:1165
virtual CH_Matrix_Classes::Real ip(const CH_Matrix_Classes::Sparsesym &S) const
returns the inner product of the constraint matrix with S
Definition: CMsymsparse.hxx:181
virtual void addprodto(CH_Matrix_Classes::Matrix &B, const CH_Matrix_Classes::Matrix &C, CH_Matrix_Classes::Real d=1.) const
computes B+=d*(*this)*C
Definition: CMsymsparse.hxx:132
Symmatrix & xpeya(const Symmatrix &A, Real d=1.)
sets *this+=d*A and returns *this
virtual CH_Matrix_Classes::Real ip(const CH_Matrix_Classes::Symmatrix &S) const
returns ip(*this,S)=trace(*this*S), the trace inner product
Definition: CMsymsparse.hxx:73