Commit 04cdab014dd2aae997248575fe2c766179af6195

Authored by knodlseder
1 parent 5ffc65b1

disable memcpy/memmove in GSparseMatrix due to 64 Bit crash

Showing 1 changed file with 787 additions and 781 deletions
src/linalg/GSparseMatrix.cpp
... ... @@ -28,6 +28,9 @@
28 28 #include "GSparseSymbolic.hpp"
29 29 #include "GSparseNumeric.hpp"
30 30  
  31 +/* __ Namespaces _________________________________________________________ */
  32 +using namespace std;
  33 +
31 34 /* __ Method name definitions ____________________________________________ */
32 35 #define G_OP_MUL_VEC "GSparseMatrix::operator* (const GVector&) const"
33 36 #define G_OP_ADD "GSparseMatrix::operator+= (const GSparseMatrix&)"
... ... @@ -57,7 +60,8 @@
57 60 #define G_MAX(a,b) (((a) > (b)) ? (a) : (b))
58 61  
59 62 /* __ Coding definitions _________________________________________________ */
60   -#define G_USE_MEMCPY
  63 +//#define G_USE_MEMCPY // Do not use due to problems on 64 Bit systems
  64 +//#define G_USE_MEMMOVE // Do not use due to problems on 64 Bit systems
61 65  
62 66 /* __ Debug definitions __________________________________________________ */
63 67 //#define G_DEBUG_SPARSE_PENDING // Analyse pending values
... ... @@ -87,7 +91,7 @@ GSparseMatrix::GSparseMatrix(int rows, int cols, int elements) : GMatrixBase()
87 91 {
88 92 // Initialise private members for clean destruction
89 93 init_members();
90   -
  94 +
91 95 // Construct sparse matrix
92 96 constructor(rows, cols, elements);
93 97  
... ... @@ -104,7 +108,7 @@ GSparseMatrix::GSparseMatrix(int rows, int cols, int elements) : GMatrixBase()
104 108 * NOTE: The copy constructor does NOT fill a pending element. *
105 109 ***************************************************************************/
106 110 GSparseMatrix::GSparseMatrix(const GSparseMatrix& m) : GMatrixBase(m)
107   -{
  111 +{
108 112 // Initialise private members for clean destruction
109 113 init_members();
110 114  
... ... @@ -123,6 +127,7 @@ GSparseMatrix::GSparseMatrix(const GSparseMatrix& m) : GMatrixBase(m)
123 127 * class members, then call the GSparseMatrix initialisation method and *
124 128 * finally construct the object and fill it with the GMatrix data. *
125 129 ***************************************************************************/
  130 +/*
126 131 GSparseMatrix::GSparseMatrix(const GMatrix& m) : GMatrixBase()
127 132 {
128 133 // Initialise private members for clean destruction
... ... @@ -147,7 +152,7 @@ GSparseMatrix::GSparseMatrix(const GMatrix& m) : GMatrixBase()
147 152 // Return result
148 153 return;
149 154 }
150   -
  155 +*/
151 156  
152 157 /***************************************************************************
153 158 * GSymMatrix -> GSparseMatrix storage class conversion *
... ... @@ -156,6 +161,7 @@ GSparseMatrix::GSparseMatrix(const GMatrix& m) : GMatrixBase()
156 161 * class members, then call the GSparseMatrix initialisation method and *
157 162 * finally construct the object and fill it with the GSymMatrix data. *
158 163 ***************************************************************************/
  164 +/*
159 165 GSparseMatrix::GSparseMatrix(const GSymMatrix& m) : GMatrixBase()
160 166 {
161 167 // Initialise private members for clean destruction
... ... @@ -180,7 +186,7 @@ GSparseMatrix::GSparseMatrix(const GSymMatrix& m) : GMatrixBase()
180 186 // Return result
181 187 return;
182 188 }
183   -
  189 +*/
184 190  
185 191 /***************************************************************************
186 192 * Destructor *
... ... @@ -208,12 +214,12 @@ GSparseMatrix::~GSparseMatrix()
208 214 * ----------------------------------------------------------------------- *
209 215 ***************************************************************************/
210 216 GSparseMatrix& GSparseMatrix::operator= (const GSparseMatrix& m)
211   -{
  217 +{
212 218 // Execute only if object is not identical
213 219 if (this != &m) {
214 220  
215 221 // Copy base class members
216   - this->GMatrixBase::operator=(m);
  222 + this->GMatrixBase::operator=(m);
217 223  
218 224 // Free members
219 225 free_members();
... ... @@ -225,7 +231,7 @@ GSparseMatrix& GSparseMatrix::operator= (const GSparseMatrix& m)
225 231 copy_members(m);
226 232  
227 233 } // endif: object was not identical
228   -
  234 +
229 235 // Return
230 236 return *this;
231 237 }
... ... @@ -251,26 +257,26 @@ GVector GSparseMatrix::operator* (const GVector& v) const
251 257  
252 258 // Perform vector multiplication
253 259 for (int col = 0; col < m_cols; ++col) {
254   - int i_start = m_colstart[col];
255   - int i_stop = m_colstart[col+1];
  260 + int i_start = m_colstart[col];
  261 + int i_stop = m_colstart[col+1];
256 262 double* ptr_data = m_data + i_start;
257   - int* ptr_rowinx = m_rowinx + i_start;
  263 + int* ptr_rowinx = m_rowinx + i_start;
258 264 for (int i = i_start; i < i_stop; ++i)
259   - result(*ptr_rowinx++) += *ptr_data++ * v(col);
  265 + result(*ptr_rowinx++) += *ptr_data++ * v(col);
260 266 }
261   -
  267 +
262 268 // If fill is pending then add-in also this element into the product
263 269 if (m_fill_val != 0.0) {
264 270 result(m_fill_row) += m_fill_val * v(m_fill_col);
265 271 #if defined(G_DEBUG_SPARSE_PENDING)
266 272 cout << G_OP_MUL_VEC << ": pending value " << m_fill_val <<
267   - " for location (" << m_fill_row << "," << m_fill_col <<
268   - ") has been used." << endl;
269   - #endif
  273 + " for location (" << m_fill_row << "," << m_fill_col <<
  274 + ") has been used." << endl;
  275 + #endif
270 276 }
271   -
  277 +
272 278 } // endif: there were elements in matrix
273   -
  279 +
274 280 // Return result
275 281 return result;
276 282 }
... ... @@ -287,24 +293,24 @@ int GSparseMatrix::operator== (const GSparseMatrix &amp;m) const
287 293 {
288 294 // Initalise the result to 'equal matrices'
289 295 int result = 1;
290   -
  296 +
291 297 // Perform comparison (only if matrix dimensions are identical)
292 298 if (m_rows == m.m_rows && m_cols == m.m_cols) {
293   -
  299 +
294 300 // Loop over all matrix elements
295 301 for (int row = 0; row < m_rows; ++row) {
296   - for (int col = 0; col < m_cols; ++col) {
297   - if ((*this)(row,col) != m(row,col)) {
298   - result = 0;
299   - break;
300   - }
301   - }
302   - if (!result)
303   - break;
304   - }
305   - }
  302 + for (int col = 0; col < m_cols; ++col) {
  303 + if ((*this)(row,col) != m(row,col)) {
  304 + result = 0;
  305 + break;
  306 + }
  307 + }
  308 + if (!result)
  309 + break;
  310 + }
  311 + }
306 312 else
307   - result = 0;
  313 + result = 0;
308 314  
309 315 // Return result
310 316 return result;
... ... @@ -325,21 +331,21 @@ int GSparseMatrix::operator!= (const GSparseMatrix &amp;m) const
325 331  
326 332 // Perform comparison (only if matrix dimensions are identical)
327 333 if (m_rows == m.m_rows && m_cols == m.m_cols) {
328   -
  334 +
329 335 // Loop over all matrix elements
330 336 for (int row = 0; row < m_rows; ++row) {
331   - for (int col = 0; col < m_cols; ++col) {
332   - if ((*this)(row,col) != m(row,col)) {
333   - result = 1;
334   - break;
335   - }
336   - }
337   - if (!result)
338   - break;
  337 + for (int col = 0; col < m_cols; ++col) {
  338 + if ((*this)(row,col) != m(row,col)) {
  339 + result = 1;
  340 + break;
  341 + }
  342 + }
  343 + if (!result)
  344 + break;
339 345 }
340   - }
  346 + }
341 347 else
342   - result = 1;
  348 + result = 1;
343 349  
344 350 // Return result
345 351 return result;
... ... @@ -361,8 +367,8 @@ GSparseMatrix&amp; GSparseMatrix::operator+= (const GSparseMatrix&amp; m)
361 367 for (int col = 0; col < m_cols; ++col) {
362 368 GVector v_result = extract_col(col);
363 369 GVector v_operand = m.extract_col(col);
364   - v_result += v_operand;
365   - insert_col(v_result, col);
  370 + v_result += v_operand;
  371 + insert_col(v_result, col);
366 372 }
367 373  
368 374 // Return result
... ... @@ -385,8 +391,8 @@ GSparseMatrix&amp; GSparseMatrix::operator-= (const GSparseMatrix&amp; m)
385 391 for (int col = 0; col < m_cols; ++col) {
386 392 GVector v_result = extract_col(col);
387 393 GVector v_operand = m.extract_col(col);
388   - v_result -= v_operand;
389   - insert_col(v_result, col);
  394 + v_result -= v_operand;
  395 + insert_col(v_result, col);
390 396 }
391 397  
392 398 // Return result
... ... @@ -411,15 +417,15 @@ GSparseMatrix&amp; GSparseMatrix::operator*= (const GSparseMatrix&amp; m)
411 417 // Multiply only if there are elements in both matrices
412 418 if (m_elements > 0 && m.m_elements > 0) {
413 419  
414   - // Loop over all elements of result matrix
  420 + // Loop over all elements of result matrix
415 421 for (int row = 0; row < m_rows; ++row) {
416 422 for (int col = 0; col < m.m_cols; ++col) {
417   - double sum = 0.0;
418   - for (int i = 0; i < m_cols; ++i)
419   - sum += (*this)(row,i) * m(i,col);
420   - result(row,col) = sum;
421   - }
422   - }
  423 + double sum = 0.0;
  424 + for (int i = 0; i < m_cols; ++i)
  425 + sum += (*this)(row,i) * m(i,col);
  426 + result(row,col) = sum;
  427 + }
  428 + }
423 429  
424 430 }
425 431  
... ... @@ -451,13 +457,13 @@ void GSparseMatrix::add_col(const GVector&amp; v, int col)
451 457 cout << "GSparseMatrix::add_col([" << v << "], " << col << "):" << endl;
452 458 cout << " In Data : ";
453 459 for (int i = 0; i < m_elements; ++i)
454   - cout << m_data[i] << " ";
  460 + cout << m_data[i] << " ";
455 461 cout << endl << " In Row .: ";
456 462 for (int i = 0; i < m_elements; ++i)
457   - cout << m_rowinx[i] << " ";
  463 + cout << m_rowinx[i] << " ";
458 464 cout << endl << " In Col .: ";
459 465 for (int i = 0; i < m_cols+1; ++i)
460   - cout << m_colstart[i] << " ";
  466 + cout << m_colstart[i] << " ";
461 467 cout << endl;
462 468 #endif
463 469  
... ... @@ -469,10 +475,10 @@ void GSparseMatrix::add_col(const GVector&amp; v, int col)
469 475 // double checking we don't do anything before this call ...
470 476 if (m_stack_data != NULL) {
471 477 non_zero = stack_push_column(v, col);
472   - if (non_zero == 0)
473   - return;
  478 + if (non_zero == 0)
  479 + return;
474 480 }
475   -
  481 +
476 482 // ... otherwise check first the arguments and determine the number of
477 483 // non-zero elements in vector
478 484 else {
... ... @@ -488,7 +494,7 @@ void GSparseMatrix::add_col(const GVector&amp; v, int col)
488 494 throw GException::matrix_vector_mismatch(G_ADD_COL, v.m_num, m_rows, m_cols);
489 495  
490 496 // Determine number of non-zero elements in vector
491   - non_zero = v.non_zeros();
  497 + non_zero = v.non_zeros();
492 498 }
493 499  
494 500 // Extract vector for column, add elements, and re-insert vector (only if
... ... @@ -506,7 +512,7 @@ void GSparseMatrix::add_col(const GVector&amp; v, int col)
506 512 if (m_fill_val != 0.0 && m_fill_col == col)
507 513 column.m_data[m_fill_row] += m_fill_val;
508 514  
509   - // Insert vector into matrix
  515 + // Insert vector into matrix
510 516 insert_col(column, col);
511 517  
512 518 }
... ... @@ -515,16 +521,16 @@ void GSparseMatrix::add_col(const GVector&amp; v, int col)
515 521 #if defined(G_DEBUG_SPARSE_ADDITION)
516 522 cout << " Out Data: ";
517 523 for (int i = 0; i < m_elements; ++i)
518   - cout << m_data[i] << " ";
  524 + cout << m_data[i] << " ";
519 525 cout << endl << " Out Row : ";
520 526 for (int i = 0; i < m_elements; ++i)
521   - cout << m_rowinx[i] << " ";
  527 + cout << m_rowinx[i] << " ";
522 528 cout << endl << " Out Col : ";
523 529 for (int i = 0; i < m_cols+1; ++i)
524   - cout << m_colstart[i] << " ";
  530 + cout << m_colstart[i] << " ";
525 531 cout << endl;
526 532 #endif
527   -
  533 +
