Isis 3 Programmer Reference
SparseBlockMatrix.cpp
1
6/* SPDX-License-Identifier: CC0-1.0 */
7#include "SparseBlockMatrix.h"
8
9// std lib
10#include <iostream>
11#include <iomanip>
12
13// qt lib
14#include <QDataStream>
15#include <QDebug>
16#include <QMapIterator>
17#include <QListIterator>
18
19// boost lib
20#include <boost/numeric/ublas/matrix_sparse.hpp>
21#include <boost/numeric/ublas/matrix_proxy.hpp>
22#include <boost/numeric/ublas/io.hpp>
23
24// Isis lib
25#include "IString.h"
26#include "LinearAlgebra.h"
27
28using namespace boost::numeric::ublas;
29
30namespace Isis {
31
38
39
46
47
53 qDeleteAll(values());
54 clear();
55 }
56
57
66
67
74 // handi-wipe
75 wipe();
76
77 // copy matrix blocks from src
78 QMapIterator<int, LinearAlgebra::Matrix *> it(src);
79 while ( it.hasNext() ) {
80 it.next();
81
82 // copy matrix block from src
83 LinearAlgebra::Matrix *m = new LinearAlgebra::Matrix(*(it.value()));
84
85 // insert matrix into map
86 this->insert(it.key(),m);
87 }
88
89 m_startColumn = src.startColumn();
90 }
91
92
100 if ( this == &src )
101 return *this;
102
103 copy(src);
104
105 return *this;
106 }
107
108
121 bool SparseBlockColumnMatrix::insertMatrixBlock(int nColumnBlock, int nRows, int nCols) {
122 // check if matrix already exists at the key "nColumnBlock"
123 if ( this->contains(nColumnBlock) )
124 return true;
125
126 // allocate matrix block with nRows and nCols
127 LinearAlgebra::Matrix *m = new LinearAlgebra::Matrix(nRows,nCols);
128
129 if ( !m )
130 return false;
131
132 // zero matrix elements
133 m->clear();
134
135 // insert matrix into map
136 this->insert(nColumnBlock,m);
137
138 return true;
139 }
140
141
148 m_startColumn = nStartColumn;
149 }
150
151
160
161
169 int nElements = 0;
170
171 QMapIterator<int, LinearAlgebra::Matrix *> it(*this);
172 while ( it.hasNext() ) {
173 it.next();
174
175 if( !it.value() )
176 continue;
177
178 nElements += it.value()->size1()*it.value()->size2();
179 }
180
181 return nElements;
182 }
183
184
191
192 int nColumns = 0;
193
194 QMapIterator<int, LinearAlgebra::Matrix *> it(*this);
195 while ( it.hasNext() ) {
196 it.next();
197
198 if( !it.value() )
199 continue;
200
201 nColumns = it.value()->size2();
202 break;
203 }
204
205 return nColumns;
206 }
207
208
216
217 // iterate to last block (the diagonal one)
218 QMapIterator<int, LinearAlgebra::Matrix *> it(*this);
219 while ( it.hasNext() ) {
220 it.next();
221
222 if( !it.value() )
223 continue;
224 }
225
226 int nRows = it.value()->size1();
227
228 return nRows;
229 }
230
231
239 void SparseBlockColumnMatrix::print(std::ostream& outstream) {
240 if ( size() == 0 ) {
241 outstream << "Empty SparseBlockColumnMatrix..." << std::endl;
242 return;
243 }
244
245 outstream << "Printing SparseBlockColumnMatrix..." << std::endl;
246 QMapIterator<int, LinearAlgebra::Matrix *> it(*this);
247 while ( it.hasNext() ) {
248 it.next();
249
250 if( it.value() )
251 outstream << it.key() << std::endl << *(it.value()) << std::endl
252 << std::endl;
253 else
254 outstream << "NULL block pointer at row[" << IString(it.key())
255 << "]!" << std::endl;
256 }
257 }
258
259
266 void SparseBlockColumnMatrix::printClean(std::ostream& outstream) {
267 if ( size() == 0 ) {
268 outstream << "Empty SparseBlockColumnMatrix..." << std::endl;
269 return;
270 }
271
272 QMapIterator<int, LinearAlgebra::Matrix *> it(*this);
273 while ( it.hasNext() ) {
274 it.next();
275
276 LinearAlgebra::Matrix * m = it.value();
277
278 int rows = m->size1();
279 int cols = m->size2();
280
281 for ( int i = 0; i < rows; i++ ) {
282 for ( int j = 0; j < cols; j++ ) {
283 double d = m->at_element(i,j);
284 if ( j == cols-1 )
285 outstream << std::setprecision(12) << d << std::endl;
286 else
287 outstream << std::setprecision(12) << d << ",";
288 }
289 }
290
291 }
292 outstream << std::endl;
293 }
294
295
300 QMapIterator<int, LinearAlgebra::Matrix *> it(*this);
301 while ( it.hasNext() ) {
302 it.next();
303 it.value()->clear();
304 }
305 }
306
307
314 QDataStream &operator<<(QDataStream &stream, const SparseBlockColumnMatrix &sbcm) {
315 // write number of blocks in this column
316 int nBlocks = sbcm.size();
317 stream << (qint32)nBlocks;
318
319 QMapIterator<int, LinearAlgebra::Matrix *> it(sbcm);
320 while ( it.hasNext() ) {
321 it.next();
322
323 if( !it.value() )
324 continue;
325
326 int nRows = it.value()->size1();
327 int nCols = it.value()->size2();
328
329 // write block number (key); rows (size1); and columns (size2)
330 stream << it.key() << (qint32)nRows << (qint32)nCols;
331
332 double* data = &it.value()->data()[0];
333
334 // write raw matrix data
335 stream.writeRawData((const char*)data, nRows*nCols*sizeof(double));
336 }
337
338 return stream;
339 }
340
341
348 QDataStream &operator>>(QDataStream &stream, SparseBlockColumnMatrix &sbcm) {
349 qint32 nBlocks, nBlockNumber, nRows, nCols;
350 int i, r, c;
351
352 stream >> nBlocks;
353
354 for ( i = 0; i < nBlocks; i++ ) {
355 // read block number (key); rows (size1); and columns (size2)
356 stream >> nBlockNumber >> nRows >> nCols;
357
358 double data[nRows*nCols];
359
360 // read raw matrix data
361 stream.readRawData((char*)data, nRows*nCols*sizeof(double));
362
363 // insert matrix at correct key
364 sbcm.insertMatrixBlock(nBlockNumber, nRows, nCols);
365
366 // get matrix
367 LinearAlgebra::Matrix *matrix = sbcm[nBlockNumber];
368
369 // fill with data
370 for ( r = 0; r < nRows; r++ ) {
371 for ( c = 0; c < nCols; c++ ) {
372 int nLocation = r*nRows + c;
373 (*matrix)(r,c) = data[nLocation];
374 }
375 }
376 }
377
378 return stream;
379 }
380
381
388 QDebug operator<<(QDebug dbg, const SparseBlockColumnMatrix &sbcm) {
389 dbg.space() << "New Block" << endl;
390
391 QMapIterator<int, LinearAlgebra::Matrix *> it(sbcm);
392 while ( it.hasNext() ) {
393 it.next();
394
395 if( !it.value() )
396 continue;
397
398 // get matrix
399 LinearAlgebra::Matrix *matrix = it.value();
400
401 // matrix rows, columns
402 int nRows = matrix->size1();
403 int nCols = matrix->size2();
404
405 dbg.nospace() << qSetFieldWidth(4);
406 dbg.nospace() << qSetRealNumberPrecision(8);
407
408 for ( int r = 0; r < nRows; r++ ) {
409 for ( int c = 0; c < nCols; c++ ) {
410 dbg.space() << (*matrix)(r,c);
411 }
412 dbg.space() << endl;
413 }
414
415 dbg.space() << endl;
416 }
417
418 return dbg;
419 }
420
421
423 // SparseBlockRowMatrix methods
424
431
432
438 qDeleteAll(values());
439 clear();
440 }
441
442
448 SparseBlockRowMatrix::SparseBlockRowMatrix(const SparseBlockRowMatrix& src) {
449 copy(src);
450 }
451
452
459 // handi-wipe
460 wipe();
461
462 // copy matrix blocks from src
463 QMapIterator<int, LinearAlgebra::Matrix *> it(src);
464 while ( it.hasNext() ) {
465 it.next();
466
467 // copy matrix block from src
468 LinearAlgebra::Matrix *m = new LinearAlgebra::Matrix(*(it.value()));
469
470 // insert matrix into map
471 this->insert(it.key(),m);
472 }
473 }
474
475
483 if ( this == &src )
484 return *this;
485
486 copy(src);
487
488 return *this;
489 }
490
491
507 bool SparseBlockRowMatrix::insertMatrixBlock(int nRowBlock, int nRows, int nCols) {
508 if ( this->contains(nRowBlock) )
509 return false;
510
511 LinearAlgebra::Matrix *m = new LinearAlgebra::Matrix(nRows,nCols);
512
513 if ( !m )
514 return false;
515
516 m->clear();
517
518 this->insert(nRowBlock,m);
519
520 return true;
521 }
522
523
531 int nElements = 0;
532
533 QMapIterator<int, LinearAlgebra::Matrix *> it(*this);
534 while ( it.hasNext() ) {
535 it.next();
536
537 if( !it.value() )
538 continue;
539
540 nElements += it.value()->size1()*it.value()->size2();
541 }
542
543 return nElements;
544 }
545
546
552 void SparseBlockRowMatrix::print(std::ostream& outstream) {
553 if ( size() == 0 ) {
554 outstream << "Empty SparseBlockRowMatrix..." << std::endl;
555 return;
556 }
557
558 outstream << "Printing SparseBlockRowMatrix..." << std::endl;
559 QMapIterator<int, LinearAlgebra::Matrix *> it(*this);
560 while ( it.hasNext() ) {
561 it.next();
562
563 if( it.value() )
564 outstream << it.key() << std::endl << *(it.value()) << std::endl
565 << std::endl;
566 else
567 outstream << "NULL block pointer at column[" << IString(it.key())
568 << "]!" << std::endl;
569 }
570 }
571
572
578 void SparseBlockRowMatrix::printClean(std::ostream& outstream) {
579 if ( size() == 0 ) {
580 outstream << "Empty SparseBlockRowMatrix..." << std::endl;
581 return;
582 }
583
584 QMapIterator<int, LinearAlgebra::Matrix *> it(*this);
585 while ( it.hasNext() ) {
586 it.next();
587
588 LinearAlgebra::Matrix *m = it.value();
589
590 int rows = m->size1();
591 int cols = m->size2();
592
593 for ( int i = 0; i < rows; i++ ) {
594 for ( int j = 0; j < cols; j++ ) {
595 double d = m->at_element(i,j);
596 if ( j == cols-1 )
597 outstream << std::setprecision(9) << d << std::endl;
598 else
599 outstream << std::setprecision(9) << d << ",";
600 }
601 }
602
603 }
604 outstream << std::endl;
605 }
606
607
612 QMapIterator<int, LinearAlgebra::Matrix *> it(*this);
613 while ( it.hasNext() ) {
614 it.next();
615 it.value()->clear();
616 }
617 }
618
619
626 void SparseBlockRowMatrix::copyToBoost(compressed_matrix<double>& B) {
627 B.clear();
628
629 int ncols, nstart, nend, nrowBlock;
630 range rRow = range(0,3);
631 range rCol;
632
633 QMapIterator<int, LinearAlgebra::Matrix *> it(*this);
634 while ( it.hasNext() ) {
635 it.next();
636
637 nrowBlock = it.key();
638 LinearAlgebra::Matrix *m = it.value();
639
640 ncols = m->size2();
641
642 nstart = nrowBlock*ncols;
643 nend = nstart + ncols;
644
645 rCol = range(nstart,nend);
646
647 matrix_range<compressed_matrix<double> > m1 (B, rRow, rCol);
648
649 m1 = *m;
650 }
651 }
652
653
662
663 if ( nblockColumn == 0 )
664 return 0;
665
666 int nLeadingColumnsElements = 0;
667
668 int nCol = 0;
669
670 while ( nCol < nblockColumn ) {
671 if ( !(*this)[nCol] ) {
672 nCol++;
673 continue;
674 }
675
676 int ncolumns = (*this)[nCol]->size2();
677
678 if ( ncolumns == -1 )
679 continue;
680
681 nLeadingColumnsElements += ncolumns;
682
683 nCol++;
684 }
685
686 return nLeadingColumnsElements;
687 }
688
689
696 QDataStream &operator<<(QDataStream &stream, const SparseBlockRowMatrix &sbrm) {
697 // write number of blocks in this column
698 int nBlocks = sbrm.size();
699 stream << (qint32)nBlocks;
700
701 QMapIterator<int, LinearAlgebra::Matrix *> it(sbrm);
702 while ( it.hasNext() ) {
703 it.next();
704
705 if( !it.value() )
706 continue;
707
708 int nRows = it.value()->size1();
709 int nCols = it.value()->size2();
710
711 // write block number (key); rows (size1); and columns (size2)
712 stream << it.key() << (qint32)nRows << (qint32)nCols;
713
714 double* data = &it.value()->data()[0];
715
716 // write raw matrix data
717 stream.writeRawData((const char*)data, nRows*nCols*sizeof(double));
718 }
719
720 return stream;
721 }
722
723
730 QDataStream &operator>>(QDataStream &stream, SparseBlockRowMatrix &sbrm) {
731 qint32 nBlocks, nBlockNumber, nRows, nCols;
732 int i, r, c;
733
734 stream >> nBlocks;
735
736 for ( i = 0; i < nBlocks; i++ ) {
737 // read block number (key); rows (size1); and columns (size2)
738 stream >> nBlockNumber >> nRows >> nCols;
739
740 double data[nRows*nCols];
741
742 // read raw matrix data
743 stream.readRawData((char*)data, nRows*nCols*sizeof(double));
744
745 // insert matrix at correct key
746 sbrm.insertMatrixBlock(nBlockNumber, nRows, nCols);
747
748 // get matrix
749 LinearAlgebra::Matrix *matrix = sbrm[nBlockNumber];
750
751 // fill with data
752 for ( r = 0; r < nRows; r++ ) {
753 for ( c = 0; c < nCols; c++ ) {
754 int nLocation = r*nRows + c;
755 (*matrix)(r,c) = data[nLocation];
756 }
757 }
758 }
759
760 return stream;
761 }
762
763
770 QDebug operator<<(QDebug dbg, const SparseBlockRowMatrix &sbrm) {
771 dbg.space() << "New Block" << endl;
772
773 QMapIterator<int, LinearAlgebra::Matrix *> it(sbrm);
774 while ( it.hasNext() ) {
775 it.next();
776
777 if( !it.value() )
778 continue;
779
780 // get matrix
781 LinearAlgebra::Matrix *matrix = it.value();
782
783 // matrix rows, columns
784 int nRows = matrix->size1();
785 int nCols = matrix->size2();
786
787 dbg.nospace() << qSetFieldWidth(4);
788 dbg.nospace() << qSetRealNumberPrecision(8);
789
790 for ( int r = 0; r < nRows; r++ ) {
791 for ( int c = 0; c < nCols; c++ ) {
792 dbg.space() << (*matrix)(r,c);
793 }
794 dbg.space() << endl;
795 }
796 dbg.space() << endl;
797 }
798
799 return dbg;
800 }
801
802
804 // SparseBlockMatrix methods
805
812
813
819 qDeleteAll(*this);
820 clear();
821 }
822
823
829 SparseBlockMatrix::SparseBlockMatrix(const SparseBlockMatrix& src) {
830 copy(src);
831 }
832
833
840 // handi-wipe
841 wipe();
842
843 // copy all SparseBlockColumnMatrix objects from src
844 for( int i = 0; i < src.size(); i++ ) {
845 append( new SparseBlockColumnMatrix(*(src.at(i))));
846 }
847 }
848
849
856 if ( this == &src )
857 return *this;
858
859 copy(src);
860
861 return *this;
862 }
863
864
874
875 for( int i = 0; i < n; i++ )
876 append( new SparseBlockColumnMatrix() );
877
878 return true;
879 }
880
881
895 bool SparseBlockMatrix::insertMatrixBlock(int nColumnBlock, int nRowBlock, int nRows, int nCols) {
896 return (*this)[nColumnBlock]->insertMatrixBlock(nRowBlock, nRows, nCols);
897 }
898
899
906 int nBlocks = 0;
907
908 for( int i = 0; i < size(); i++ ) {
909 if ( !(*this)[i] )
910 continue;
911
912 nBlocks += (*this)[i]->size();
913 }
914
915 return nBlocks;
916 }
917
918
925 int ndiagBlocks = 0;
926
927 for( int i = 0; i < size(); i++ ) {
928 SparseBlockColumnMatrix* column = at(i);
929
930 if ( !column )
931 continue;
932
933 QMapIterator<int, LinearAlgebra::Matrix *> it(*column);
934 while ( it.hasNext() ) {
935 it.next();
936
937 if( it.key() == i ) {
938 ndiagBlocks++;
939 break;
940 }
941 }
942 }
943
944 return ndiagBlocks;
945 }
946
947
956
957
964 int nElements = 0;
965
966 for( int i = 0; i < size(); i++ ) {
967 if ( !(*this)[i] )
968 continue;
969
970 nElements += (*this)[i]->numberOfElements();
971 }
972
973 return nElements;
974 }
975
976
987 return (*(*this)[column])[row];
988 }
989
990
995 for ( int i = 0; i < size(); i++ )
996 (*this)[i]->zeroBlocks();
997 }
998
999
1005 void SparseBlockMatrix::print(std::ostream& outstream) {
1006 if ( size() == 0 ) {
1007 outstream << "Empty SparseBlockMatrix..." << std::endl;
1008 return;
1009 }
1010
1011 outstream << "Printing SparseBlockMatrix..." << std::endl;
1012 for( int i = 0; i < size(); i++ ) {
1013 SparseBlockColumnMatrix* column = at(i);
1014
1015 if ( column )
1016 column->print(outstream);
1017 else
1018 outstream << "NULL column pointer at column[" << IString(i)
1019 << "]!" << std::endl;
1020 }
1021 }
1022
1023
1029 void SparseBlockMatrix::printClean(std::ostream& outstream) {
1030 if ( size() == 0 ) {
1031 outstream << "Empty SparseBlockMatrix..." << std::endl;
1032 return;
1033 }
1034
1035 for( int i = 0; i < size(); i++ ) {
1036 SparseBlockColumnMatrix* column = at(i);
1037
1038 if ( column )
1039 column->printClean(outstream);
1040 else
1041 outstream << "NULL column pointer at column[" << IString(i)
1042 << "]!" << std::endl;
1043 }
1044 }
1045
1046
1055
1056 if ( nblockColumn == 0 )
1057 return 0;
1058
1059 int nLeadingColumnsElements = 0;
1060
1061 int nCol = 0;
1062
1063 while ( nCol < nblockColumn ) {
1064 if ( !(*this)[nCol] )
1065 continue;
1066
1067 int ncolumns = (*this)[nCol]->numberOfColumns();
1068
1069 if ( ncolumns == -1 )
1070 continue;
1071
1072 nLeadingColumnsElements += ncolumns;
1073
1074 nCol++;
1075 }
1076
1077 return nLeadingColumnsElements;
1078 }
1079
1080
1089
1090 if ( nblockRow == 0 )
1091 return 0;
1092
1093 int i = 0;
1094 int nLeadingRows = 0;
1095
1096 while ( i < nblockRow ) {
1097 SparseBlockColumnMatrix* column = at(i);
1098
1099 if ( !column )
1100 continue;
1101
1102 QMapIterator<int, LinearAlgebra::Matrix *> it(*column);
1103 // iterate to last element in column
1104 while ( it.hasNext() ) {
1105 it.next();
1106
1107 if( it.key() == i )
1108 nLeadingRows += it.value()->size1();
1109 }
1110 i++;
1111 }
1112
1113 return nLeadingRows;
1114 }
1115
1116
1123 QDataStream &operator<<(QDataStream &stream, const SparseBlockMatrix &sparseBlockMatrix) {
1124 int nBlockColumns = sparseBlockMatrix.size();
1125
1126 stream << (qint32)nBlockColumns;
1127
1128 for ( int i =0; i < nBlockColumns; i++ )
1129 stream << *sparseBlockMatrix.at(i);
1130
1131 return stream;
1132 }
1133
1134
1141 QDataStream &operator>>(QDataStream &stream, SparseBlockMatrix &sparseBlockMatrix) {
1142 qint32 nBlockColumns;
1143
1144 // read and set number of block columns
1145 stream >> nBlockColumns;
1146 sparseBlockMatrix.setNumberOfColumns(nBlockColumns);
1147
1148 for ( int i =0; i < nBlockColumns; i++ )
1149 stream >> *sparseBlockMatrix.at(i);
1150
1151 return stream;
1152 }
1153
1160 QDebug operator<<(QDebug dbg, const SparseBlockMatrix &m) {
1161 int nBlockColumns = m.size();
1162
1163 for ( int i =0; i < nBlockColumns; i++ )
1164 dbg << *m.at(i);
1165
1166 return dbg;
1167 }
1168}
Adds specific functionality to C++ strings.
Definition IString.h:165
boost::numeric::ublas::matrix< double > Matrix
Definition for an Isis::LinearAlgebra::Matrix of doubles.
SparseBlockColumnMatrix.
int numberOfElements()
Returns total number of matrix elements in map (NOTE: NOT the number of matrix blocks).
void wipe()
Deletes all pointer elements and removes them from the map.
void printClean(std::ostream &outstream)
Prints matrix blocks to std output stream out for debugging.
int startColumn() const
Sets starting column for block in full matrix.
void print(std::ostream &outstream)
Prints matrix blocks to std output stream out for debugging.
SparseBlockColumnMatrix & operator=(const SparseBlockColumnMatrix &src)
"Equals" operator.
void zeroBlocks()
Sets all elements of all matrix blocks to zero.
bool insertMatrixBlock(int nColumnBlock, int nRows, int nCols)
Inserts a "newed" LinearAlgebra::Matrix pointer of size (nRows, nCols) into the map with the block co...
int numberOfColumns()
Returns total number of columns in map (NOTE: NOT the number of matrix blocks).
int numberOfRows()
Returns total number of rows in map (this needs to be clarified and maybe rewritten).
int m_startColumn
starting column for this Block Column in full matrix e.g.
SparseBlockColumnMatrix()
Default constructor.
void copy(const SparseBlockColumnMatrix &src)
Copy method.
void setStartColumn(int nStartColumn)
Sets starting column for block in full matrix.
void copy(const SparseBlockMatrix &src)
Copy method.
void zeroBlocks()
Sets all elements of all matrix blocks to zero.
int numberOfBlocks()
Returns total number of blocks in matrix.
int numberOfDiagonalBlocks()
Returns number of diagonal matrix blocks (equivalent to size - there is one per column).
int getLeadingRowsForBlock(int nblockRow)
Sums and returns the number of rows in each matrix block prior to nblockRow.
void wipe()
Deletes all pointer elements and removes them from the list.
bool insertMatrixBlock(int nColumnBlock, int nRowBlock, int nRows, int nCols)
Inserts a "newed" boost LinearAlgebra::Matrix pointer of size (nRows, nCols) into the matrix at nColu...
int numberOfOffDiagonalBlocks()
Returns number of off-diagonal matrix blocks.
void print(std::ostream &outstream)
Prints matrix blocks to std output stream out for debugging.
SparseBlockMatrix & operator=(const SparseBlockMatrix &src)
"Equals" operator.
void printClean(std::ostream &outstream)
Prints matrix blocks to std output stream out for debugging.
LinearAlgebra::Matrix * getBlock(int column, int row)
Returns pointer to boost matrix at position (column, row).
bool setNumberOfColumns(int n)
Initializes number of columns (SparseBlockColumnMatrix).
int getLeadingColumnsForBlock(int nblockColumn)
Sums and returns the number of columns in each matrix block prior to nblockColumn.
int numberOfElements()
Returns number of matrix elements in matrix.
int numberOfElements()
Returns total number of matrix elements in map (NOTE: NOT the number of matrix blocks).
void print(std::ostream &outstream)
Prints matrix blocks to std output stream out for debugging.
void copy(const SparseBlockRowMatrix &src)
Copy method.
void printClean(std::ostream &outstream)
Prints matrix blocks to std output stream out for debugging.
SparseBlockRowMatrix & operator=(const SparseBlockRowMatrix &src)
"Equals" operator.
void copyToBoost(boost::numeric::ublas::compressed_matrix< double > &B)
Copies a SparseBlockRowMatrix to a Boost compressed_matrix.
void zeroBlocks()
Sets all elements of all matrix blocks to zero.
void wipe()
Deletes all pointer elements and removes them from the map.
int getLeadingColumnsForBlock(int nblockColumn)
Sums and returns the number of columns in each matrix block prior to nblockColumn.
bool insertMatrixBlock(int nRowBlock, int nRows, int nCols)
Inserts a "newed" LinearAlgebra::Matrix pointer of size (nRows, nCols) into the map with the block ro...
This is free and unencumbered software released into the public domain.
Definition Apollo.h:16
std::istream & operator>>(std::istream &is, CSVReader &csv)
Input read operator for input stream sources.
QDebug operator<<(QDebug debug, const Hillshade &hillshade)
Print this class out to a QDebug object.