ATLAS Offline Software
AlSpaMat.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 // Original Author: Anthony Morley (15Jan2007)
6 // MKU (15Jan2007)
7 // PBdR (17Apr2007) interface ~identcal to AlSymMat
8 
9 #include "GaudiKernel/StatusCode.h"
11 
14 #include "TrkAlgebraUtils/AlVec.h"
15 #include "TrkAlgebraUtils/AlMat.h"
16 
17 #include <algorithm>
18 #include <cfloat>
19 #include <cmath>
20 #include <cstdint>
21 #include <fstream>
22 #include <iomanip>
23 #include <stdexcept>
24 
25 #include <TMatrixDSparse.h>
26 
27 
28 #include <Eigen/Core>
29 #include <Eigen/IterativeLinearSolvers>
30 #include <Eigen/SparseCholesky>
31 
32 
33 namespace Trk {
34 
35 //______________________________________________________________________________
37  : m_ptr_row(nullptr)
38  , m_ptr_col(nullptr)
39 {
40  m_matrix_type = 2;
41  m_size = 0;
42  m_nele = 0;
43 }
44 
45 //______________________________________________________________________________
47  : m_ptr_row(nullptr)
48  , m_ptr_col(nullptr)
49 {
50  m_matrix_type = 2;
51  m_size = N;
52  m_nele = 0;
53 }
54 
55 //______________________________________________________________________________
57  : AlSymMatBase(m)
58  , m_ptr_row(nullptr)
59  , m_ptr_col(nullptr)
60 {
61  m_matrix_type = 2;
62  m_size = m.size();
63  copy(m);
64 }
65 
66 //______________________________________________________________________________
68  : m_ptr_row(nullptr)
69  , m_ptr_col(nullptr)
70 {
71  m_matrix_type = 2;
72  m_size = m.size();
73  copy(m);
74 }
75 
76 //______________________________________________________________________________
78 {
79  m_ptr_map.clear();
80  if( m_ptr_row != nullptr ) delete [] m_ptr_row;
81  if( m_ptr_col != nullptr ) delete [] m_ptr_col;
82 }
83 
84 //______________________________________________________________________________
86 {
87  if( size() != m.size()) {
88  throw std::range_error( "AlSpaMat::copy: size do not match!" );
89  }
90  m_ptr_map.clear();
91  m_nele=m.m_nele;
92  m_ptr_map = m.m_ptr_map;
93 }
94 
95 //______________________________________________________________________________
97 {
98  if( size() != m.size()) {
99  throw std::range_error( "AlSpaMat::copy: size do not match!" );
100  }
101  m_ptr_map.clear();
102  m_nele=0;
103 
104  // Convert Storage System
105  for (int i = 0; i<m_size; i++)
106  for (int j = 0; j<=i; j++)
107  if (m.elemc(i,j) != 0.) {
108  m_ptr_map.insert(std::make_pair(std::make_pair(i,j), m.elemc(i,j)));
109  m_nele++;
110  }
111 
112  }
113 
114 //______________________________________________________________________________
115 void AlSpaMat::copy(const AlMat& m)
116 {
117  if( size() != m.nrow() || size() != m.ncol() ) {
118  throw std::range_error( "AlSpaMat::copy: size do not match!" );
119  }
120 
121  // copy just the lower triangle:
122  m_ptr_map.clear();
123  m_nele=0;
124 
125  //Convert Storage System
126  for (int i = 0; i<m_size; i++)
127  for (int j = 0; j<=i; j++)
128  if (m.elemc(i,j) != 0.) {
129  m_ptr_map.insert(std::make_pair(std::make_pair(i,j), m.elemc(i,j)));
130  m_nele++;
131  }
132 
133  }
134 
135 //______________________________________________________________________________
136 double& AlSpaMat::elemr(long int i,long int j)
137 {
138 #ifdef _DEBUG
139  if( i<0 ) {
140  throw std::out_of_range( "AlSpaMat::elemr: Index 1 < zero! " );
141  }
142  if( i>=size() ) {
143  throw std::out_of_range( "AlSpaMat::elemr: Index 1 too large! " );
144  }
145  if( j<0 ) {
146  throw std::out_of_range( "AlSpaMat::elemr: Index 2 < zero! " );
147  }
148  if( j>=size() ) {
149  throw std::out_of_range("AlSpaMat::elemr: Index 2 too large! " );;
150  }
151 #endif
152  // try fast referencing:
154  indices key = j < i ? std::make_pair(i,j) : std::make_pair(j,i);
155  pos=m_ptr_map.find(key);
156  if( pos!=m_ptr_map.end() ) // already exists
157  return pos->second;
158  else { // does not yet exist
159  // create it with the null value:
160  m_nele++;
161  return (m_ptr_map.insert(std::make_pair(key, 0.))).first->second;
162  }
163  // simpler implementation of the above:
164  /*
165  m_ptr_map[key]=0;
166  m_nele = m_ptr_map.size();
167  return m_ptr_map[key];
168  */
169 }
170 
171 //______________________________________________________________________________
172 double AlSpaMat::elemc(long int i,long int j) const
173 {
174 #ifdef _DEBUG
175  if( i<0 ) {
176  throw std::out_of_range( "AlSpaMat::elemc: Index 1 < zero! " );
177  }
178  if( i>=size() ) {
179  throw std::out_of_range( "AlSpaMat::elemc: Index 1 too large! " );
180  }
181  if( j<0 ) {
182  throw std::out_of_range( "AlSpaMat::elemc: Index 2 < zero! " );
183  }
184  if( j>=size() ) {
185  throw std::out_of_range( "AlSpaMat::elemc: Index 2 too large! " );
186  }
187 #endif
188  // try fast referencing:
190  indices key = j < i ? std::make_pair(i,j) : std::make_pair(j,i);
191  pos=m_ptr_map.find(key);
192 
193  if( pos!=m_ptr_map.end() ) // already exists
194  return pos->second;
195 
196  // does not yet exist
197  // return zero:
198  return 0.;
199 }
200 
201 //______________________________________________________________________________
202 indices AlSpaMat::elem(long int i,long int j)
203 {
204  // ATTENTION! the key value is returned:
205 #ifdef _DEBUG
206  if( i<0 ) {
207  throw std::out_of_range( "AlSpaMat::elem: Index 1 < zero! " );
208  }
209  if( i>=size() ) {
210  throw std::out_of_range( "AlSpaMat::elem: Index 1 too large! " );
211  }
212  if( j<0 ) {
213  throw std::out_of_range( "AlSpaMat::elem: Index 2 < zero! " );
214  }
215  if( j>=size() ) {
216  throw std::out_of_range( "AlSpaMat::elem: Index 2 too large! " );
217  }
218 #endif
219 
220  indices key = j < i ? std::make_pair(i,j) : std::make_pair(j,i);
221  return key;
222 }
223 
224 //______________________________________________________________________________
225 // cppcheck-suppress operatorEqVarError; m_ptr_row/col deliberately not copied.
227 {
228 
229  if ( this != &m ) {
230  m_size=m.size();
231  copy(m);
232  }
233  return *this;
234 }
235 
236 //______________________________________________________________________________
238 {
239  m_size=m.size();
240  copy(m);
241  return *this;
242 }
243 
244 //______________________________________________________________________________
246 {
247  if( m.nrow() != m.ncol() ) {
248  throw std::range_error( "AlSpaMat::=operator: allowed for square matrices only!" );
249  }
250 
251  m_size=m.nrow();
252  copy(m);
253  return *this;
254 }
255 
256 //______________________________________________________________________________
258 {
260  for (pos = m_ptr_map.begin(); pos!=m_ptr_map.end(); pos++)
261  pos->second = d;
262 
263  return *this;
264 }
265 
266 //______________________________________________________________________________
268 {
269  if( size() != m.size()) {
270  throw std::range_error( "AlSpaMat::operator+: size do not match!" );
271  }
272 
273  AlSpaMat b(m);
275  for (pos = m_ptr_map.begin(); pos!=m_ptr_map.end(); pos++)
276  b.m_ptr_map[pos->first] += pos->second;
277  b.m_nele = b.m_ptr_map.size();
278 
279  return b;
280 }
281 
282 //______________________________________________________________________________
284 {
285  if( size() != m.size()) {
286  throw std::range_error( "AlSpaMat::operator+=: size do not match!" );
287  }
288 
290  for (pos = m.m_ptr_map.begin(); pos!=m.m_ptr_map.end(); pos++)
291  (*this).m_ptr_map[pos->first] += pos->second;
292  m_nele = m_ptr_map.size();
293 
294  return *this;
295 }
296 
297 //______________________________________________________________________________
299 {
300  if( size() != m.size()) {
301  throw std::range_error( "AlSpaMat::operator-: size do not match!" );
302  }
303 
304  AlSpaMat b(m);
306  for (pos = m_ptr_map.begin(); pos!=m_ptr_map.end(); pos++)
307  b.m_ptr_map[pos->first] -= pos->second;
308  b.m_nele = b.m_ptr_map.size();
309 
310  return b;
311 }
312 
313 //______________________________________________________________________________
315 {
316  if( size() != m.size()) {
317  throw std::range_error( "AlSpaMat::operator-=: size do not match!" );
318  }
319 
321  for (pos = m.m_ptr_map.begin(); pos!=m.m_ptr_map.end(); pos++)
322  (*this).m_ptr_map[pos->first] -= pos->second;
323  m_nele = m_ptr_map.size();
324 
325  return *this;
326 }
327 
328 //______________________________________________________________________________
330 {
331  if( size() != m.size() ) {
332  throw std::range_error( "AlSpaMat::operator*: size do not match!" );
333  }
334 
335  long int isiz(size());
336  AlMat b( isiz, isiz);
337 
338  for( long int i=0; i<isiz; i++ )
339  for( long int j=0; j<isiz; j++ )
340  for( int k=0; k<isiz; k++)
341  b.elemr(i,j) += elemc(i,k)*m.elemc(k,j);
342 
343  return b;
344 }
345 
346 //______________________________________________________________________________
348  if( size() != m.nrow() ) {
349  throw std::range_error( "AlSpaMat::operator*: size do not match!" );
350  }
351 
352  long int isiz(size());
353  long int icol(m.ncol());
354  AlMat b( isiz, icol);
355 
356  for( long int i=0; i<isiz; i++ )
357  for( long int j=0; j<icol; j++ )
358  for( long int k=0; k<isiz; k++)
359  b.elemr(i,j) += elemc(i,k)*m.elemc(k,j);
360 
361  return b;
362 }
363 
364 //______________________________________________________________________________
366 {
367  if( size() != v.size() ) {
368  throw std::range_error( "AlSpaMat::operator*: size do not match! " );
369  }
370 
371  long int isiz(size());
372  AlVec b(isiz);
373 
374  for( long int i=0; i<isiz; i++ )
375  for( long int j=0; j<isiz; j++ )
376  b[i] += elemc(i,j)*v[j];
377 
378  return b;
379 }
380 
381 //______________________________________________________________________________
383 {
385  for (pos = m_ptr_map.begin(); pos!=m_ptr_map.end(); pos++)
386  pos->second *= d;
387 
388  return *this;
389 }
390 
391 //______________________________________________________________________________
392 AlSpaMat AlSpaMat::operator*(const double& d) const
393 {
394  AlSpaMat a(size());
396  for (pos = m_ptr_map.begin(); pos!=m_ptr_map.end(); pos++)
397  a.m_ptr_map.insert(std::make_pair(pos->first, (pos->second)*d));
398 
399  return a;
400 }
401 
402 //______________________________________________________________________________
404 {
405  throw std::invalid_argument( "AlSpaMat::determinant: not implemented!" );
406 }
407 
409 
410  if(RHS.size() != size() ){
411  throw std::range_error( "AlSpaMat::SolveWithEigen vector size is incorrect" );
412  }
413 
414  Eigen::VectorXd eigenBigVector( RHS.size() );
415  for(int i(0); i< RHS.size(); ++i ){
416  eigenBigVector[i] = RHS[i];
417  }
418 
419  Eigen::SparseMatrix<double> eigenBigMatrix( m_size, m_size );
420 
421  using Triplet = Eigen::Triplet<double>;
422  std::vector<Triplet> tripletList;
423  tripletList.reserve(m_nele);
424  long int i, j;
426  for (pos = m_ptr_map.begin(); pos!=m_ptr_map.end(); pos++){
427  elem(pos->first, i, j);
428  tripletList.emplace_back(i,j,pos->second);
429  if(i!=j) tripletList.emplace_back(j,i,pos->second);
430  }
431  eigenBigMatrix.setFromTriplets(tripletList.begin(), tripletList.end());
432 
433  // Eigen::CholmodSupernodalLLT is much much quicker (x50) so it would be great to move to that in the future
434  // requires an external package SuiteSparse
435  // BiCGSTAB was the fastest iterative solver in Eigen from a quick test
436  // SimplicialLDLT was the fastest direct solver in Eigen (x2 slower than BiCGSTAB )
437 
438  // Eigen::BiCGSTAB<Eigen::SparseMatrix<double> > solver;
439  Eigen::SimplicialLDLT<Eigen::SparseMatrix<double> > solver;
440 
441  solver.compute(eigenBigMatrix);
442  if(solver.info()!=Eigen::Success) {
443  // decomposition failed
444  throw std::domain_error("AlSpaMat::SolveWithEigen: failed to compute: -- is the input matrix singular?" );
445  return 1;
446  }
447 
448  Eigen::VectorXd x = solver.solve( eigenBigVector );
449  if(solver.info()!=Eigen::Success) {
450  // solving failed
451  throw std::domain_error("AlSpaMat::SolveWithEigen: Failed to solve: -- is your matrix singular? ");
452  return 2;
453  }
454 
455  //Copy results into vector
456  for(int i(0); i< RHS.size(); ++i ){
457  RHS[i] = x[i];
458  }
459 
460  //Check accuracy
461  Eigen::VectorXd residual = eigenBigMatrix * x - eigenBigVector;
462  double sumresidual = 0;
463  for( int i=0; i<residual.size(); ++i){
464  sumresidual += fabs(residual[i]);
465  }
466  sumresidual /= (double) residual.size();
467 
468  if( sumresidual > 1e-3 ){
469  throw std::overflow_error( "AlSpaMat::SolveWithEigen: your solution is no good! ");
470  return 3;
471  }
472 
473  return 0;
474 
475 
476 }
477 
478 
479 
480 //______________________________________________________________________________
481 //jlove int AlSpaMat::diagonalize(char jobz, AlVec& w, AlMat& z) {
483 {
484  throw std::invalid_argument( "AlSpaMat::diagonalize: not implemented!" );
485 }
486 
487 //______________________________________________________________________________
489 {
490  throw std::invalid_argument( "AlSpaMat::invert: not implemented!" );
491 }
492 
493 //______________________________________________________________________________
494 void AlSpaMat::RemoveDoF(int index, int nelem)
495 {
496  // index here is the first alignment parameter to remove, nelem number of consecutive ones
497 
498  m_size-=nelem;
499  long int n=index+nelem-1;
501  mapiterator pos_obs=m_ptr_map.end();
502  for (pos = m_ptr_map.begin(); pos!=m_ptr_map.end(); pos++) {
503 
504  if( pos_obs!=m_ptr_map.end() )
505  m_ptr_map.erase(pos_obs);
506 
507  pos_obs = m_ptr_map.end();
508 
509  long int k, l;
510  elem(pos->first, k, l);
511 
512  if( (k>=index && k<=n) || (l>=index && l<=n) )
513  pos_obs = pos;
514  else {
515  if( k > n )
516  k -= nelem;
517  if( l > n )
518  l -= nelem;
519  if( k >= index || l >= index ) {
520  elemr(k, l) = pos->second;
521  pos_obs = pos;
522  }
523  }
524  }
525 
526  if( pos_obs!=m_ptr_map.end() )
527  m_ptr_map.erase(pos_obs);
528  m_nele = m_ptr_map.size();
529 }
530 
531 //______________________________________________________________________________
532 int AlSpaMat::RemoveCollsRows(std::vector<int> indices)
533 {
534  int n = indices.size();
535  if (n==0) {
536  return m_size;
537  }
538  if (n>m_size) {
539  throw std::invalid_argument( "AlSpaMat::RemoveCollsRows: Vector of indices larger than matrix size." );
540  return m_size;
541  }
542 
543  // first sort the list of indices descending
544  // maybe not the fastest way to do that but it works
545  for (int i=0;i<n-1;i++)
546  for (int j=i+1; j<n; j++)
547  if (indices[j] > indices[i]) {
548  int itmp = indices[i];
549  indices[i] = indices[j];
550  indices[j] = itmp;
551  }
552 
553  // remove rows and columns starting from largest indices
554  for (int i=0;i<n;i++) {
555  if (indices[i] > m_size-1) {
556  throw std::out_of_range( "AlSpaMat::RemoveCollsRows: Index goes beyond matrix." );
557  }
558  RemoveDoF(indices[i]);
559  }
560 
561  return m_size;
562 }
563 
564 //______________________________________________________________________________
565 void AlSpaMat::RemoveAlignPar(int index, int control)
566 {
567  // Dynamic shiftRow
568  int shiftRow = 1;
569  int counterRow = 0;
570 
571  // Dynamic shiftCol
572  int shiftCol;
573  int counterCol = 0;
574 
575  index = index-control;
576 
578 
579  for(int row=index; row<(size()-shiftRow); row++) {
580  shiftCol = 0;
581  counterCol = 0;
582 
583  for(int col=0; col<row+1; col++) {
584 
585  if (col==index) {
586  shiftCol = 1;
587  counterCol=0;
588  }
589 
590  pos = m_ptr_map.find(std::make_pair(row+shiftRow,col+shiftCol));
591  if( pos!=m_ptr_map.end() ) { // exists
592  elemr(row,col) = pos->second;
593  m_ptr_map.erase(pos);
594  }
595  else {
596  pos = m_ptr_map.find(std::make_pair(row,col));
597  if( pos!=m_ptr_map.end() )
598  m_ptr_map.erase(pos);
599  }
600  counterCol++;
601  if (counterCol==5-control) {
602  counterCol=0;
603  shiftCol++;
604  }
605  }
606 
607  counterRow++;
608  if (counterRow==5-control) {
609  counterRow=0;
610  shiftRow++;
611  }
612  }
613 
614  m_nele = m_ptr_map.size();
615 }
616 
617 //______________________________________________________________________________
619 {
620  // index here is module number within matrix (size=6*max_index)
621  const int shift=6;
622  const int ind=shift*index;
623 
624  RemoveDoF(ind, shift);
625 }
626 
627 //______________________________________________________________________________
628 void AlSpaMat::reSize(long int n)
629 {
630  // balanced binary tree!
631  if( n!=m_size ) {
632  // make a temporary copy:
633  AlSpaMat m(*this);
634  m_ptr_map.clear();
635  m_size = n;
636  long int i, j;
638  for (pos = m.m_ptr_map.begin(); pos!=m.m_ptr_map.end(); pos++) {
639  m.elem(pos->first, i, j);
640  if( i<n && j<n )
641  m_ptr_map.insert(*pos);
642  }
643  }
644 
645  m_nele = m_ptr_map.size();
646 }
647 
648 //______________________________________________________________________________
649 void AlSpaMat::SetPathBin(const std::string &path)
650 {
651  m_pathbin.assign(path);
652 }
653 
654 //______________________________________________________________________________
655 void AlSpaMat::SetPathTxt(const std::string &path)
656 {
657  m_pathtxt.assign(path);
658 }
659 
660 //______________________________________________________________________________
661 //jlove StatusCode AlSpaMat::Write(const std::string &filename, bool binary,
662 // bool square, double scale, float version){
663 StatusCode AlSpaMat::Write(const std::string &filename, bool binary,
664  bool /*square*/, double, float version)
665 {
666  std::ofstream outmat;
667 
668  int32_t msizz = 1000000+size();
669  int32_t nelem = m_ptr_map.size();
670 
671  if(binary) {
672  outmat.open((m_pathbin+filename).c_str(), std::ios::binary);
673  if(outmat.fail())
674  return StatusCode::FAILURE;
675  // add 10^6 to the size to distinguish
676  // from dense format
677  outmat.write((char*)&msizz, sizeof (msizz));
678  outmat.write((char*)&version, sizeof (version));
679  outmat.write((char*)&nelem, sizeof (nelem));
680  }
681  else {
682  outmat.open((m_pathtxt+filename).c_str());
683  if(outmat.fail())
684  return StatusCode::FAILURE;
685  outmat.setf(std::ios::fixed);
686  outmat.setf(std::ios::showpoint);
687  outmat.precision(3);
688  outmat << "msizz: " << std::setw(6) << msizz << std::endl;
689  outmat << "nelem: " << std::setw(6) << nelem << std::endl;
690  outmat << "AlSpaMat version: " << std::setw(6) << version << std::endl;
691  }
692 
693  double melem=0;
694  long int ii, jj;
695  int32_t i, j;
696 
698  for (pos = m_ptr_map.begin(); pos!=m_ptr_map.end(); pos++) {
699  melem = pos->second;
700  elem(pos->first, ii, jj); i=ii; j=jj; // just a type conversion
701  if(binary) {
702  outmat.write((char*)&(i), sizeof (i));
703  outmat.write((char*)&(j), sizeof (j));
704  outmat.write((char*)&(melem), sizeof (melem));
705  }
706  else
707  outmat << std::setw(6) << i << std::setw(6) << j << std::setw(18) << melem << std::endl;
708  }
709  outmat.close();
710 
711  return StatusCode::SUCCESS;
712 }
713 
714 //______________________________________________________________________________
715 StatusCode AlSpaMat::CheckMatVersion(const std::string& filename, bool &StdUnits)
716 {
717  std::ifstream inmat((filename).c_str(), std::ios::binary);
718  if(inmat.fail())
719  return StatusCode::FAILURE;
720 
721  m_ptr_map.clear();
722 
723  int32_t msiz=0;
724  inmat.read((char*)&msiz, sizeof (msiz));
725 
726  float version=0.0;
727  inmat.read((char*)&version, sizeof (version));
728 
729  StdUnits = version>=2.0;
730 
731  inmat.close();
732 
733  return StatusCode::SUCCESS;
734 }
735 
736 //______________________________________________________________________________
737 StatusCode AlSpaMat::Read(const std::string &filename, int &dofs, bool &triang, float &version)
738 {
739  bool stdUnits = true;
740  if (StatusCode::SUCCESS != CheckMatVersion(m_pathbin+filename, stdUnits))
741  return StatusCode::FAILURE;
742 
743  std::ifstream inmat((m_pathbin+filename).c_str(), std::ios::binary);
744  if(inmat.fail())
745  return StatusCode::FAILURE;
746 
747  m_ptr_map.clear();
748 
749  int32_t msiz=0;
750  int32_t nelem;
751  inmat.read((char*)&msiz, sizeof (msiz));
752  if( msiz>999999 )
753  dofs = msiz-1000000;
754  else
755  dofs = abs(msiz);
756  m_size = dofs;
757 
758  if (stdUnits)
759  inmat.read((char*)&version, sizeof (version));
760 
761  double melem=0;
762  int32_t i, j;
763 
764  if(msiz>999999) { // sparse format
765  triang=false;
766  inmat.read((char*)&nelem, sizeof (nelem));
767  m_nele=nelem;
768  for(int k=0; k<nelem; k++) {
769  inmat.read((char*)&i, sizeof (i));
770  inmat.read((char*)&j, sizeof (j));
771  inmat.read((char*)&melem, sizeof (melem));
772  m_ptr_map.insert(std::make_pair(std::make_pair(i,j), melem));
773  }
774  }
775  else if(msiz>0) { // square format
776  triang=false;
777  for(int32_t i=0; i<msiz; i++) {
778  for(int32_t j=0; j<msiz; j++) {
779  inmat.read((char*)&melem, sizeof (melem));
780  if( i>=j && melem!=0. )
781  m_ptr_map.insert(std::make_pair(std::make_pair(i,j), melem));
782  }
783  }
784  }
785  else { // triangular format
786  triang=true;
787  msiz = (-1)*msiz;
788  for( int32_t i=0; i<msiz; i++) {
789  for( int32_t j=0; j<=i; j++) {
790  inmat.read((char*)&melem, sizeof (melem));
791  if( melem!=0. )
792  m_ptr_map.insert(std::make_pair(std::make_pair(i,j), melem));
793  }
794  }
795  }
796 
797  m_nele = m_ptr_map.size();
798  inmat.close();
799  return StatusCode::SUCCESS;
800 }
801 
802 //______________________________________________________________________________
803 StatusCode AlSpaMat::ReadProjected(const std::string &filename, int &dofs,
804  bool &triang, float &version)
805 {
806  std::ifstream inmat((m_pathbin+filename).c_str(), std::ios::binary);
807  if(inmat.fail())
808  return StatusCode::FAILURE;
809 
810  m_ptr_map.clear();
811 
812  int32_t msiz=0;
813  int32_t nelem;
814  inmat.read((char*)&msiz, sizeof (msiz));
815  if( msiz>999999 )
816  dofs = msiz-1000000;
817  else
818  dofs = abs(msiz);
819  m_size = dofs;
820 
821  inmat.read((char*)&version, sizeof (version));
822 
823  double melem=0;
824  int32_t i, j;
825 
826  if(msiz>999999) { // sparse format
827  triang=false;
828  inmat.read((char*)&nelem, sizeof (nelem));
829  m_nele=nelem;
830  for(int k=0; k<nelem; k++) {
831  inmat.read((char*)&i, sizeof (i));
832  inmat.read((char*)&j, sizeof (j));
833  inmat.read((char*)&melem, sizeof (melem));
834  m_ptr_map.insert(std::make_pair(std::make_pair(i,j), melem));
835  }
836  }
837  else if(msiz>0) { // square format
838  triang=false;
839  for(int32_t i=0; i<msiz; i++) {
840  for(int32_t j=0; j<msiz; j++) {
841  inmat.read((char*)&melem, sizeof (melem));
842  if( i>=j && melem!=0. )
843  m_ptr_map.insert(std::make_pair(std::make_pair(i,j), melem));
844  }
845  }
846  }
847  else { // triangular format
848  triang=true;
849  msiz = (-1)*msiz;
850  for( int32_t i=0; i<msiz; i++) {
851  for( int32_t j=0; j<=i; j++) {
852  inmat.read((char*)&melem, sizeof (melem));
853  if( melem!=0. )
854  m_ptr_map.insert(std::make_pair(std::make_pair(i,j), melem));
855  }
856  }
857  }
858 
859  m_nele = m_ptr_map.size();
860  inmat.close();
861  return StatusCode::SUCCESS;
862 }
863 
865 {
866 
867  long int nonZeroElements = m_ptr_map.size();
868  int *irow = new int[nonZeroElements];
869  int *icol = new int[nonZeroElements];
870  double *val = new double[nonZeroElements];
871 
872  long int i, j;
873  long int counter(0);
874  const_mapiterator pos = m_ptr_map.begin();
875  for(pos=m_ptr_map.begin(); pos!=m_ptr_map.end(); pos++){
876  i = pos->first.first;
877  j = pos->first.second;
878  *(val+counter)=pos->second;
879  *(irow+counter)= i;
880  *(icol+counter)= j;
881  counter++;
882  }
883 
884  TMatrixDSparse* myTMatrix = new TMatrixDSparse(0,m_size-1,0,m_size-1);
885  myTMatrix->SetMatrixArray(nonZeroElements,irow,icol,val);
886 
887  delete [] irow;
888  delete [] icol;
889  delete [] val;
890  return myTMatrix;
891 }
892 
893 
894 
895 } // end namespace Trk
AllowedVariables::e
e
Definition: AsgElectronSelectorTool.cxx:37
query_example.row
row
Definition: query_example.py:24
Trk::AlSpaMat::m_ptr_row
int * m_ptr_row
Definition: AlSpaMat.h:88
Trk::const_mapiterator
datamap::const_iterator const_mapiterator
Definition: AlSymMatBase.h:30
Trk::AlSpaMat::SetPathBin
virtual void SetPathBin(const std::string &) override final
Definition: AlSpaMat.cxx:649
Trk::AlSpaMat::ReadProjected
virtual StatusCode ReadProjected(const std::string &, int &, bool &, float &) override final
Definition: AlSpaMat.cxx:803
python.SystemOfUnits.m
int m
Definition: SystemOfUnits.py:91
athena.path
path
python interpreter configuration --------------------------------------—
Definition: athena.py:128
Trk::AlSpaMat::RemoveCollsRows
virtual int RemoveCollsRows(std::vector< int >) override final
Definition: AlSpaMat.cxx:532
Trk::AlSpaMat::Write
virtual StatusCode Write(const std::string &, bool, bool, double, float) override final
Definition: AlSpaMat.cxx:663
Trk::AlVec
Definition: AlVec.h:23
ClusterSeg::residual
@ residual
Definition: ClusterNtuple.h:20
AlSpaMat.h
index
Definition: index.py:1
Trk::AlSymMatBase
Definition: AlSymMatBase.h:38
hist_file_dump.d
d
Definition: hist_file_dump.py:137
Trk::AlSpaMat::elemr
virtual double & elemr(long int, long int) override final
Definition: AlSpaMat.cxx:136
Trk::indices
std::pair< long int, long int > indices
Definition: AlSymMatBase.h:24
Trk::AlSpaMat::copy
void copy(const AlSpaMat &m)
Definition: AlSpaMat.cxx:85
Trk::AlSymMatBase::m_ptr_map
datamap m_ptr_map
Definition: AlSymMatBase.h:101
Trk::AlSpaMat::operator*
AlMat operator*(const AlSymMatBase &) const
Definition: AlSpaMat.cxx:329
Trk::AlSpaMat::SolveWithEigen
int SolveWithEigen(AlVec &RHS)
Definition: AlSpaMat.cxx:408
AlVec.h
Trk::AlSpaMat::elemc
virtual double elemc(long int, long int) const override final
Definition: AlSpaMat.cxx:172
UploadAMITag.l
list l
Definition: UploadAMITag.larcaf.py:158
Trk::AlSpaMat::determinant
virtual double determinant() override final
Definition: AlSpaMat.cxx:403
JetTiledMap::N
@ N
Definition: TiledEtaPhiMap.h:44
Trk::AlSpaMat::m_pathbin
std::string m_pathbin
Definition: AlSpaMat.h:85
AlSymMat.h
Trk::AlSpaMat::CheckMatVersion
virtual StatusCode CheckMatVersion(const std::string &, bool &) override final
Definition: AlSpaMat.cxx:715
Trk::AlSpaMat::operator=
AlSpaMat & operator=(const double &)
Definition: AlSpaMat.cxx:257
atlasStyleMacro.icol
int icol
Definition: atlasStyleMacro.py:13
Trk::AlSpaMat::elem
void elem(const indices &, long int &, long int &) const
Definition: AlSpaMat.h:94
Trk::AlSymMat
Definition: AlSymMat.h:26
TMatrixDSparse
class TMatrixTSparse< double > TMatrixDSparse
Definition: AlSpaMat.h:14
Trk::AlSpaMat::RemoveAlignPar
virtual void RemoveAlignPar(int, int) override final
Definition: AlSpaMat.cxx:565
Trk::AlSymMatBase::size
long int size() const
Definition: AlSymMatBase.h:145
lumiFormat.i
int i
Definition: lumiFormat.py:85
Trk::AlVec::size
int size() const
Definition: AlVec.h:109
Trk::AlSpaMat::makeTMatrix
virtual TMatrixDSparse * makeTMatrix() override final
Definition: AlSpaMat.cxx:864
Trk::AlSpaMat::diagonalize
virtual int diagonalize(char jobz, AlVec &w, AlMat &z) override final
Definition: AlSpaMat.cxx:482
beamspotman.n
n
Definition: beamspotman.py:731
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
Trk::AlSpaMat::invert
virtual int invert() override final
Definition: AlSpaMat.cxx:488
AlMat.h
Trk::AlSpaMat::AlSpaMat
AlSpaMat()
Definition: AlSpaMat.cxx:36
Trk::AlMat
Definition: AlMat.h:27
Trk::AlSpaMat::~AlSpaMat
~AlSpaMat()
Definition: AlSpaMat.cxx:77
Trk::AlSpaMat::reSize
virtual void reSize(long int) override final
Definition: AlSpaMat.cxx:628
Trk::AlSymMatBase::m_nele
long int m_nele
Definition: AlSymMatBase.h:104
Trk::AlSpaMat::RemoveDoF
void RemoveDoF(int, int nelem=1)
Definition: AlSpaMat.cxx:494
xAOD::double
double
Definition: CompositeParticle_v1.cxx:159
Trk::AlSpaMat::operator+
AlSpaMat operator+(const AlSpaMat &) const
Definition: AlSpaMat.cxx:267
EventPrimitives.h
Trk
Ensure that the ATLAS eigen extensions are properly loaded.
Definition: FakeTrackBuilder.h:9
plotBeamSpotMon.b
b
Definition: plotBeamSpotMon.py:77
Trk::mapiterator
datamap::iterator mapiterator
Definition: AlSymMatBase.h:29
query_example.col
col
Definition: query_example.py:7
python.LumiBlobConversion.pos
pos
Definition: LumiBlobConversion.py:18
get_generator_info.version
version
Definition: get_generator_info.py:33
Trk::AlSpaMat::operator+=
AlSpaMat & operator+=(const AlSpaMat &)
Definition: AlSpaMat.cxx:283
DeMoScan.index
string index
Definition: DeMoScan.py:364
a
TList * a
Definition: liststreamerinfos.cxx:10
Pythia8_RapidityOrderMPI.val
val
Definition: Pythia8_RapidityOrderMPI.py:14
Trk::AlSpaMat::operator*=
AlSpaMat & operator*=(const double &)
Definition: AlSpaMat.cxx:382
CaloCellTimeCorrFiller.filename
filename
Definition: CaloCellTimeCorrFiller.py:24
Trk::AlSpaMat::SetPathTxt
virtual void SetPathTxt(const std::string &) override final
Definition: AlSpaMat.cxx:655
Trk::AlSpaMat::m_ptr_col
int * m_ptr_col
Definition: AlSpaMat.h:89
Trk::AlSymMatBase::m_matrix_type
int m_matrix_type
Definition: AlSymMatBase.h:100
Trk::x
@ x
Definition: ParamDefs.h:55
test_pyathena.counter
counter
Definition: test_pyathena.py:15
Trk::AlSpaMat::m_pathtxt
std::string m_pathtxt
Definition: AlSpaMat.h:86
Trk::AlSymMatBase::m_size
long int m_size
Definition: AlSymMatBase.h:103
Trk::AlSpaMat::operator-=
AlSpaMat & operator-=(const AlSpaMat &)
Definition: AlSpaMat.cxx:314
Trk::AlSpaMat
Definition: AlSpaMat.h:27
checkFileSG.ind
list ind
Definition: checkFileSG.py:118
Trk::v
@ v
Definition: ParamDefs.h:78
Trk::AlSpaMat::RemoveModule
virtual void RemoveModule(int) override final
Definition: AlSpaMat.cxx:618
fitman.k
k
Definition: fitman.py:528
Trk::AlSpaMat::Read
virtual StatusCode Read(const std::string &, int &, bool &, float &) override final
Definition: AlSpaMat.cxx:737
Trk::AlSpaMat::operator-
AlSpaMat operator-(const AlSpaMat &) const
Definition: AlSpaMat.cxx:298
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37