528 534 // Return
529 535 return;
530 536 }
... ... @@ -545,20 +551,20 @@ void GSparseMatrix::add_col(const double* values, const int* rows,
545 551 cout << "GSparseMatrix::add_col(v, i, n, " << col << "):" << endl;
546 552 cout << " Matrix Data : ";
547 553 for (int i = 0; i < m_elements; ++i)
548   - cout << m_data[i] << " ";
  554 + cout << m_data[i] << " ";
549 555 cout << endl << " Matrix Row .: ";
550 556 for (int i = 0; i < m_elements; ++i)
551   - cout << m_rowinx[i] << " ";
  557 + cout << m_rowinx[i] << " ";
552 558 cout << endl << " Matrix Col .: ";
553 559 for (int i = 0; i < m_cols+1; ++i)
554   - cout << m_colstart[i] << " ";
  560 + cout << m_colstart[i] << " ";
555 561 cout << endl;
556 562 cout << " Array Data .: ";
557 563 for (int i = 0; i < number; ++i)
558   - cout << values[i] << " ";
  564 + cout << values[i] << " ";
559 565 cout << endl << " Array Row ..: ";
560 566 for (int i = 0; i < number; ++i)
561   - cout << rows[i] << " ";
  567 + cout << rows[i] << " ";
562 568 cout << endl;
563 569 #endif
564 570  
... ... @@ -567,10 +573,10 @@ void GSparseMatrix::add_col(const double* values, const int* rows,
567 573 // double checking we don't do anything before this call ...
568 574 if (m_stack_data != NULL) {
569 575 number = stack_push_column(values, rows, number, col);
570   - if (number == 0)
571   - return;
  576 + if (number == 0)
  577 + return;
572 578 }
573   -
  579 +
574 580 // ... otherwise check the arguments
575 581 else {
576 582 // If the array is empty there is nothing to do
... ... @@ -596,29 +602,29 @@ void GSparseMatrix::add_col(const double* values, const int* rows,
596 602 // Case A: the column exists in the matrix, so mix new elements with existing
597 603 // data
598 604 if (i_start < i_stop) {
599   -
  605 +
600 606 // Allocate workspace to hold combined column
601 607 int wrk_size = number + i_stop - i_start;
602   - double* wrk_double = new double[wrk_size];
  608 + double* wrk_double = new double[wrk_size];
603 609 int* wrk_int = new int[wrk_size];
604 610 if (wrk_double == NULL || wrk_int == NULL)
605   - throw GException::mem_alloc(G_ADD_COL2, wrk_size);
  611 + throw GException::mem_alloc(G_ADD_COL2, wrk_size);
606 612  
607 613 // Mix matrix column with specified data
608   - int num_mix;
  614 + int num_mix;
609 615 mix_column(&(m_data[i_start]), &(m_rowinx[i_start]), i_stop-i_start,
610   - values, rows, number,
611   - wrk_double, wrk_int, &num_mix);
  616 + values, rows, number,
  617 + wrk_double, wrk_int, &num_mix);
612 618  
613 619 // Insert mixed column
614 620 insert_col(wrk_double, wrk_int, num_mix, col);
615 621  
616 622 // Free workspace
617   - delete [] wrk_int;
618   - delete [] wrk_double;
619   -
  623 + delete [] wrk_int;
  624 + delete [] wrk_double;
  625 +
620 626 } // endif: Case A
621   -
  627 +
622 628 // Case B: the column does not yet exist in the matrix, so just insert it
623 629 else
624 630 insert_col(values, rows, number, col);
... ... @@ -627,13 +633,13 @@ void GSparseMatrix::add_col(const double* values, const int* rows,
627 633 #if defined(G_DEBUG_SPARSE_ADDITION)
628 634 cout << " Out Data: ";
629 635 for (int i = 0; i < m_elements; ++i)
630   - cout << m_data[i] << " ";
  636 + cout << m_data[i] << " ";
631 637 cout << endl << " Out Row : ";
632 638 for (int i = 0; i < m_elements; ++i)
633   - cout << m_rowinx[i] << " ";
  639 + cout << m_rowinx[i] << " ";
634 640 cout << endl << " Out Col : ";
635 641 for (int i = 0; i < m_cols+1; ++i)
636   - cout << m_colstart[i] << " ";
  642 + cout << m_colstart[i] << " ";
637 643 cout << endl;
638 644 #endif
639 645  
... ... @@ -664,31 +670,31 @@ void GSparseMatrix::cholesky_decompose(int compress)
664 670 // Allocate symbolic analysis object
665 671 GSparseSymbolic* symbolic = new GSparseSymbolic();
666 672 if (symbolic == NULL)
667   - throw GException::mem_alloc(G_CHOL_DECOMP, 1);
  673 + throw GException::mem_alloc(G_CHOL_DECOMP, 1);
668 674  
669 675 // Declare numeric analysis object. We don't allocate one since we'll
670 676 // throw it away at the end of the function (the L matrix will be copied
671 677 // in this object)
672 678 GSparseNumeric numeric;
673   -
  679 +
674 680 // Fill pending element into matrix
675 681 fill_pending();
676 682  
677 683 // Remove rows and columns containing only zeros if matrix compression
678 684 // has been selected
679 685 if (compress)
680   - remove_zero_row_col();
681   -
  686 + remove_zero_row_col();
  687 +
682 688 // Ordering an symbolic analysis of matrix. This sets up an array 'pinv'
683 689 // which contains the fill-in reducing permutations
684 690 symbolic->cholesky_symbolic_analysis(1, *this);
685 691  
686 692 // Store symbolic pointer in sparse matrix object
687 693 m_symbolic = (void*)symbolic;
688   -
  694 +
689 695 // Perform numeric Cholesky decomposition
690 696 numeric.cholesky_numeric_analysis(*this, *symbolic);
691   -
  697 +
692 698 // Copy L matrix into this object
693 699 free_elements(0, m_elements);
694 700 alloc_elements(0, numeric.m_L->m_elements);
... ... @@ -701,7 +707,7 @@ void GSparseMatrix::cholesky_decompose(int compress)
701 707  
702 708 // Insert zero rows and columns if they have been removed previously.
703 709 if (compress)
704   - insert_zero_row_col(matrix_rows, matrix_cols);
  710 + insert_zero_row_col(matrix_rows, matrix_cols);
705 711  
706 712 // Return
707 713 return;
... ... @@ -731,15 +737,15 @@ GVector GSparseMatrix::cholesky_solver(const GVector&amp; v, int compress)
731 737  
732 738 // Raise an exception if the matrix and vector dimensions are incompatible
733 739 if (m_rows != v.m_num)
734   - throw GException::matrix_vector_mismatch(G_CHOL_SOLVE, v.m_num, m_rows, m_cols);
735   -
  740 + throw GException::matrix_vector_mismatch(G_CHOL_SOLVE, v.m_num, m_rows, m_cols);
  741 +
736 742 // Raise an exception if there is no symbolic pointer
737 743 if (!m_symbolic)
738 744 throw GException::matrix_not_factorised(G_CHOL_SOLVE, "Cholesky decomposition");
739 745  
740 746 // Get symbolic pointer
741 747 GSparseSymbolic* symbolic = (GSparseSymbolic*)m_symbolic;
742   -
  748 +
743 749 // Raise an exception if there is no permutation
744 750 if (!symbolic->m_pinv)
745 751 throw GException::matrix_not_factorised(G_CHOL_SOLVE, "Cholesky decomposition");
... ... @@ -750,7 +756,7 @@ GVector GSparseMatrix::cholesky_solver(const GVector&amp; v, int compress)
750 756  
751 757 // Decide if we need a compression algorithm or not
752 758 int no_zero = !(compress && (row_compressed || col_compressed));
753   -
  759 +
754 760 // Allocate vector for permutation and result vector
755 761 GVector result(m_cols);
756 762  
... ... @@ -763,7 +769,7 @@ GVector GSparseMatrix::cholesky_solver(const GVector&amp; v, int compress)
763 769 if (no_zero) {
764 770  
765 771 // Declare working vector
766   - GVector x(m_rows);
  772 + GVector x(m_rows);
767 773  
768 774 // Perform inverse vector permutation
769 775 for (int i = 0; i < v.m_num; ++i)
... ... @@ -771,27 +777,27 @@ GVector GSparseMatrix::cholesky_solver(const GVector&amp; v, int compress)
771 777  
772 778 // Inplace solve L\x=x
773 779 for (col = 0; col < m_cols; ++col) { // loop over columns
774   - x.m_data[col] /= Lx[Lp[col]]; // divide by diag.
775   - for (int p = Lp[col]+1; p < Lp[col+1]; p++) // loop over elements
  780 + x.m_data[col] /= Lx[Lp[col]]; // divide by diag.
  781 + for (int p = Lp[col]+1; p < Lp[col+1]; p++) // loop over elements
776 782 x.m_data[Li[p]] -= Lx[p] * x.m_data[col];
777 783 }
778   -
  784 +
779 785 // Inplace solve L'\x=x
780 786 for (col = m_cols-1; col >= 0; --col) { // loop over columns
781   - for (int p = Lp[col]+1; p < Lp[col+1]; p++) // loop over elements
782   - x.m_data[col] -= Lx[p] * x.m_data[Li[p]];
783   - x.m_data[col] /= Lx[Lp[col]];
  787 + for (int p = Lp[col]+1; p < Lp[col+1]; p++) // loop over elements
  788 + x.m_data[col] -= Lx[p] * x.m_data[Li[p]];
  789 + x.m_data[col] /= Lx[Lp[col]];
784 790 }
785   -
786   - // Perform vector permutation
787   - for (int i = 0; i < m_cols; ++i)
  791 +
  792 + // Perform vector permutation
  793 + for (int i = 0; i < m_cols; ++i)
788 794 result.m_data[i] = x.m_data[symbolic->m_pinv[i]];
789   -
  795 +
790 796 } // endif: Case A
791   -
  797 +
792 798 // Case B: zero-row/column compression requested
793 799 else {
794   -
  800 +
795 801 // Allocate row and column mapping arrays
796 802 int* row_map = new int[m_rows];
797 803 if (row_map == NULL)
... ... @@ -802,54 +808,54 @@ GVector GSparseMatrix::cholesky_solver(const GVector&amp; v, int compress)
802 808  
803 809 // Setup row mapping array that maps original matrix rows into compressed
804 810 // matrix rows. An entry of -1 indicates that the row should be dropped.
805   - // If no selection exists then setup an identity map.
806   - if (row_compressed) {
  811 + // If no selection exists then setup an identity map.
  812 + if (row_compressed) {
807 813 for (row = 0; row < m_rows; ++row)
808 814 row_map[row] = -1;
809 815 for (c_row = 0; c_row < m_num_rowsel; ++c_row)
810 816 row_map[m_rowsel[c_row]] = c_row;
811   - }
812   - else {
  817 + }
  818 + else {
813 819 for (row = 0; row < m_rows; ++row)
814 820 row_map[row] = row;
815   - }
  821 + }
816 822 #if defined(G_DEBUG_SPARSE_COMPRESSION)
817 823 cout << " Row mapping ......:";
818   - for (row = 0; row < m_rows; ++row)
819   - cout << " " << row_map[row];
820   - cout << endl;
  824 + for (row = 0; row < m_rows; ++row)
  825 + cout << " " << row_map[row];
  826 + cout << endl;
821 827 #endif
822 828  
823 829 // Setup column mapping array that maps original matrix column into compressed
824 830 // matrix columns. An entry of -1 indicates that the column should be dropped
825   - // If no selection exists then setup an identity map.
826   - if (col_compressed) {
  831 + // If no selection exists then setup an identity map.
  832 + if (col_compressed) {
827 833 for (col = 0; col < m_cols; ++col)
828 834 col_map[col] = -1;
829 835 for (c_col = 0; c_col < m_num_colsel; ++c_col)
830 836 col_map[m_colsel[c_col]] = c_col;
831   - }
832   - else {
  837 + }
  838 + else {
833 839 for (col = 0; col < m_cols; ++col)
834 840 col_map[col] = col;
835   - }
  841 + }
836 842 #if defined(G_DEBUG_SPARSE_COMPRESSION)
837 843 cout << " Column mapping ...:";
838   - for (col = 0; col < m_cols; ++col)
839   - cout << " " << col_map[col];
840   - cout << endl;
  844 + for (col = 0; col < m_cols; ++col)
  845 + cout << " " << col_map[col];
  846 + cout << endl;
841 847 #endif
842 848  
843 849 // Declare working vector
844   - GVector x(row_compressed ? m_num_rowsel : m_rows);
845   -
846   - // Compress input vector v -> c_v if required
  850 + GVector x(row_compressed ? m_num_rowsel : m_rows);
  851 +
  852 + // Compress input vector v -> c_v if required
847 853 if (m_rowsel != NULL && m_num_rowsel < m_rows) {
848 854 for (c_row = 0; c_row < m_num_rowsel; ++c_row)
849   - x.m_data[c_row] = v.m_data[m_rowsel[c_row]];
850   - }
851   - else
852   - x = v;
  855 + x.m_data[c_row] = v.m_data[m_rowsel[c_row]];
  856 + }
  857 + else
  858 + x = v;
853 859 #if defined(G_DEBUG_SPARSE_COMPRESSION)
854 860 cout << " Compressed vector : " << x << endl;
855 861 #endif
... ... @@ -859,32 +865,32 @@ GVector GSparseMatrix::cholesky_solver(const GVector&amp; v, int compress)
859 865 #if defined(G_DEBUG_SPARSE_COMPRESSION)
860 866 cout << " Permutated vector : " << x << endl;
861 867 #endif
862   -
  868 +
863 869 // Inplace solve L\x=x. The column and row maps are just use to see which
864   - // columns or rows should be skipped in the calculations.
  870 + // columns or rows should be skipped in the calculations.
865 871 for (col = 0; col < m_cols; ++col) { // loop over columns
866   - if ((c_col = col_map[col]) >= 0) { // use only non-zero cols
867   - x.m_data[c_col] /= Lx[Lp[col]]; // divide by diag.
868   - for (int p = Lp[col]+1; p < Lp[col+1]; p++) { // loop over elements
869   - if ((c_row = row_map[Li[p]]) >= 0) // use only non-zero rows
  872 + if ((c_col = col_map[col]) >= 0) { // use only non-zero cols
  873 + x.m_data[c_col] /= Lx[Lp[col]]; // divide by diag.
  874 + for (int p = Lp[col]+1; p < Lp[col+1]; p++) { // loop over elements
  875 + if ((c_row = row_map[Li[p]]) >= 0) // use only non-zero rows
870 876 x.m_data[c_row] -= Lx[p] * x.m_data[c_col];
871   - }
872   - }
  877 + }
  878 + }
873 879 }
874 880 #if defined(G_DEBUG_SPARSE_COMPRESSION)
875 881 cout << " Solve Lx=x .......: " << x << endl;
876 882 #endif
877   -
  883 +
878 884 // Inplace solve L'\x=x. The column and row maps are just use to see which
879   - // columns or rows should be skipped in the calculations.
  885 + // columns or rows should be skipped in the calculations.
880 886 for (col = m_cols-1; col >= 0; --col) { // loop over columns
881   - if ((c_col = col_map[col]) >= 0) { // use only non-zero cols
882   - for (int p = Lp[col]+1; p < Lp[col+1]; p++) { // loop over elements
883   - if ((c_row = row_map[Li[p]]) >= 0) // use only non-zero rows
884   - x.m_data[c_col] -= Lx[p] * x.m_data[c_row];
885   - }
886   - x.m_data[c_col] /= Lx[Lp[col]];
887   - }
  887 + if ((c_col = col_map[col]) >= 0) { // use only non-zero cols
  888 + for (int p = Lp[col]+1; p < Lp[col+1]; p++) { // loop over elements
  889 + if ((c_row = row_map[Li[p]]) >= 0) // use only non-zero rows
  890 + x.m_data[c_col] -= Lx[p] * x.m_data[c_row];
  891 + }
  892 + x.m_data[c_col] /= Lx[Lp[col]];
  893 + }
888 894 }
889 895 #if defined(G_DEBUG_SPARSE_COMPRESSION)
890 896 cout << " Solve L'x=x ......: " << x << endl;
... ... @@ -895,15 +901,15 @@ GVector GSparseMatrix::cholesky_solver(const GVector&amp; v, int compress)
895 901 #if defined(G_DEBUG_SPARSE_COMPRESSION)
896 902 cout << " Permutated vector : " << x << endl;
897 903 #endif
898   -
  904 +
899 905 // If column compression has been performed the expand the result vector
900 906 // accordingly
901 907 if (m_colsel != NULL && m_num_colsel < m_cols) {
902   - for (c_col = 0; c_col < m_num_colsel; ++c_col)
903   - result.m_data[m_colsel[c_col]] = x.m_data[c_col];
904   - }
905   - else
906   - result = x;
  908 + for (c_col = 0; c_col < m_num_colsel; ++c_col)
  909 + result.m_data[m_colsel[c_col]] = x.m_data[c_col];
  910 + }
  911 + else
  912 + result = x;
907 913 #if defined(G_DEBUG_SPARSE_COMPRESSION)
908 914 cout << " Restored vector ..: " << result << endl;
909 915 #endif
... ... @@ -911,7 +917,7 @@ GVector GSparseMatrix::cholesky_solver(const GVector&amp; v, int compress)
911 917 // Free mapping arrays
912 918 delete [] row_map;
913 919 delete [] col_map;
914   -
  920 +
915 921 } // endelse: Case B
916 922  
917 923 // Return result vector
... ... @@ -935,23 +941,23 @@ void GSparseMatrix::cholesky_invert(int compress)
935 941  
936 942 // Column-wise solving of the problem
937 943 for (int col = 0; col < m_cols; ++col) {
938   -
  944 +
939 945 // Set unit vector
940   - unit.m_data[col] = 1.0;
941   -
942   - // Solve for column
943   - GVector x = cholesky_solver(unit, compress);
944   -
945   - // Insert column in matrix
  946 + unit.m_data[col] = 1.0;
  947 +
  948 + // Solve for column
  949 + GVector x = cholesky_solver(unit, compress);
  950 +
  951 + // Insert column in matrix
946 952 result.insert_col(x, col);
947 953  
948 954 // Clear unit vector for next round
949   - unit.m_data[col] = 0.0;
950   -
  955 + unit.m_data[col] = 0.0;
  956 +
951 957 }
952   -
  958 +
953 959 *this = result;
954   -
  960 +
955 961 // Return
956 962 return;
957 963 }
... ... @@ -969,7 +975,7 @@ void GSparseMatrix::clear()
969 975 // Initialise column start indices to 0
970 976 for (int col = 0; col <= m_cols; ++col)
971 977 m_colstart[col] = 0;
972   -
  978 +
973 979 // Return
974 980 return;
975 981 }
... ... @@ -986,34 +992,34 @@ GVector GSparseMatrix::extract_row(int row) const
986 992 if (row >= m_rows)
987 993 throw GException::out_of_range(G_EXTRACT_ROW, row, 0, m_rows, m_cols);
988 994 #endif
989   -
  995 +
990 996 // Create result vector
991 997 GVector result(m_cols);
992   -
  998 +
993 999 // Loop over all columns to extract data
994 1000 for (int col = 0; col < m_cols; ++col) {
995   -
  1001 +
996 1002 // Get the start and stop of the elements
997 1003 int i_start = m_colstart[col];
998 1004 int i_stop = m_colstart[col+1];
999   -
1000   - // Search requested row in elements
1001   - int i;
  1005 +
  1006 + // Search requested row in elements
  1007 + int i;
1002 1008 for (i = i_start; i < i_stop; ++i) {
1003   - if (m_rowinx[i] == row)
1004   - break;
1005   - }
1006   -
1007   - // Copy element if we found one
1008   - if (i < i_stop)
1009   - result(col) = m_data[i];
1010   -
  1009 + if (m_rowinx[i] == row)
  1010 + break;
  1011 + }
  1012 +
  1013 + // Copy element if we found one
  1014 + if (i < i_stop)
  1015 + result(col) = m_data[i];
  1016 +
1011 1017 } // endfor: looped over all columns
1012   -
  1018 +
1013 1019 // If there is a pending element then put it in the vector
1014 1020 if (m_fill_val != 0.0 && m_fill_row == row)
1015 1021 result(m_fill_col) = m_fill_val;
1016   -
  1022 +
1017 1023 // Return vector
1018 1024 return result;
1019 1025  
... ... @@ -1030,14 +1036,14 @@ GVector GSparseMatrix::extract_col(int col) const
1030 1036 if (col >= m_cols)
1031 1037 throw GException::out_of_range(G_EXTRACT_COL, 0, col, m_rows, m_cols);
1032 1038 #endif
1033   -
  1039 +
1034 1040 // Create result vector
1035 1041 GVector result(m_rows);
1036 1042  
1037 1043 // Get the start and stop of the elements
1038 1044 int i_start = m_colstart[col];
1039 1045 int i_stop = m_colstart[col+1];
1040   -
  1046 +
1041 1047 // Extract elements into vector
1042 1048 for (int i = i_start; i < i_stop; ++i)
1043 1049 result(m_rowinx[i]) = m_data[i];
... ... @@ -1045,7 +1051,7 @@ GVector GSparseMatrix::extract_col(int col) const
1045 1051 // If there is a pending element then put it in the vector
1046 1052 if (m_fill_val != 0.0 && m_fill_col == col)
1047 1053 result(m_fill_row) = m_fill_val;
1048   -
  1054 +
1049 1055 // Return vector
1050 1056 return result;
1051 1057 }
... ... @@ -1059,7 +1065,7 @@ double GSparseMatrix::fill() const
1059 1065 {
1060 1066 // Determine number of elements in matrix
1061 1067 int num = (m_fill_val == 0.0) ? m_elements : m_elements + 1;
1062   -
  1068 +
1063 1069 // Return fill
1064 1070 return (double(num) / double(m_rows*m_cols));
1065 1071 }
... ... @@ -1079,16 +1085,16 @@ void GSparseMatrix::insert_col(const GVector&amp; v, int col)
1079 1085 cout << "GSparseMatrix::insert_col([" << v << "], " << col << "):" << endl;
1080 1086 cout << " In Data : ";
1081 1087 for (int i = 0; i < m_elements; ++i)
1082   - cout << m_data[i] << " ";
  1088 + cout << m_data[i] << " ";
1083 1089 cout << endl << " In Row .: ";
1084 1090 for (int i = 0; i < m_elements; ++i)
1085   - cout << m_rowinx[i] << " ";
  1091 + cout << m_rowinx[i] << " ";
1086 1092 cout << endl << " In Col .: ";
1087 1093 for (int i = 0; i < m_cols+1; ++i)
1088   - cout << m_colstart[i] << " ";
  1094 + cout << m_colstart[i] << " ";
1089 1095 cout << endl;
1090 1096 #endif
1091   -
  1097 +
1092 1098 // Raise an exception if the column index is invalid
1093 1099 #if defined(G_RANGE_CHECK)
1094 1100 if (col >= m_cols)
... ... @@ -1104,76 +1110,76 @@ void GSparseMatrix::insert_col(const GVector&amp; v, int col)
1104 1110 if (m_fill_val != 0.0 && m_fill_col == col) {
1105 1111 #if defined(G_DEBUG_SPARSE_PENDING)
1106 1112 cout << G_INSERT_COL << ": pending value " << m_fill_val <<
1107   - " for location (" << m_fill_row << "," << m_fill_col <<
1108   - ") became obsolete" << endl;
1109   - #endif
  1113 + " for location (" << m_fill_row << "," << m_fill_col <<
  1114 + ") became obsolete" << endl;
  1115 + #endif
1110 1116 m_fill_val = 0.0;
1111   - m_fill_row = 0;
1112   - m_fill_col = 0;
  1117 + m_fill_row = 0;
  1118 + m_fill_col = 0;
1113 1119 }
1114 1120  
1115 1121 // Determine the number of non-zero elements in the vector
1116 1122 int n_vector = 0;
1117 1123 for (int row = 0; row < m_rows; ++row) {
1118 1124 if (v.m_data[row] != 0.0)
1119   - n_vector++;
  1125 + n_vector++;
1120 1126 }
1121   -
  1127 +
1122 1128 // Get the start and stop indices of the actual column and compute
1123 1129 // the number of exisiting elements in the column
1124 1130 int i_start = m_colstart[col];
1125 1131 int i_stop = m_colstart[col+1];
1126 1132 int n_exist = i_stop - i_start;
1127   -
  1133 +
1128 1134 // Compute the size difference for the new matrix. It is positive if
1129 1135 // the number of non-zero entries in the vector is larger than the
1130 1136 // number of non-zero entries in the matrix (in this case we have to
1131 1137 // increase the matrix size).
1132 1138 int n_diff = n_vector - n_exist;
1133   -
  1139 +
1134 1140 // If we need space then allocate it, if we have to much space then free it
1135 1141 if (n_diff > 0) {
1136   - alloc_elements(i_start, n_diff);
1137   - #if defined(G_DEBUG_SPARSE_INSERTION)
  1142 + alloc_elements(i_start, n_diff);
  1143 + #if defined(G_DEBUG_SPARSE_INSERTION)
1138 1144 cout << " Insert .: " << n_diff << " elements at index " << i_start << endl;
1139 1145 #endif
1140 1146 }
1141 1147 else if (n_diff < 0) {
1142   - free_elements(i_start, -n_diff);
1143   - #if defined(G_DEBUG_SPARSE_INSERTION)
  1148 + free_elements(i_start, -n_diff);
  1149 + #if defined(G_DEBUG_SPARSE_INSERTION)
1144 1150 cout << " Remove .: " << -n_diff << " elements at index " << i_start << endl;
1145 1151 #endif
1146 1152 }
1147   -
  1153 +
1148 1154 // Insert the vector elements in the matrix
1149 1155 if (n_vector > 0) {
1150 1156 for (int row = 0, i = i_start; row < m_rows; ++row) {
1151   - if (v.m_data[row] != 0.0) {
1152   - m_data[i] = v.m_data[row];
1153   - m_rowinx[i] = row;
1154   - i++;
1155   - }
  1157 + if (v.m_data[row] != 0.0) {
  1158 + m_data[i] = v.m_data[row];
  1159 + m_rowinx[i] = row;
  1160 + i++;
  1161 + }
1156 1162 }
1157 1163 }
1158   -
  1164 +
1159 1165 // Update column start indices
1160 1166 for (int i = col+1; i <= m_cols; ++i)
1161   - m_colstart[i] += n_diff;
  1167 + m_colstart[i] += n_diff;
1162 1168  
1163 1169 // Debugging: show sparse matrix after insertion
1164 1170 #if defined(G_DEBUG_SPARSE_INSERTION)
1165 1171 cout << " Out Data: ";
1166 1172 for (int i = 0; i < m_elements; ++i)
1167   - cout << m_data[i] << " ";
  1173 + cout << m_data[i] << " ";
1168 1174 cout << endl << " Out Row : ";
1169 1175 for (int i = 0; i < m_elements; ++i)
1170   - cout << m_rowinx[i] << " ";
  1176 + cout << m_rowinx[i] << " ";
1171 1177 cout << endl << " Out Col : ";
1172 1178 for (int i = 0; i < m_cols+1; ++i)
1173   - cout << m_colstart[i] << " ";
  1179 + cout << m_colstart[i] << " ";
1174 1180 cout << endl;
1175 1181 #endif
1176   -
  1182 +
1177 1183 // Return
1178 1184 return;
1179 1185 }
... ... @@ -1193,23 +1199,23 @@ void GSparseMatrix::insert_col(const double* values, const int* rows,
1193 1199 cout << "GSparseMatrix::insert_col(v, i, n, " << col << "):" << endl;
1194 1200 cout << " Matrix Data : ";
1195 1201 for (int i = 0; i < m_elements; ++i)
1196   - cout << m_data[i] << " ";
  1202 + cout << m_data[i] << " ";
1197 1203 cout << endl << " Matrix Row .: ";
1198 1204 for (int i = 0; i < m_elements; ++i)
1199   - cout << m_rowinx[i] << " ";
  1205 + cout << m_rowinx[i] << " ";
1200 1206 cout << endl << " Matrix Col .: ";
1201 1207 for (int i = 0; i < m_cols+1; ++i)
1202   - cout << m_colstart[i] << " ";
  1208 + cout << m_colstart[i] << " ";
1203 1209 cout << endl;
1204 1210 cout << " Array Data .: ";
1205 1211 for (int i = 0; i < number; ++i)
1206   - cout << values[i] << " ";
  1212 + cout << values[i] << " ";
1207 1213 cout << endl << " Array Row ..: ";
1208 1214 for (int i = 0; i < number; ++i)
1209   - cout << rows[i] << " ";
  1215 + cout << rows[i] << " ";
1210 1216 cout << endl;
1211 1217 #endif
1212   -
  1218 +
1213 1219 // Raise an exception if the column index is invalid
1214 1220 #if defined(G_RANGE_CHECK)
1215 1221 if (col >= m_cols)
... ... @@ -1226,12 +1232,12 @@ void GSparseMatrix::insert_col(const double* values, const int* rows,
1226 1232 if (m_fill_val != 0.0 && m_fill_col == col) {
1227 1233 #if defined(G_DEBUG_SPARSE_PENDING)
1228 1234 cout << G_INSERT_COL2 << ": pending value " << m_fill_val <<
1229   - " for location (" << m_fill_row << "," << m_fill_col <<
1230   - ") became obsolete" << endl;
1231   - #endif
  1235 + " for location (" << m_fill_row << "," << m_fill_col <<
  1236 + ") became obsolete" << endl;
  1237 + #endif
1232 1238 m_fill_val = 0.0;
1233   - m_fill_row = 0;
1234   - m_fill_col = 0;
  1239 + m_fill_row = 0;
  1240 + m_fill_col = 0;
1235 1241 }
1236 1242  
1237 1243 // Get the start and stop indices of the actual column and compute
... ... @@ -1243,54 +1249,54 @@ void GSparseMatrix::insert_col(const double* values, const int* rows,
1243 1249 // If the array is empty then make sure that the number of elements is 0
1244 1250 // (we then just delete the existing column)
1245 1251 if (!values || !rows)
1246   - number = 0;
1247   -
  1252 + number = 0;
  1253 +
1248 1254 // Compute the size difference for the new matrix. It is positive if
1249 1255 // the number of non-zero entries in the array is larger than the
1250 1256 // number of non-zero entries in the matrix (in this case we have to
1251 1257 // increase the matrix size).
1252 1258 int n_diff = number - n_exist;
1253   -
  1259 +
1254 1260 // If we need space then allocate it, if we have to much space then free it
1255 1261 if (n_diff > 0) {
1256   - alloc_elements(i_start, n_diff);
1257   - #if defined(G_DEBUG_SPARSE_INSERTION)
  1262 + alloc_elements(i_start, n_diff);
  1263 + #if defined(G_DEBUG_SPARSE_INSERTION)
1258 1264 cout << " Insert .: " << n_diff << " elements at index " << i_start << endl;
1259 1265 #endif
1260 1266 }
1261 1267 else if (n_diff < 0) {
1262   - free_elements(i_start, -n_diff);
1263   - #if defined(G_DEBUG_SPARSE_INSERTION)
  1268 + free_elements(i_start, -n_diff);
  1269 + #if defined(G_DEBUG_SPARSE_INSERTION)
1264 1270 cout << " Remove .: " << -n_diff << " elements at index " << i_start << endl;
1265 1271 #endif
1266 1272 }
1267   -
  1273 +
1268 1274 // Insert the array elements into the matrix
1269 1275 if (number > 0) {
1270 1276 for (int row = 0, i = i_start; row < number; ++row, ++i) {
1271   - m_data[i] = values[row];
1272   - m_rowinx[i] = rows[row];
  1277 + m_data[i] = values[row];
  1278 + m_rowinx[i] = rows[row];
1273 1279 }
1274 1280 }
1275   -
  1281 +
1276 1282 // Update column start indices
1277 1283 for (int i = col+1; i <= m_cols; ++i)
1278   - m_colstart[i] += n_diff;
  1284 + m_colstart[i] += n_diff;
1279 1285  
1280 1286 // Debugging: show sparse matrix after insertion
1281 1287 #if defined(G_DEBUG_SPARSE_INSERTION)
1282 1288 cout << " Out Data: ";
1283 1289 for (int i = 0; i < m_elements; ++i)
1284   - cout << m_data[i] << " ";
  1290 + cout << m_data[i] << " ";
1285 1291 cout << endl << " Out Row : ";
1286 1292 for (int i = 0; i < m_elements; ++i)
1287   - cout << m_rowinx[i] << " ";
  1293 + cout << m_rowinx[i] << " ";
1288 1294 cout << endl << " Out Col : ";
1289 1295 for (int i = 0; i < m_cols+1; ++i)
1290   - cout << m_colstart[i] << " ";
  1296 + cout << m_colstart[i] << " ";
1291 1297 cout << endl;
1292 1298 #endif
1293   -
  1299 +
1294 1300 // Return
1295 1301 return;
1296 1302 }
... ... @@ -1304,18 +1310,18 @@ double GSparseMatrix::min() const
1304 1310 {
1305 1311 // Initialise minimum with fill value
1306 1312 double result = m_fill_val;
1307   -
  1313 +
1308 1314 // Search all elements for the smallest one
1309 1315 for (int i = 0; i < m_elements; ++i) {
1310 1316 if (m_data[i] < result)
1311   - result = m_data[i];
  1317 + result = m_data[i];
1312 1318 }
1313   -
  1319 +
1314 1320 // If minimum is > 0.0 and there are zero elements then set the minimum
1315 1321 // to 0.0
1316 1322 if ((result > 0.0) && (m_elements < (m_rows*m_cols)))
1317 1323 result = 0.0;
1318   -
  1324 +
1319 1325 // Return result
1320 1326 return result;
1321 1327 }
... ... @@ -1333,7 +1339,7 @@ double GSparseMatrix::max() const
1333 1339 // Search all elements for the largest one
1334 1340 for (int i = 0; i < m_elements; ++i) {
1335 1341 if (m_data[i] > result)
1336   - result = m_data[i];
  1342 + result = m_data[i];
1337 1343 }
1338 1344  
1339 1345 // If maximum is < 0.0 and there are zero elements then set the maximum
... ... @@ -1358,12 +1364,12 @@ void GSparseMatrix::stack_init(int size, int entries)
1358 1364 {
1359 1365 // Free exisiting stack
1360 1366 free_stack_members();
1361   -
  1367 +
1362 1368 // Initialise stack members
1363 1369 init_stack_members();
1364 1370 m_stack_max_entries = (entries > 0) ? entries : m_cols;
1365 1371 m_stack_size = (size > 0) ? size : G_SPARSE_MATRIX_DEFAULT_STACK_SIZE;
1366   -
  1372 +
1367 1373 // Allocate stack memory. Raise an exception if allocation fails
1368 1374 m_stack_colinx = new int[m_stack_max_entries];
1369 1375 m_stack_start = new int[m_stack_max_entries+1];
... ... @@ -1372,14 +1378,14 @@ void GSparseMatrix::stack_init(int size, int entries)
1372 1378 m_stack_work = new int[m_cols];
1373 1379 m_stack_buffer = new double[m_cols];
1374 1380 if (m_stack_colinx == NULL)
1375   - throw GException::mem_alloc(G_STACK_INIT, m_stack_max_entries);
  1381 + throw GException::mem_alloc(G_STACK_INIT, m_stack_max_entries);
1376 1382 if (m_stack_start == NULL)
1377   - throw GException::mem_alloc(G_STACK_INIT, m_stack_max_entries+1);
  1383 + throw GException::mem_alloc(G_STACK_INIT, m_stack_max_entries+1);
1378 1384 if (m_stack_data == NULL || m_stack_rowinx == NULL)
1379   - throw GException::mem_alloc(G_STACK_INIT, m_stack_size);
  1385 + throw GException::mem_alloc(G_STACK_INIT, m_stack_size);
1380 1386 if (m_stack_work == NULL || m_stack_buffer == NULL)
1381   - throw GException::mem_alloc(G_STACK_INIT, m_cols);
1382   -
  1387 + throw GException::mem_alloc(G_STACK_INIT, m_cols);
  1388 +
1383 1389 // Initialise next free stack location to the first stack element
1384 1390 m_stack_start[0] = 0;
1385 1391  
... ... @@ -1417,7 +1423,7 @@ int GSparseMatrix::stack_push_column(const double* values, const int* rows,
1417 1423 // If there is no stack or the stack can not hold the requested number of
1418 1424 // elements then report number of array elements to the caller
1419 1425 if (m_stack_data == NULL || number > m_stack_size)
1420   - continue;
  1426 + continue;
1421 1427  
1422 1428 // Raise an exception if the column index is invalid
1423 1429 #if defined(G_RANGE_CHECK)
... ... @@ -1430,7 +1436,7 @@ int GSparseMatrix::stack_push_column(const double* values, const int* rows,
1430 1436 if (rows[number-1] >= m_rows)
1431 1437 throw GException::matrix_vector_mismatch(G_STACK_PUSH, rows[number-1], m_rows, m_cols);
1432 1438  
1433   - // Debug header
  1439 + // Debug header
1434 1440 #if defined(G_DEBUG_SPARSE_STACK_PUSH)
1435 1441 cout << "GSparseMatrix::stack_push_column(v, i, n, col=" << col << ")" << endl;
1436 1442 cout << " Data to push on stack ...:";
... ... @@ -1441,87 +1447,87 @@ int GSparseMatrix::stack_push_column(const double* values, const int* rows,
1441 1447 for (int i = 0; i < number; ++i)
1442 1448 cout << " " << rows[i];
1443 1449 cout << endl;
1444   - #endif
  1450 + #endif
1445 1451  
1446 1452 // If the stack is full then flush it before pushing the array onto it.
1447   - // There are 2 conditions that may fill the stack: all entries are
1448   - // occupied or there is not enough space to hold more elements
  1453 + // There are 2 conditions that may fill the stack: all entries are
  1454 + // occupied or there is not enough space to hold more elements
1449 1455 if ((m_stack_entries >= m_stack_max_entries) ||
1450 1456 (number >= (m_stack_size - m_stack_start[m_stack_entries])))
1451   - stack_flush();
  1457 + stack_flush();
1452 1458  
1453 1459 // If the specified column is already on the stack then mix new column with
1454 1460 // old one and invalidate old column (by setting its column index to -1).
1455   - // Since we loop here over all stack entries we don't want to have too
1456   - // many entries in the stack. So don't set the maximum number of stack
1457   - // entries too large ...
  1461 + // Since we loop here over all stack entries we don't want to have too
  1462 + // many entries in the stack. So don't set the maximum number of stack
  1463 + // entries too large ...
1458 1464 for (int entry = 0; entry < m_stack_entries; ++entry) {
1459 1465 if (col == m_stack_colinx[entry]) {
1460 1466  
1461 1467 // Get start and stop indices of existing column in stack
1462   - int i_start = m_stack_start[entry];
1463   - int i_stop = m_stack_start[entry+1];
1464   -
1465   - // Allocate variables to hold mixing results
1466   - int num_1; // Number of elements that are only in stack column
1467   - int num_2; // Number of elements that are only in new column
1468   - int num_mix; // Number of elements that are in both columns
1469   -
1470   - // Determine how many elements are requested to hold the combined
1471   - // column
  1468 + int i_start = m_stack_start[entry];
  1469 + int i_stop = m_stack_start[entry+1];
  1470 +
  1471 + // Allocate variables to hold mixing results
  1472 + int num_1; // Number of elements that are only in stack column
  1473 + int num_2; // Number of elements that are only in new column
  1474 + int num_mix; // Number of elements that are in both columns
  1475 +
  1476 + // Determine how many elements are requested to hold the combined
  1477 + // column
1472 1478 mix_column_prepare(&(m_stack_rowinx[i_start]), i_stop-i_start,
1473   - rows, number, &num_1, &num_2, &num_mix);
1474   - int num_request = num_1 + num_2 + num_mix;
1475   -
1476   - // If there is not enough space in the stack to hold the combined
1477   - // column we flush the stack and exit the loop now. In this case the
1478   - // new column is put as the first column in the empty (flushed stack)
1479   - if (num_request >= (m_stack_size - m_stack_start[m_stack_entries])) {
1480   - stack_flush();
1481   - break;
1482   - }
1483   -
1484   - // There is enough space, so combine both columns into a fresh one
  1479 + rows, number, &num_1, &num_2, &num_mix);
  1480 + int num_request = num_1 + num_2 + num_mix;
  1481 +
  1482 + // If there is not enough space in the stack to hold the combined
  1483 + // column we flush the stack and exit the loop now. In this case the
  1484 + // new column is put as the first column in the empty (flushed stack)
  1485 + if (num_request >= (m_stack_size - m_stack_start[m_stack_entries])) {
  1486 + stack_flush();
  1487 + break;
  1488 + }
  1489 +
  1490 + // There is enough space, so combine both columns into a fresh one
1485 1491 int inx = m_stack_start[m_stack_entries];
1486   - int num_new;
  1492 + int num_new;
1487 1493 mix_column(&(m_stack_data[i_start]), &(m_stack_rowinx[i_start]), i_stop-i_start,
1488 1494 values, rows, number,
1489   - &(m_stack_data[inx]), &(m_stack_rowinx[inx]), &num_new);
1490   -
  1495 + &(m_stack_data[inx]), &(m_stack_rowinx[inx]), &num_new);
  1496 +
1491 1497 // Store entry information and initialise start of next entry
1492 1498 m_stack_colinx[m_stack_entries] = col; // Store column index for entry
1493 1499 m_stack_entries++; // Increase the # of entries
1494 1500 m_stack_start[m_stack_entries] = inx + num_new; // Set start pointer for next entry
1495   -
1496   - // Invalidate old column
1497   - m_stack_colinx[entry] = -1;
1498   -
1499   - // Fall through to end
1500   - remaining = 0;
1501   - break;
1502   -
1503   - } // endif: we found an existing column
  1501 +
  1502 + // Invalidate old column
  1503 + m_stack_colinx[entry] = -1;
  1504 +
  1505 + // Fall through to end
  1506 + remaining = 0;
  1507 + break;
  1508 +
  1509 + } // endif: we found an existing column
1504 1510 } // endfor: looped over all columns
1505   -
  1511 +
1506 1512 // If column has already been inserted then fall through ...
1507   - if (remaining == 0)
1508   - continue;
  1513 + if (remaining == 0)
  1514 + continue;
1509 1515  
1510 1516 // Otherwise, push the array on the stack
1511 1517 int inx = m_stack_start[m_stack_entries];
1512 1518 for (int i = 0; i < number; ++i) {
1513   - m_stack_data[inx] = values[i];
1514   - m_stack_rowinx[inx] = rows[i];
1515   - inx++;
  1519 + m_stack_data[inx] = values[i];
  1520 + m_stack_rowinx[inx] = rows[i];
  1521 + inx++;
1516 1522 }
1517   -
  1523 +
1518 1524 // Store entry information and initialise start of next entry
1519 1525 m_stack_colinx[m_stack_entries] = col; // Store column index for entry
1520 1526 m_stack_entries++; // Increase the # of entries
1521 1527 m_stack_start[m_stack_entries] = inx; // Set start pointer for next entry
1522   -
1523   - // Signal success
1524   - remaining = 0;
  1528 +
  1529 + // Signal success
  1530 + remaining = 0;
1525 1531  
1526 1532 } while (0); // End of main do-loop
1527 1533  
... ... @@ -1545,7 +1551,7 @@ int GSparseMatrix::stack_push_column(const double* values, const int* rows,
1545 1551 cout << " " << m_stack_rowinx[i];
1546 1552 cout << endl;
1547 1553 #endif
1548   -
  1554 +
1549 1555 // Return remaining number of elements
1550 1556 return remaining;
1551 1557 }
... ... @@ -1567,15 +1573,15 @@ int GSparseMatrix::stack_push_column(const GVector&amp; v, int col)
1567 1573 // Compress vector in the buffer and set-up row index array
1568 1574 for (int i = 0; i < v.m_num; ++i) {
1569 1575 if (v.m_data[i] != 0.0) {
1570   - m_stack_buffer[non_zero] = v.m_data[i];
1571   - m_stack_work[non_zero] = i;
1572   - non_zero++;
1573   - }
  1576 + m_stack_buffer[non_zero] = v.m_data[i];
  1577 + m_stack_work[non_zero] = i;
  1578 + non_zero++;
  1579 + }
1574 1580 }
1575   -
  1581 +
1576 1582 // Hand over to compressed array method
1577 1583 int remaining = stack_push_column(m_stack_buffer, m_stack_work, non_zero, col);
1578   -
  1584 +
1579 1585 // Return remaining number of elements
1580 1586 return remaining;
1581 1587 }
... ... @@ -1600,24 +1606,24 @@ void GSparseMatrix::stack_flush(void)
1600 1606  
1601 1607 // Fill pending value
1602 1608 fill_pending();
1603   -
1604   - // Debug header
  1609 +
  1610 + // Debug header
1605 1611 #if defined(G_DEBUG_SPARSE_STACK_FLUSH)
1606 1612 cout << "GSparseMatrix::stack_flush" << endl;
1607 1613 cout << " Number of stack entries .: " << m_stack_entries << endl;
1608 1614 cout << " Number of stack elements : " << m_stack_start[m_stack_entries] << endl;
1609 1615 cout << " Number of matrix elements: " << m_elements << endl;
1610 1616 #endif
1611   -
  1617 +
1612 1618 // Use stack working array to flag all columns that exist already in the
1613 1619 // matrix by 1 and all non-existing columns by 0
1614 1620 for (int col = 0; col < m_cols; ++col) {
1615 1621 if (m_colstart[col] < m_colstart[col+1])
1616   - m_stack_work[col] = 1;
1617   - else
  1622 + m_stack_work[col] = 1;
  1623 + else
1618 1624 m_stack_work[col] = 0;
1619 1625 }
1620   -
  1626 +
1621 1627 // Initialise some element counters
1622 1628 int new_elements = 0;
1623 1629 #if defined(G_DEBUG_SPARSE_STACK_FLUSH)
... ... @@ -1625,7 +1631,7 @@ void GSparseMatrix::stack_flush(void)
1625 1631 int num_stack = 0; // Number of elements only on stack
1626 1632 int num_both = 0; // Number of elements in matrix and on stack
1627 1633 #endif
1628   -
  1634 +
1629 1635 // Loop over all stack entries and gather the number of elements that are
1630 1636 // new with respect to the initial matrix. For each column set a flag with
1631 1637 // the following meanings:
... ... @@ -1634,53 +1640,53 @@ void GSparseMatrix::stack_flush(void)
1634 1640 // 1: Column exists in matrix only
1635 1641 // 0: Column does neither exist in matrix or stack
1636 1642 for (int entry = 0; entry < m_stack_entries; ++entry) {
1637   -
  1643 +
1638 1644 // Get column for actual entry
1639 1645 int col = m_stack_colinx[entry];
1640 1646  
1641 1647 // Consider only valid entries
1642   - if (col >= 0) {
1643   -
1644   - // If column exists already in matrix then determine total number
1645   - // of additional elements
1646   - if (m_stack_work[col] == 1) {
1647   -
1648   - // Flag that this column is a mixed column
1649   - m_stack_work[col] = -(entry+2);
1650   -
1651   - // Setup index boundaries
1652   - int i_start = m_colstart[col];
1653   - int i_stop = m_colstart[col+1];
1654   - int k_start = m_stack_start[entry];
1655   - int k_stop = m_stack_start[entry+1];
1656   -
1657   - // Allocate output counters
  1648 + if (col >= 0) {
  1649 +
  1650 + // If column exists already in matrix then determine total number
  1651 + // of additional elements
  1652 + if (m_stack_work[col] == 1) {
  1653 +
  1654 + // Flag that this column is a mixed column
  1655 + m_stack_work[col] = -(entry+2);
  1656 +
  1657 + // Setup index boundaries
  1658 + int i_start = m_colstart[col];
  1659 + int i_stop = m_colstart[col+1];
  1660 + int k_start = m_stack_start[entry];
  1661 + int k_stop = m_stack_start[entry+1];
  1662 +
  1663 + // Allocate output counters
1658 1664 int num_1;
1659 1665 int num_2;
1660 1666 int num_mix;
1661   -
1662   - // Analyse column mixing
  1667 +
  1668 + // Analyse column mixing
1663 1669 mix_column_prepare(&(m_rowinx[i_start]), i_stop-i_start,
1664   - &(m_stack_rowinx[k_start]), k_stop-k_start,
1665   - &num_1, &num_2, &num_mix);
  1670 + &(m_stack_rowinx[k_start]), k_stop-k_start,
  1671 + &num_1, &num_2, &num_mix);
1666 1672  
1667 1673 // Update element counters
1668   - new_elements += num_2;
  1674 + new_elements += num_2;
1669 1675 #if defined(G_DEBUG_SPARSE_STACK_FLUSH)
1670 1676 num_matrix += num_1;
1671 1677 num_stack += num_2;
1672 1678 num_both += num_mix;
1673 1679 #endif
1674 1680  
1675   - } // endif: column existed in the matrix
  1681 + } // endif: column existed in the matrix
1676 1682  
1677   - // If column did not exists in the matrix then consider all elements
1678   - // as new
1679   - else {
1680   - m_stack_work[col] = (entry+2);
1681   - new_elements += (m_stack_start[entry+1] - m_stack_start[entry]);
1682   - }
1683   - } // endif: entry was valid
  1683 + // If column did not exists in the matrix then consider all elements
  1684 + // as new
  1685 + else {
  1686 + m_stack_work[col] = (entry+2);
  1687 + new_elements += (m_stack_start[entry+1] - m_stack_start[entry]);
  1688 + }
  1689 + } // endif: entry was valid
1684 1690 } // endfor: looped over all entries
1685 1691 int elements = m_elements + new_elements;
1686 1692  
... ... @@ -1688,80 +1694,80 @@ void GSparseMatrix::stack_flush(void)
1688 1694 #if defined(G_DEBUG_SPARSE_STACK_FLUSH)
1689 1695 cout << " New elements ............: " << new_elements << endl;
1690 1696 #endif
1691   -
  1697 +
1692 1698 // Allocate memory for new matrix (always keep some elbow room)
1693 1699 m_alloc = elements + m_mem_block;
1694 1700 double* new_data = new double[m_alloc];
1695 1701 int* new_rowinx = new int[m_alloc];
1696 1702 if (new_data == NULL || new_rowinx == NULL)
1697   - throw GException::mem_alloc(G_STACK_FLUSH, m_alloc);
1698   -
  1703 + throw GException::mem_alloc(G_STACK_FLUSH, m_alloc);
  1704 +
1699 1705 // Fill new matrix. For this purpose we loop over all matrix columns
1700 1706 // and perform the operation that was identified in the previous scan
1701 1707 int index = 0;
1702 1708 for (int col = 0; col < m_cols; ++col) {
1703 1709  
1704 1710 // If column does not exist then skip
1705   - if (m_stack_work[col] == 0) {
1706   - m_colstart[col] = index;
1707   - continue;
1708   - }
  1711 + if (m_stack_work[col] == 0) {
  1712 + m_colstart[col] = index;
  1713 + continue;
  1714 + }
1709 1715  
1710 1716 // If column exists in the matrix but not in the stack we copy the
1711   - // existing column into the new matrix
1712   - if (m_stack_work[col] == 1) {
1713   - for (int i = m_colstart[col]; i < m_colstart[col+1]; ++i) {
1714   - new_data[index] = m_data[i];
1715   - new_rowinx[index] = m_rowinx[i];
1716   - index++;
  1717 + // existing column into the new matrix
  1718 + if (m_stack_work[col] == 1) {
  1719 + for (int i = m_colstart[col]; i < m_colstart[col+1]; ++i) {
  1720 + new_data[index] = m_data[i];
  1721 + new_rowinx[index] = m_rowinx[i];
  1722 + index++;
1717 1723 #if defined(G_DEBUG_SPARSE_STACK_FLUSH)
1718   - num_matrix++;
1719   - #endif
1720   - }
1721   - }
1722   -
1723   - // If column is new (i.e. it did not exist in the matrix before) we
1724   - // copy the stack into the new matrix
1725   - else if (m_stack_work[col] > 1) {
1726   - int entry = m_stack_work[col] - 2;
1727   - for (int i = m_stack_start[entry]; i < m_stack_start[entry+1]; ++i) {
1728   - new_data[index] = m_stack_data[i];
1729   - new_rowinx[index] = m_stack_rowinx[i];
1730   - index++;
  1724 + num_matrix++;
  1725 + #endif
  1726 + }
  1727 + }
  1728 +
  1729 + // If column is new (i.e. it did not exist in the matrix before) we
  1730 + // copy the stack into the new matrix
  1731 + else if (m_stack_work[col] > 1) {
  1732 + int entry = m_stack_work[col] - 2;
  1733 + for (int i = m_stack_start[entry]; i < m_stack_start[entry+1]; ++i) {
  1734 + new_data[index] = m_stack_data[i];
  1735 + new_rowinx[index] = m_stack_rowinx[i];
  1736 + index++;
1731 1737 #if defined(G_DEBUG_SPARSE_STACK_FLUSH)
1732   - num_stack++;
1733   - #endif
1734   - }
1735   - }
1736   -
1737   - // If column exists in the matrix and in the stack then we have to mix both
1738   - else {
1739   -
1740   - // Get stack entry for column mix
1741   - int entry = -(m_stack_work[col] + 2);
1742   -
1743   - // Setup index boundaries
1744   - int i_start = m_colstart[col];
1745   - int i_stop = m_colstart[col+1];
1746   - int k_start = m_stack_start[entry];
1747   - int k_stop = m_stack_start[entry+1];
1748   -
1749   - // Allocate output counter
  1738 + num_stack++;
  1739 + #endif
  1740 + }
  1741 + }
  1742 +
  1743 + // If column exists in the matrix and in the stack then we have to mix both
  1744 + else {
  1745 +
  1746 + // Get stack entry for column mix
  1747 + int entry = -(m_stack_work[col] + 2);
  1748 +
  1749 + // Setup index boundaries
  1750 + int i_start = m_colstart[col];
  1751 + int i_stop = m_colstart[col+1];
  1752 + int k_start = m_stack_start[entry];
  1753 + int k_stop = m_stack_start[entry+1];
  1754 +
  1755 + // Allocate output counter
1750 1756 int num;
1751   -
1752   - // Perform column mixing
  1757 +
  1758 + // Perform column mixing
1753 1759 mix_column(&(m_data[i_start]), &(m_rowinx[i_start]), i_stop-i_start,
1754   - &(m_stack_data[k_start]), &(m_stack_rowinx[k_start]), k_stop-k_start,
1755   - &(new_data[index]), &(new_rowinx[index]), &num);
  1760 + &(m_stack_data[k_start]), &(m_stack_rowinx[k_start]), k_stop-k_start,
  1761 + &(new_data[index]), &(new_rowinx[index]), &num);
1756 1762  
1757 1763 // Increment element index
1758   - index += num;
1759   -
  1764 + index += num;
  1765 +
1760 1766 } // endelse: column mixing required
1761   -
1762   - // Store actual index in column start array
1763   - m_colstart[col] = index;
1764   -
  1767 +
  1768 + // Store actual index in column start array
  1769 + m_colstart[col] = index;
  1770 +
1765 1771 } // endfor: looped over all columns
1766 1772  
1767 1773 // Dump number of elements in new matrix after addition
... ... @@ -1776,11 +1782,11 @@ void GSparseMatrix::stack_flush(void)
1776 1782 for (int col = m_cols; col > 0; --col)
1777 1783 m_colstart[col] = m_colstart[col-1];
1778 1784 m_colstart[0] = 0;
1779   -
  1785 +
1780 1786 // Delete old matrix memory
1781 1787 if (m_data != NULL) delete [] m_data;
1782 1788 if (m_rowinx != NULL) delete [] m_rowinx;
1783   -
  1789 +
1784 1790 // Update pointers to new memory and update element counter
1785 1791 m_data = new_data;
1786 1792 m_rowinx = new_rowinx;
... ... @@ -1804,13 +1810,13 @@ void GSparseMatrix::stack_destroy(void)
1804 1810 {
1805 1811 // Flush stack first
1806 1812 stack_flush();
1807   -
  1813 +
1808 1814 // Free stack members
1809 1815 free_stack_members();
1810   -
  1816 +
1811 1817 // Initialise stack (no entries)
1812 1818 init_stack_members();
1813   -
  1819 +
1814 1820 // Return
1815 1821 return;
1816 1822 }
... ... @@ -1824,11 +1830,11 @@ double GSparseMatrix::sum() const
1824 1830 {
1825 1831 // Initialise matrix sum with fill value
1826 1832 double result = m_fill_val;
1827   -
1828   - // Add all elements
  1833 +
  1834 + // Add all elements
1829 1835 for (int i = 0; i < m_elements; ++i)
1830 1836 result += m_data[i];
1831   -
  1837 +
1832 1838 // Return result
1833 1839 return result;
1834 1840 }
... ... @@ -1854,7 +1860,7 @@ void GSparseMatrix::constructor(int rows, int cols, int elements)
1854 1860 // filling of the matrix
1855 1861 m_colstart = new int[cols+1];
1856 1862 if (m_colstart == NULL)
1857   - throw GException::mem_alloc(G_CONSTRUCTOR, cols+1);
  1863 + throw GException::mem_alloc(G_CONSTRUCTOR, cols+1);
1858 1864  
1859 1865 // Store (logical) matrix size
1860 1866 m_rows = rows;
... ... @@ -1863,11 +1869,11 @@ void GSparseMatrix::constructor(int rows, int cols, int elements)
1863 1869 // Initialise column start indices to 0
1864 1870 for (int col = 0; col <= m_cols; ++col)
1865 1871 m_colstart[col] = 0;
1866   -
  1872 +
1867 1873 // Optionally allocate elements
1868 1874 if (elements > 0)
1869 1875 alloc_elements(0, elements);
1870   -
  1876 +
1871 1877 // Return
1872 1878 return;
1873 1879 }
... ... @@ -1888,10 +1894,10 @@ void GSparseMatrix::init_members(void)
1888 1894 m_fill_col = 0;
1889 1895 m_symbolic = NULL;
1890 1896 m_numeric = NULL;
1891   -
  1897 +
1892 1898 // Initialise stack members
1893 1899 init_stack_members();
1894   -
  1900 +
1895 1901 // Return
1896 1902 return;
1897 1903 }
... ... @@ -1913,7 +1919,7 @@ void GSparseMatrix::init_stack_members(void)
1913 1919 m_stack_rowinx = NULL;
1914 1920 m_stack_work = NULL;
1915 1921 m_stack_buffer = NULL;
1916   -
  1922 +
1917 1923 // Return
1918 1924 return;
1919 1925 }
... ... @@ -1936,7 +1942,7 @@ void GSparseMatrix::copy_members(const GSparseMatrix&amp; m)
1936 1942 if (m.m_rowinx != NULL && m.m_alloc > 0) {
1937 1943 m_rowinx = new int[m.m_alloc];
1938 1944 if (m_rowinx == NULL)
1939   - throw GException::mem_alloc(G_COPY_MEMBERS, m.m_alloc);
  1945 + throw GException::mem_alloc(G_COPY_MEMBERS, m.m_alloc);
1940 1946 for (int i = 0; i < m.m_elements; ++i)
1941 1947 m_rowinx[i] = m.m_rowinx[i];
1942 1948 }
... ... @@ -1945,7 +1951,7 @@ void GSparseMatrix::copy_members(const GSparseMatrix&amp; m)
1945 1951 if (m.m_symbolic != NULL) {
1946 1952 GSparseSymbolic* symbolic = new GSparseSymbolic();
1947 1953 if (symbolic == NULL)
1948   - throw GException::mem_alloc(G_COPY_MEMBERS, 1);
  1954 + throw GException::mem_alloc(G_COPY_MEMBERS, 1);
1949 1955 *symbolic = *((GSparseSymbolic*)m.m_symbolic);
1950 1956 m_symbolic = (void*)symbolic;
1951 1957 }
... ... @@ -1954,11 +1960,11 @@ void GSparseMatrix::copy_members(const GSparseMatrix&amp; m)
1954 1960 if (m.m_numeric != NULL) {
1955 1961 GSparseNumeric* numeric = new GSparseNumeric();
1956 1962 if (numeric == NULL)
1957   - throw GException::mem_alloc(G_COPY_MEMBERS, 1);
  1963 + throw GException::mem_alloc(G_COPY_MEMBERS, 1);
1958 1964 *numeric = *((GSparseNumeric*)m.m_numeric);
1959 1965 m_numeric = (void*)numeric;
1960 1966 }
1961   -
  1967 +
1962 1968 // Return
1963 1969 return;
1964 1970 }
... ... @@ -1982,7 +1988,7 @@ void GSparseMatrix::free_members(void)
1982 1988  
1983 1989 // Free stack members
1984 1990 free_stack_members();
1985   -
  1991 +
1986 1992 // Return
1987 1993 return;
1988 1994 }
... ... @@ -2027,13 +2033,13 @@ int GSparseMatrix::get_index(int row, int col) const
2027 2033 {
2028 2034 // Initialise element to 'not found'
2029 2035 int index = -1;
2030   -
  2036 +
2031 2037 // If we have a pending element then check if this element is requested
2032 2038 if (m_fill_val != 0.0) {
2033 2039 if (row == m_fill_row && col == m_fill_col)
2034   - return m_elements;
  2040 + return m_elements;
2035 2041 }
2036   -
  2042 +
2037 2043 // If requested element is not the pending element then check if it exists
2038 2044 // in the matrix. Only if it is found its index is returned. Otherwise
2039 2045 // the default index is -1, signalling that the element is absent.
... ... @@ -2041,16 +2047,16 @@ int GSparseMatrix::get_index(int row, int col) const
2041 2047 int* ptr_colstart = m_colstart + col;
2042 2048 int i_start = *ptr_colstart++;
2043 2049 int i_stop = *ptr_colstart;
2044   - int* ptr_rowinx = m_rowinx + i_start;
  2050 + int* ptr_rowinx = m_rowinx + i_start;
2045 2051 for (int i = i_start; i < i_stop; ++i) {
2046   - int row_test = *ptr_rowinx++;
2047   - if (row_test == row) {
2048   - index = i;
2049   - break;
2050   - }
2051   - }
  2052 + int row_test = *ptr_rowinx++;
  2053 + if (row_test == row) {
  2054 + index = i;
  2055 + break;
  2056 + }
  2057 + }
2052 2058 }
2053   -
  2059 +
2054 2060 // Return index
2055 2061 return index;
2056 2062 }
... ... @@ -2074,45 +2080,45 @@ void GSparseMatrix::fill_pending(void)
2074 2080  
2075 2081 // Debugging
2076 2082 #if defined(G_DEBUG_SPARSE_PENDING) || defined(G_DEBUG_SPARSE_INSERTION)
2077   - cout << "GSparseMatrix::fill_pending(): pending value " <<
2078   - m_fill_val << " will be filled in location (" <<
2079   - m_fill_row << "," << m_fill_col << ")" << endl;
2080   - #endif
  2083 + cout << "GSparseMatrix::fill_pending(): pending value " <<
  2084 + m_fill_val << " will be filled in location (" <<
  2085 + m_fill_row << "," << m_fill_col << ")" << endl;
  2086 + #endif
2081 2087  
2082 2088 // If there are so far no elements in the matrix then append element ...
2083   - int inx_insert;
  2089 + int inx_insert;
2084 2090 if (m_elements == 0)
2085   - inx_insert = 0;
2086   -
2087   - // ... otherwise search for index to insert
2088   - else {
  2091 + inx_insert = 0;
  2092 +
  2093 + // ... otherwise search for index to insert
  2094 + else {
2089 2095 int* ptr_colstart = m_colstart + m_fill_col;
2090 2096 int i_start = *ptr_colstart++;
2091 2097 int i_stop = *ptr_colstart;
2092   - int* ptr_rowinx = m_rowinx + i_start;
  2098 + int* ptr_rowinx = m_rowinx + i_start;
2093 2099 for (inx_insert = i_start; inx_insert < i_stop; ++inx_insert) {
2094   - int row_test = *ptr_rowinx++;
2095   - if (row_test > m_fill_row) {
2096   - break;
2097   - }
2098   - }
2099   - }
2100   -
2101   - // Allocate memory for new element
2102   - alloc_elements(inx_insert, 1);
2103   -
2104   - // Insert element
2105   - m_data[inx_insert] = m_fill_val;
2106   - m_rowinx[inx_insert] = m_fill_row;
2107   -
2108   - // Update column start indices
2109   - for (int col = m_fill_col+1; col <= m_cols; ++col)
2110   - m_colstart[col] += 1;
2111   -
  2100 + int row_test = *ptr_rowinx++;
  2101 + if (row_test > m_fill_row) {
  2102 + break;
  2103 + }
  2104 + }
  2105 + }
  2106 +
  2107 + // Allocate memory for new element
  2108 + alloc_elements(inx_insert, 1);
  2109 +
  2110 + // Insert element
  2111 + m_data[inx_insert] = m_fill_val;
  2112 + m_rowinx[inx_insert] = m_fill_row;
  2113 +
  2114 + // Update column start indices
  2115 + for (int col = m_fill_col+1; col <= m_cols; ++col)
  2116 + m_colstart[col] += 1;
  2117 +
2112 2118 // Reset fill value
2113   - m_fill_val = 0.0;
2114   - m_fill_row = 0;
2115   - m_fill_col = 0;
  2119 + m_fill_val = 0.0;
  2120 + m_fill_row = 0;
  2121 + m_fill_col = 0;
2116 2122  
2117 2123 // Debugging: show sparse matrix after filling
2118 2124 #if defined(G_DEBUG_SPARSE_PENDING) || defined(G_DEBUG_SPARSE_INSERTION)
... ... @@ -2126,10 +2132,10 @@ void GSparseMatrix::fill_pending(void)
2126 2132 for (int i = 0; i < m_cols+1; ++i)
2127 2133 cout << m_colstart[i] << " ";
2128 2134 cout << endl;
2129   - #endif
  2135 + #endif
2130 2136  
2131 2137 } // endif: a pending matrix element was found
2132   -
  2138 +
2133 2139 }
2134 2140  
2135 2141  
... ... @@ -2150,99 +2156,99 @@ void GSparseMatrix::alloc_elements(int start, int num)
2150 2156 num << ")" << endl;
2151 2157 cout << " Before allocation : " << m_elements << " " << m_alloc << endl;
2152 2158 #endif
2153   -
  2159 +
2154 2160 // Continue only if we need memory
2155 2161 if (num > 0) {
2156   -
2157   - // If start is after the end the append memory
2158   - if (start > m_elements)
2159   - start = m_elements;
  2162 +
  2163 + // If start is after the end then append memory
  2164 + if (start > m_elements)
  2165 + start = m_elements;
2160 2166  
2161 2167 // Determine the requested new logical size of the matrix
2162   - int new_size = m_elements + num;
  2168 + int new_size = m_elements + num;
2163 2169  
2164 2170 // Case A: the requested memory is already available, so just move the
2165   - // data to make space for new elements and initialise the new cells
2166   - if (new_size <= m_alloc) {
2167   -
2168   - // Move up all elements after index to insert
2169   - #if defined(G_USE_MEMCPY)
2170   - int n_copy = m_elements - start;
2171   - memmove(&(m_data[start+num]), &(m_data[start]), sizeof(double)*n_copy);
2172   - memmove(&(m_rowinx[start+num]), &(m_rowinx[start]), sizeof(long)*n_copy);
2173   - #else
2174   - for (int i = m_elements - 1; i >= start; --i) {
2175   - m_data[i+num] = m_data[i];
2176   - m_rowinx[i+num] = m_rowinx[i];
2177   - }
2178   - #endif
2179   -
2180   - // Clear new elements (zero content for row 0)
2181   - for (int i = start; i < start+num; ++i) {
2182   - m_data[i] = 0.0;
2183   - m_rowinx[i] = 0;
2184   - }
2185   -
2186   - // Update element counter
2187   - m_elements += num;
2188   -
2189   - } // endif: Case A: memory already existed
2190   -
2191   - // Case B: more memory is needed, so allocate it, copy the existing
2192   - // content, and initialise new cells
2193   - else {
2194   -
2195   - // Make sure that enough memory is allocated
2196   - int new_propose = m_alloc + m_mem_block;
2197   - m_alloc = (new_size > new_propose) ? new_size : new_propose;
2198   -
2199   - // Allocate memory for new elements
2200   - double* new_data = new double[m_alloc];
2201   - int* new_rowinx = new int[m_alloc];
2202   - if (new_data == NULL || new_rowinx == NULL)
2203   - throw GException::mem_alloc(G_ALLOC, m_alloc);
  2171 + // data to make space for new elements and initialise the new cells
  2172 + if (new_size <= m_alloc) {
  2173 +
  2174 + // Move up all elements after index to insert
  2175 + #if defined(G_USE_MEMMOVE)
  2176 + int n_copy = m_elements - start;
  2177 + memmove(&(m_data[start+num]), &(m_data[start]), sizeof(double)*n_copy);
  2178 + memmove(&(m_rowinx[start+num]), &(m_rowinx[start]), sizeof(long)*n_copy);
  2179 + #else
  2180 + for (int i = m_elements - 1; i >= start; --i) {
  2181 + m_data[i+num] = m_data[i];
  2182 + m_rowinx[i+num] = m_rowinx[i];
  2183 + }
  2184 + #endif
  2185 +
  2186 + // Clear new elements (zero content for row 0)
  2187 + for (int i = start; i < start+num; ++i) {
  2188 + m_data[i] = 0.0;
  2189 + m_rowinx[i] = 0;
  2190 + }
  2191 +
  2192 + // Update element counter
  2193 + m_elements += num;
  2194 +
  2195 + } // endif: Case A: memory already existed
  2196 +
  2197 + // Case B: more memory is needed, so allocate it, copy the existing
  2198 + // content, and initialise new cells
  2199 + else {
  2200 +
  2201 + // Make sure that enough memory is allocated
  2202 + int new_propose = m_alloc + m_mem_block;
  2203 + m_alloc = (new_size > new_propose) ? new_size : new_propose;
  2204 +
  2205 + // Allocate memory for new elements
  2206 + double* new_data = new double[m_alloc];
  2207 + int* new_rowinx = new int[m_alloc];
  2208 + if (new_data == NULL || new_rowinx == NULL)
  2209 + throw GException::mem_alloc(G_ALLOC, m_alloc);
2204 2210  
2205 2211 // Copy all elements before index to insert
2206   - #if defined(G_USE_MEMCPY)
2207   - int n_copy = start;
2208   - memcpy(new_data, m_data, sizeof(double)*n_copy);
2209   - memcpy(new_rowinx, m_rowinx, sizeof(long)*n_copy);
2210   - #else
2211   - for (int i = 0; i < start; ++i) {
2212   - new_data[i] = m_data[i];
2213   - new_rowinx[i] = m_rowinx[i];
2214   - }
2215   - #endif
2216   -
2217   - // Clear new elements (zero content for row 0)
2218   - for (int i = start; i < start+num; ++i) {
2219   - new_data[i] = 0.0;
2220   - new_rowinx[i] = 0;
2221   - }
2222   -
2223   - // Copy all elements after index to insert
2224   - #if defined(G_USE_MEMCPY)
2225   - n_copy = m_elements - start;
2226   - memcpy(&(new_data[start+num]), &(m_data[start]), sizeof(double)*n_copy);
2227   - memcpy(&(new_rowinx[start+num]), &(m_rowinx[start]), sizeof(long)*n_copy);
2228   - #else
2229   - for (int i = start; i < m_elements; ++i) {
2230   - new_data[i+num] = m_data[i];
2231   - new_rowinx[i+num] = m_rowinx[i];
2232   - }
2233   - #endif
2234   -
  2212 + #if defined(G_USE_MEMCPY)
  2213 + int n_copy = start;
  2214 + memcpy(new_data, m_data, sizeof(double)*n_copy);
  2215 + memcpy(new_rowinx, m_rowinx, sizeof(long)*n_copy);
  2216 + #else
  2217 + for (int i = 0; i < start; ++i) {
  2218 + new_data[i] = m_data[i];
  2219 + new_rowinx[i] = m_rowinx[i];
  2220 + }
  2221 + #endif
  2222 +
  2223 + // Clear new elements (zero content for row 0)
  2224 + for (int i = start; i < start+num; ++i) {
  2225 + new_data[i] = 0.0;
  2226 + new_rowinx[i] = 0;
  2227 + }
  2228 +
  2229 + // Copy all elements after index to insert
  2230 + #if defined(G_USE_MEMCPY)
  2231 + n_copy = m_elements - start;
  2232 + memcpy(&(new_data[start+num]), &(m_data[start]), sizeof(double)*n_copy);
  2233 + memcpy(&(new_rowinx[start+num]), &(m_rowinx[start]), sizeof(long)*n_copy);
  2234 + #else
  2235 + for (int i = start; i < m_elements; ++i) {
  2236 + new_data[i+num] = m_data[i];
  2237 + new_rowinx[i+num] = m_rowinx[i];
  2238 + }
  2239 + #endif
  2240 +
2235 2241 // Delete old memory
2236 2242 if (m_data != NULL) delete [] m_data;
2237 2243 if (m_rowinx != NULL) delete [] m_rowinx;
2238   -
2239   - // Update pointers to new memory and update element counter
2240   - m_data = new_data;
2241   - m_rowinx = new_rowinx;
2242   - m_elements += num;
2243   -
2244   - } // endelse: Case B: more memory was needed
2245   -
  2244 +
  2245 + // Update pointers to new memory and update element counter
  2246 + m_data = new_data;
  2247 + m_rowinx = new_rowinx;
  2248 + m_elements += num;
  2249 +
  2250 + } // endelse: Case B: more memory was needed
  2251 +
2246 2252 } // endif: needed new memory
2247 2253  
2248 2254 // Dump new memory size
... ... @@ -2275,90 +2281,90 @@ void GSparseMatrix::free_elements(int start, int num)
2275 2281 if (num > 0 && start < m_elements) {
2276 2282  
2277 2283 // Determine the requested new logical size of the matrix
2278   - int new_size = m_elements - num;
  2284 + int new_size = m_elements - num;
2279 2285  
2280 2286 // If there are no elements then simply delete all matrix elements ...
2281   - if (new_size < 1) {
  2287 + if (new_size < 1) {
2282 2288 if (m_data != NULL) delete [] m_data;
2283 2289 if (m_rowinx != NULL) delete [] m_rowinx;
2284   - m_data = NULL;
2285   - m_rowinx = NULL;
2286   - m_elements = 0;
2287   - m_alloc = 0;
2288   - }
2289   -
2290   - // ... otherwise shrink the array
2291   - else {
2292   -
2293   - // Case A: If at least one entire memory block has been liberated then
2294   - // physically shrink the matrix array
2295   - if (m_alloc - new_size > m_mem_block) {
2296   -
2297   - // Shrink, but leave a memory block for possible future filling
2298   - m_alloc = new_size + m_mem_block;
2299   -
2300   - // Allocate new memory
2301   - double* new_data = new double[m_alloc];
2302   - int* new_rowinx = new int[m_alloc];
2303   - if (new_data == NULL || new_rowinx == NULL)
2304   - throw GException::mem_alloc(G_FREE, m_alloc);
2305   -
2306   - // Copy all elements before the starting index
2307   - #if defined(G_USE_MEMCPY)
2308   - int n_copy = start;
2309   - memcpy(new_data, m_data, sizeof(double)*n_copy);
2310   - memcpy(new_rowinx, m_rowinx, sizeof(long)*n_copy);
2311   - #else
2312   - for (int i = 0; i < start; ++i) {
2313   - new_data[i] = m_data[i];
2314   - new_rowinx[i] = m_rowinx[i];
2315   - }
2316   - #endif
2317   -
2318   - // Copy all elements after the starting index
2319   - #if defined(G_USE_MEMCPY)
2320   - n_copy = new_size - start;
2321   - memcpy(&(new_data[start]), &(m_data[start+num]), sizeof(double)*n_copy);
2322   - memcpy(&(new_rowinx[start]), &(m_rowinx[start+num]), sizeof(long)*n_copy);
2323   - #else
2324   - for (int i = start; i < new_size; ++i) {
2325   - new_data[i] = m_data[i+num];
2326   - new_rowinx[i] = m_rowinx[i+num];
2327   - }
2328   - #endif
2329   -
  2290 + m_data = NULL;
  2291 + m_rowinx = NULL;
  2292 + m_elements = 0;
  2293 + m_alloc = 0;
  2294 + }
  2295 +
  2296 + // ... otherwise shrink the array
  2297 + else {
  2298 +
  2299 + // Case A: If at least one entire memory block has been liberated then
  2300 + // physically shrink the matrix array
  2301 + if (m_alloc - new_size > m_mem_block) {
  2302 +
  2303 + // Shrink, but leave a memory block for possible future filling
  2304 + m_alloc = new_size + m_mem_block;
  2305 +
  2306 + // Allocate new memory
  2307 + double* new_data = new double[m_alloc];
  2308 + int* new_rowinx = new int[m_alloc];
  2309 + if (new_data == NULL || new_rowinx == NULL)
  2310 + throw GException::mem_alloc(G_FREE, m_alloc);
  2311 +
  2312 + // Copy all elements before the starting index
  2313 + #if defined(G_USE_MEMCPY)
  2314 + int n_copy = start;
  2315 + memcpy(new_data, m_data, sizeof(double)*n_copy);
  2316 + memcpy(new_rowinx, m_rowinx, sizeof(long)*n_copy);
  2317 + #else
  2318 + for (int i = 0; i < start; ++i) {
  2319 + new_data[i] = m_data[i];
  2320 + new_rowinx[i] = m_rowinx[i];
  2321 + }
  2322 + #endif
  2323 +
  2324 + // Copy all elements after the starting index
  2325 + #if defined(G_USE_MEMCPY)
  2326 + n_copy = new_size - start;
  2327 + memcpy(&(new_data[start]), &(m_data[start+num]), sizeof(double)*n_copy);
  2328 + memcpy(&(new_rowinx[start]), &(m_rowinx[start+num]), sizeof(long)*n_copy);
  2329 + #else
  2330 + for (int i = start; i < new_size; ++i) {
  2331 + new_data[i] = m_data[i+num];
  2332 + new_rowinx[i] = m_rowinx[i+num];
  2333 + }
  2334 + #endif
  2335 +
2330 2336 // Delete old memory
2331 2337 if (m_data != NULL) delete [] m_data;
2332 2338 if (m_rowinx != NULL) delete [] m_rowinx;
2333   -
2334   - // Update pointers to new memory and update element counter
2335   - m_data = new_data;
2336   - m_rowinx = new_rowinx;
2337   - m_elements = new_size;
2338   -
2339   - } // endif: Case A: memory shrinkage performed
2340   -
2341   - // Case B: we keep the memory and just move the elements
2342   - else {
2343   -
2344   - // Move all elements after the starting index
2345   - #if defined(G_USE_MEMCPY)
2346   - int n_copy = new_size - start;
2347   - memmove(&(m_data[start]), &(m_data[start+num]), sizeof(double)*n_copy);
2348   - memmove(&(m_rowinx[start]), &(m_rowinx[start+num]), sizeof(long)*n_copy);
2349   - #else
2350   - for (int i = start; i < new_size; ++i) {
2351   - m_data[i] = m_data[i+num];
2352   - m_rowinx[i] = m_rowinx[i+num];
2353   - }
2354   - #endif
2355   -
2356   - // Update element counter
2357   - m_elements = new_size;
2358   -
2359   - } // endelse: Case B
2360   -
2361   - } // endif: array shrinkage needed
  2339 +
  2340 + // Update pointers to new memory and update element counter
  2341 + m_data = new_data;
  2342 + m_rowinx = new_rowinx;
  2343 + m_elements = new_size;
  2344 +
  2345 + } // endif: Case A: memory shrinkage performed
  2346 +
  2347 + // Case B: we keep the memory and just move the elements
  2348 + else {
  2349 +
  2350 + // Move all elements after the starting index
  2351 + #if defined(G_USE_MEMMOVE)
  2352 + int n_copy = new_size - start;
  2353 + memmove(&(m_data[start]), &(m_data[start+num]), sizeof(double)*n_copy);
  2354 + memmove(&(m_rowinx[start]), &(m_rowinx[start+num]), sizeof(long)*n_copy);
  2355 + #else
  2356 + for (int i = start; i < new_size; ++i) {
  2357 + m_data[i] = m_data[i+num];
  2358 + m_rowinx[i] = m_rowinx[i+num];
  2359 + }
  2360 + #endif
  2361 +
  2362 + // Update element counter
  2363 + m_elements = new_size;
  2364 +
  2365 + } // endelse: Case B
  2366 +
  2367 + } // endif: array shrinkage needed
2362 2368 } // endif: needed new memory
2363 2369  
2364 2370 // Return
... ... @@ -2386,7 +2392,7 @@ void GSparseMatrix::remove_zero_row_col(void)
2386 2392  
2387 2393 // Select non-zero rows and columns of matrix
2388 2394 select_non_zero();
2389   -
  2395 +
2390 2396 // Stop if there is no compression
2391 2397 if (m_rows == m_num_rowsel && m_cols == m_num_colsel)
2392 2398 return;
... ... @@ -2399,18 +2405,18 @@ void GSparseMatrix::remove_zero_row_col(void)
2399 2405 int* row_map = new int[m_rows];
2400 2406 if (row_map == NULL)
2401 2407 throw GException::mem_alloc(G_REMOVE_ZERO, m_rows);
2402   -
  2408 +
2403 2409 // Setup row mapping array that maps original matrix rows into compressed
2404 2410 // matrix rows. An entry of -1 indicates that the row should be dropped
2405 2411 for (int row = 0; row < m_rows; ++row)
2406 2412 row_map[row] = -1;
2407 2413 for (int c_row = 0; c_row < m_num_rowsel; ++c_row)
2408 2414 row_map[m_rowsel[c_row]] = c_row;
2409   -
  2415 +
2410 2416 // Initialise pointers to compressed array
2411 2417 double* d_data = m_data;
2412 2418 int* d_rowinx = m_rowinx;
2413   -
  2419 +
2414 2420 // Initialise column start of first column to zero
2415 2421 m_colstart[0] = 0;
2416 2422  
... ... @@ -2424,27 +2430,27 @@ void GSparseMatrix::remove_zero_row_col(void)
2424 2430  
2425 2431 // Loop over all columns of compressed matrix
2426 2432 for (int c_col = 0; c_col < m_num_colsel; ++c_col) {
2427   -
2428   - // Get index range for elements in original matrix
2429   - int i_start = m_colstart[m_colsel[c_col]];
2430   - int i_stop = m_colstart[m_colsel[c_col]+1];
2431   -
2432   - // Initialise number of element counter for the compressed column
2433   - int num = 0;
2434   -
2435   - // Loop over all elements in original column
2436   - int c_row;
2437   - for (int i = i_start; i < i_stop; ++i) {
2438   - if ((c_row = row_map[m_rowinx[i]]) >= 0) {
2439   - *d_data++ = m_data[i];
2440   - *d_rowinx++ = c_row;
2441   - num++;
2442   - }
2443   - }
2444   -
2445   - // Update column stop
2446   - m_colstart[c_col+1] = m_colstart[c_col] + num;
2447   -
  2433 +
  2434 + // Get index range for elements in original matrix
  2435 + int i_start = m_colstart[m_colsel[c_col]];
  2436 + int i_stop = m_colstart[m_colsel[c_col]+1];
  2437 +
  2438 + // Initialise number of element counter for the compressed column
  2439 + int num = 0;
  2440 +
  2441 + // Loop over all elements in original column
  2442 + int c_row;
  2443 + for (int i = i_start; i < i_stop; ++i) {
  2444 + if ((c_row = row_map[m_rowinx[i]]) >= 0) {
  2445 + *d_data++ = m_data[i];
  2446 + *d_rowinx++ = c_row;
  2447 + num++;
  2448 + }
  2449 + }
  2450 +
  2451 + // Update column stop
  2452 + m_colstart[c_col+1] = m_colstart[c_col] + num;
  2453 +
2448 2454 } // endfor: looped over all columns of compressed matrix
2449 2455  
2450 2456 // Dump column start array
... ... @@ -2457,11 +2463,11 @@ void GSparseMatrix::remove_zero_row_col(void)
2457 2463  
2458 2464 // Free row mapping array
2459 2465 delete [] row_map;
2460   -
  2466 +
2461 2467 // Update matrix size
2462 2468 m_rows = m_num_rowsel;
2463 2469 m_cols = m_num_colsel;
2464   -
  2470 +
2465 2471 // Return
2466 2472 return;
2467 2473 }
... ... @@ -2488,11 +2494,11 @@ void GSparseMatrix::insert_zero_row_col(int rows, int cols)
2488 2494 // Stop if there is no insertion
2489 2495 if (m_rows == rows && m_cols == cols)
2490 2496 return;
2491   -
  2497 +
2492 2498 // If row selection exists then restore row indices
2493 2499 if (m_rowsel != NULL) {
2494 2500 for (int i = 0; i < m_elements; ++i)
2495   - m_rowinx[i] = m_rowsel[m_rowinx[i]];
  2501 + m_rowinx[i] = m_rowsel[m_rowinx[i]];
2496 2502 }
2497 2503  
2498 2504 // Dump column start array
... ... @@ -2502,28 +2508,28 @@ void GSparseMatrix::insert_zero_row_col(int rows, int cols)
2502 2508 cout << " " << m_colstart[c_col];
2503 2509 cout << endl;
2504 2510 #endif
2505   -
  2511 +
2506 2512 // If column selection exists then restore column counters
2507 2513 if (m_colsel != NULL) {
2508   -
  2514 +
2509 2515 // Start insertion from the last original column
2510 2516 int col_stop = cols - 1;
2511   -
2512   - // Loop over all compressed columns
  2517 +
  2518 + // Loop over all compressed columns
2513 2519 for (int c_col = m_num_colsel-1; c_col > 0; --c_col) {
2514   - int col_start = m_colsel[c_col-1] + 1;
2515   - int col_value = m_colstart[c_col];
2516   - for (int col = col_start; col <= col_stop; ++col)
2517   - m_colstart[col] = col_value;
2518   - col_stop = col_start - 1;
2519   - }
2520   -
2521   - // Set first columns if they are not yet set
2522   - for (int col = 0; col <= col_stop; ++col)
2523   - m_colstart[col] = 0;
2524   -
2525   - // Restore the number of elements
2526   - m_colstart[cols] = m_elements;
  2520 + int col_start = m_colsel[c_col-1] + 1;
  2521 + int col_value = m_colstart[c_col];
  2522 + for (int col = col_start; col <= col_stop; ++col)
  2523 + m_colstart[col] = col_value;
  2524 + col_stop = col_start - 1;
  2525 + }
  2526 +
  2527 + // Set first columns if they are not yet set
  2528 + for (int col = 0; col <= col_stop; ++col)
  2529 + m_colstart[col] = 0;
  2530 +
  2531 + // Restore the number of elements
  2532 + m_colstart[cols] = m_elements;
2527 2533 }
2528 2534  
2529 2535 // Dump column start array
... ... @@ -2532,12 +2538,12 @@ void GSparseMatrix::insert_zero_row_col(int rows, int cols)
2532 2538 for (int col = 0; col <= cols; ++col)
2533 2539 cout << " " << m_colstart[col];
2534 2540 cout << endl;
2535   - #endif
  2541 + #endif
2536 2542  
2537 2543 // Update matrix size
2538 2544 m_rows = rows;
2539 2545 m_cols = cols;
2540   -
  2546 +
2541 2547 // Return
2542 2548 return;
2543 2549 }
... ... @@ -2557,41 +2563,41 @@ void GSparseMatrix::insert_zero_row_col(int rows, int cols)
2557 2563 ***************************************************************************/
2558 2564 void GSparseMatrix::mix_column_prepare(const int* src1_row, int src1_num,
2559 2565 const int* src2_row, int src2_num,
2560   - int* num_1, int* num_2, int* num_mix)
  2566 + int* num_1, int* num_2, int* num_mix)
2561 2567 {
2562 2568 // Initialise element counters
2563 2569 *num_1 = 0;
2564 2570 *num_2 = 0;
2565 2571 *num_mix = 0;
2566   -
  2572 +
2567 2573 // Initialise indices and row indices of both columns
2568 2574 int inx_1 = 0; // Column 1 element index
2569 2575 int inx_2 = 0; // Column 2 element index
2570 2576 int row_1 = src1_row[inx_1]; // Column 1 first row index
2571 2577 int row_2 = src2_row[inx_2]; // Column 2 first row index
2572   -
  2578 +
2573 2579 // Mix elements of both columns while both contain still elements
2574 2580 while (inx_1 < src1_num && inx_2 < src2_num) {
2575   -
  2581 +
2576 2582 // Case A: the element exist in both columns
2577   - if (row_1 == row_2) {
  2583 + if (row_1 == row_2) {
2578 2584 row_1 = src1_row[++inx_1];
2579 2585 row_2 = src2_row[++inx_2];
2580   - (*num_mix)++;
2581   - }
2582   -
2583   - // Case B: the element exists only in first column
2584   - else if (row_1 < row_2) {
  2586 + (*num_mix)++;
  2587 + }
  2588 +
  2589 + // Case B: the element exists only in first column
  2590 + else if (row_1 < row_2) {
2585 2591 row_1 = src1_row[++inx_1];
2586   - (*num_1)++;
  2592 + (*num_1)++;
2587 2593 }
2588   -
2589   - // Case C: the element exists only in second column
2590   - else {
  2594 +
  2595 + // Case C: the element exists only in second column
  2596 + else {
2591 2597 row_2 = src2_row[++inx_2];
2592   - (*num_2)++;
  2598 + (*num_2)++;
2593 2599 }
2594   -
  2600 +
2595 2601 } // endwhile: mixing
2596 2602  
2597 2603 // At this point either the first or the second column expired of elements
... ... @@ -2599,7 +2605,7 @@ void GSparseMatrix::mix_column_prepare(const int* src1_row, int src1_num,
2599 2605 // count them now ...
2600 2606 if (inx_1 < src1_num)
2601 2607 *num_1 += (src1_num - inx_1);
2602   -
  2608 +
2603 2609 // ... or in the case that there are still elements remaining in the second
2604 2610 // column we count them now
2605 2611 if (inx_2 < src2_num)
... ... @@ -2628,7 +2634,7 @@ void GSparseMatrix::mix_column(const double* src1_data, const int* src1_row,
2628 2634 int src1_num,
2629 2635 const double* src2_data, const int* src2_row,
2630 2636 int src2_num,
2631   - double* dst_data, int* dst_row, int* dst_num)
  2637 + double* dst_data, int* dst_row, int* dst_num)
2632 2638 {
2633 2639 // Initialise indices and row indices of both columns
2634 2640 int inx_1 = 0; // Column 1 element index
... ... @@ -2636,36 +2642,36 @@ void GSparseMatrix::mix_column(const double* src1_data, const int* src1_row,
2636 2642 int inx = 0; // Result column element index
2637 2643 int row_1 = src1_row[inx_1];
2638 2644 int row_2 = src2_row[inx_2];
2639   -
  2645 +
2640 2646 // Mix elements of both columns while both contain still elements
2641 2647 while (inx_1 < src1_num && inx_2 < src2_num) {
2642   -
  2648 +
2643 2649 // Case A: the element exists in both columns, so we add up the values
2644   - if (row_1 == row_2) {
2645   - dst_data[inx] = src1_data[inx_1] + src2_data[inx_2];
2646   - dst_row[inx] = row_1;
  2650 + if (row_1 == row_2) {
  2651 + dst_data[inx] = src1_data[inx_1] + src2_data[inx_2];
  2652 + dst_row[inx] = row_1;
2647 2653 row_1 = src1_row[++inx_1];
2648 2654 row_2 = src2_row[++inx_2];
2649   - }
2650   -
2651   - // Case B: the element exists only in first column, so we copy the element
2652   - // from the first column
2653   - else if (row_1 < row_2) {
2654   - dst_data[inx] = src1_data[inx_1];
2655   - dst_row[inx] = row_1;
  2655 + }
  2656 +
  2657 + // Case B: the element exists only in first column, so we copy the element
  2658 + // from the first column
  2659 + else if (row_1 < row_2) {
  2660 + dst_data[inx] = src1_data[inx_1];
  2661 + dst_row[inx] = row_1;
2656 2662 row_1 = src1_row[++inx_1];
2657 2663 }
2658   -
2659   - // Case C: the element exists only in second column, so we copy the element
2660   - // from the second column
2661   - else {
2662   - dst_data[inx] = src2_data[inx_2];
2663   - dst_row[inx] = row_2;
  2664 +
  2665 + // Case C: the element exists only in second column, so we copy the element
  2666 + // from the second column
  2667 + else {
  2668 + dst_data[inx] = src2_data[inx_2];
  2669 + dst_row[inx] = row_2;
2664 2670 row_2 = src2_row[++inx_2];
2665 2671 }
2666   -
2667   - // Update the destination index since we added a element
2668   - inx++;
  2672 +
  2673 + // Update the destination index since we added a element
  2674 + inx++;
2669 2675  
2670 2676 } // endwhile: mixing
2671 2677  
... ... @@ -2673,20 +2679,20 @@ void GSparseMatrix::mix_column(const double* src1_data, const int* src1_row,
2673 2679 // In the case that there are still elements remaining in the first column we
2674 2680 // add them now ...
2675 2681 for (int i = inx_1; i < src1_num; ++i, ++inx) {
2676   - dst_data[inx] = src1_data[i];
2677   - dst_row[inx] = src1_row[i];
  2682 + dst_data[inx] = src1_data[i];
  2683 + dst_row[inx] = src1_row[i];
2678 2684 }
2679   -
  2685 +
2680 2686 // ... or in the case that there are still elements remaining in the second
2681 2687 // column we add them now
2682 2688 for (int i = inx_2; i < src2_num; ++i, ++inx) {
2683   - dst_data[inx] = src2_data[i];
2684   - dst_row[inx] = src2_row[i];
  2689 + dst_data[inx] = src2_data[i];
  2690 + dst_row[inx] = src2_row[i];
2685 2691 }
2686   -
  2692 +
2687 2693 // Now store the number of columns in the second column
2688 2694 *dst_num = inx;
2689   -
  2695 +
2690 2696 // We're done
2691 2697 return;
2692 2698 }
... ... @@ -2702,46 +2708,46 @@ void GSparseMatrix::mix_column(const double* src1_data, const int* src1_row,
2702 2708 * Output operator *
2703 2709 * ----------------------------------------------------------------------- *
2704 2710 ***************************************************************************/
2705   -std::ostream& operator<< (std::ostream& os, const GSparseMatrix& m)
  2711 +ostream& operator<< (ostream& os, const GSparseMatrix& m)
2706 2712 {
2707 2713 // Put header in stream
2708   - os << "=== GSparseMatrix ===" << std::endl;
  2714 + os << "=== GSparseMatrix ===" << endl;
2709 2715 if (m.m_rowsel != NULL)
2710 2716 os << " Number of rows ............: " << m.m_rows << " (compressed " <<
2711   - m.m_num_rowsel << ")" << std::endl;
  2717 + m.m_num_rowsel << ")" << endl;
2712 2718 else
2713   - os << " Number of rows ............: " << m.m_rows << std::endl;
  2719 + os << " Number of rows ............: " << m.m_rows << endl;
2714 2720 if (m.m_colsel != NULL)
2715 2721 os << " Number of columns .........: " << m.m_cols << " (compressed " <<
2716   - m.m_num_colsel << ")" << std::endl;
  2722 + m.m_num_colsel << ")" << endl;
2717 2723 else
2718   - os << " Number of columns .........: " << m.m_cols << std::endl;
  2724 + os << " Number of columns .........: " << m.m_cols << endl;
2719 2725 if (m.m_fill_val == 0.0)
2720 2726 os << " Number of non-zero elements: " << m.m_colstart[m.m_cols] << " (" <<
2721   - m.m_elements << ")" << std::endl;
  2727 + m.m_elements << ")" << endl;
2722 2728 else {
2723 2729 os << " Number of non-zero elements: " << m.m_colstart[m.m_cols]+1 << " (" <<
2724   - m.m_elements+1 << ")" << std::endl;
  2730 + m.m_elements+1 << ")" << endl;
2725 2731 os << " Pending element ...........: (" << m.m_fill_row << "," << m.m_fill_col <<
2726   - ")=" << m.m_fill_val << std::endl;
  2732 + ")=" << m.m_fill_val << endl;
2727 2733 }
2728   - os << " Number of allocated cells .: " << m.m_alloc << std::endl;
2729   - os << " Memory block size .........: " << m.m_mem_block << std::endl;
2730   - os << " Sparse matrix fill ........: " << m.fill() << std::endl;
  2734 + os << " Number of allocated cells .: " << m.m_alloc << endl;
  2735 + os << " Memory block size .........: " << m.m_mem_block << endl;
  2736 + os << " Sparse matrix fill ........: " << m.fill() << endl;
2731 2737  
2732 2738 // Dump elements and compression schemes
2733 2739 m.dump_elements(os);
2734 2740 m.dump_row_comp(os);
2735 2741 m.dump_col_comp(os);
2736   -
  2742 +
2737 2743 // If there is a symbolic decomposition then put it also in the stream
2738 2744 if (m.m_symbolic != NULL) {
2739   - os << std::endl << *((GSparseSymbolic*)m.m_symbolic);
  2745 + os << endl << *((GSparseSymbolic*)m.m_symbolic);
2740 2746 }
2741 2747  
2742 2748 // If there is a numeric decomposition then put it also in the stream
2743 2749 if (m.m_numeric != NULL) {
2744   - os << std::endl << *((GSparseNumeric*)m.m_numeric);
  2750 + os << endl << *((GSparseNumeric*)m.m_numeric);
2745 2751 }
2746 2752  
2747 2753 // Return output stream
... ... @@ -2757,14 +2763,14 @@ GSparseMatrix fabs(const GSparseMatrix&amp; m)
2757 2763 {
2758 2764 // Define result matrix
2759 2765 GSparseMatrix result = m;
2760   -
  2766 +
2761 2767 // Fill pending element
2762 2768 result.fill_pending();
2763   -
  2769 +
2764 2770 // Convert all elements to absolute values
2765 2771 for (int i = 0; i < result.m_elements; ++i)
2766 2772 result.m_data[i] = fabs(result.m_data[i]);
2767   -
  2773 +
2768 2774 // Return result
2769 2775 return result;
2770 2776 }
... ... @@ -2789,7 +2795,7 @@ GSparseMatrix cs_symperm(const GSparseMatrix&amp; m, const int* pinv)
2789 2795 int* Ap = m.m_colstart;
2790 2796 int* Ai = m.m_rowinx;
2791 2797 double* Ax = m.m_data;
2792   -
  2798 +
2793 2799 // Allocate result matrix
2794 2800 GSparseMatrix C(n, n, Ap[n]);
2795 2801  
... ... @@ -2797,49 +2803,49 @@ GSparseMatrix cs_symperm(const GSparseMatrix&amp; m, const int* pinv)
2797 2803 int wrk_size = n;
2798 2804 int* wrk_int = new int[wrk_size];
2799 2805 if (wrk_int == NULL)
2800   - throw GException::mem_alloc(G_SYMPERM, wrk_size);
  2806 + throw GException::mem_alloc(G_SYMPERM, wrk_size);
2801 2807 for (i = 0; i < wrk_size; ++i)
2802 2808 wrk_int[i] = 0;
2803 2809  
2804   - // Assign result matrix attributes
  2810 + // Assign result matrix attributes
2805 2811 int* Cp = C.m_colstart;
2806 2812 int* Ci = C.m_rowinx;
2807 2813 double* Cx = C.m_data;
2808 2814  
2809 2815 // Count entries in each column of C
2810 2816 for (j = 0; j < n; j++) {
2811   -
  2817 +
2812 2818 // Column j of A is column j2 of C
2813   - j2 = pinv ? pinv[j] : j;
2814   -
2815   - // Loop over entries in column j
2816   - for (p = Ap[j]; p < Ap[j+1]; p++) {
  2819 + j2 = pinv ? pinv[j] : j;
  2820 +
  2821 + // Loop over entries in column j
  2822 + for (p = Ap[j]; p < Ap[j+1]; p++) {
2817 2823 i = Ai [p];
2818 2824 if (i > j) continue; // skip lower triangular part of A
2819 2825 i2 = pinv ? pinv[i] : i; // row i of A is row i2 of C
2820   - wrk_int[G_MAX(i2, j2)]++; // column count of C
2821   - }
  2826 + wrk_int[G_MAX(i2, j2)]++; // column count of C
  2827 + }
2822 2828 }
2823   -
  2829 +
2824 2830 // Compute column pointers of C
2825 2831 cs_cumsum(Cp, wrk_int, n);
2826   -
  2832 +
2827 2833 // Loop over all columns of A
2828 2834 for (j = 0 ; j < n ; j++) {
2829   -
  2835 +
2830 2836 // Column j of A is column j2 of C
2831   - j2 = pinv ? pinv[j] : j;
2832   -
2833   - // Loop over entries in column j
2834   - for (p = Ap[j]; p < Ap[j+1]; p++) {
  2837 + j2 = pinv ? pinv[j] : j;
  2838 +
  2839 + // Loop over entries in column j
  2840 + for (p = Ap[j]; p < Ap[j+1]; p++) {
2835 2841 i = Ai [p] ;
2836 2842 if (i > j) continue; // skip lower triangular part of A
2837   - i2 = pinv ? pinv[i] : i; // row i of A is row i2 of C
  2843 + i2 = pinv ? pinv[i] : i; // row i of A is row i2 of C
2838 2844 Ci[q = wrk_int[G_MAX(i2,j2)]++] = G_MIN(i2,j2);
2839 2845 if (Cx) Cx[q] = Ax[p];
2840   - }
  2846 + }
2841 2847 }
2842   -
  2848 +
2843 2849 // Free workspace
2844 2850 delete [] wrk_int;
2845 2851  
... ... @@ -2871,14 +2877,14 @@ GSparseMatrix cs_transpose(const GSparseMatrix&amp; m, int values)
2871 2877 int wrk_size = m.m_rows;
2872 2878 int* wrk_int = new int[wrk_size];
2873 2879 if (wrk_int == NULL)
2874   - throw GException::mem_alloc(G_TRANSPOSE, wrk_size);
  2880 + throw GException::mem_alloc(G_TRANSPOSE, wrk_size);
2875 2881 for (int i = 0; i < wrk_size; i++)
2876 2882 wrk_int[i] = 0;
2877 2883  
2878 2884 // Setup the number of non-zero elements in each row
2879 2885 for (int p = 0; p < m.m_elements; p++)
2880 2886 wrk_int[m.m_rowinx[p]]++;
2881   -
  2887 +
2882 2888 // Set row pointers. To use a GSparseSymbolic function we have to
2883 2889 // allocate and object (but this does not take memory)
2884 2890 cs_cumsum(result.m_colstart, wrk_int, m.m_rows);
... ... @@ -2886,25 +2892,25 @@ GSparseMatrix cs_transpose(const GSparseMatrix&amp; m, int values)
2886 2892 // Case A: Normal transponse, including assignment of values
2887 2893 if (values) {
2888 2894 for (int col = 0; col < m.m_cols; col++) {
2889   - for (int p = m.m_colstart[col] ; p < m.m_colstart[col+1] ; p++) {
2890   - int i = wrk_int[m.m_rowinx[p]]++;
2891   - result.m_rowinx[i] = col;
2892   - result.m_data[i] = m.m_data[p] ;
2893   - }
  2895 + for (int p = m.m_colstart[col] ; p < m.m_colstart[col+1] ; p++) {
  2896 + int i = wrk_int[m.m_rowinx[p]]++;
  2897 + result.m_rowinx[i] = col;
  2898 + result.m_data[i] = m.m_data[p] ;
  2899 + }
2894 2900 }
2895 2901 }
2896   -
  2902 +
2897 2903 // Case B: Logical transponse, no assignment of values is performed
2898 2904 else {
2899 2905 for (int col = 0; col < m.m_cols; col++) {
2900   - for (int p = m.m_colstart[col] ; p < m.m_colstart[col+1] ; p++)
2901   - result.m_rowinx[wrk_int[m.m_rowinx[p]]++] = col;
  2906 + for (int p = m.m_colstart[col] ; p < m.m_colstart[col+1] ; p++)
  2907 + result.m_rowinx[wrk_int[m.m_rowinx[p]]++] = col;
2902 2908 }
2903 2909 }
2904   -
  2910 +
2905 2911 // Return transponse matrix
2906 2912 return result;
2907   -
  2913 +
2908 2914 }
2909 2915  
2910 2916  
... ... @@ -2928,20 +2934,20 @@ double cs_cumsum(int* p, int* c, int n)
2928 2934 {
2929 2935 // Signal error if one of the input pointers is NULL
2930 2936 if (!p || !c) return (-1);
2931   -
  2937 +
2932 2938 // Initialise sums (integer and double)
2933 2939 int nz = 0;
2934 2940 double nz2 = 0.0;
2935   -
  2941 +
2936 2942 // Evaluate p[0..n] = cumulative sum of c[0..n-1]
2937 2943 for (int i = 0; i < n; ++i) {
2938   - p[i] = nz ;
2939   - nz += c[i];
2940   - nz2 += c[i]; // also in double to avoid int overflow
2941   - c[i] = p[i]; // also copy p[0..n-1] back into c[0..n-1]
  2944 + p[i] = nz ;
  2945 + nz += c[i];
  2946 + nz2 += c[i]; // also in double to avoid int overflow
  2947 + c[i] = p[i]; // also copy p[0..n-1] back into c[0..n-1]
2942 2948 }
2943 2949 p[n] = nz ;
2944   -
  2950 +
2945 2951 // Return cumulative sum of c[0..n-1]
2946 2952 return nz2;
2947 2953 }
... ...