ARTS  2.0.49
matpackII.cc
Go to the documentation of this file.
1 /* Copyright (C) 2001-2008
2  Stefan Buehler <sbuehler@ltu.se>
3  Mattias Ekstroem <ekstrom@rss.chalmers.se>
4 
5  This program is free software; you can redistribute it and/or modify it
6  under the terms of the GNU General Public License as published by the
7  Free Software Foundation; either version 2, or (at your option) any
8  later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program; if not, write to the Free Software
17  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
18  USA. */
19 
40 // #include <vector>
41 #include <algorithm>
42 #include <set>
43 #include <iostream> // For debugging.
44 #include <cmath>
45 #include <iterator>
46 #include "matpackII.h"
47 
48 
49 // Simple member Functions
50 // ----------------
51 
54 {
55  return mrr;
56 }
57 
60 {
61  return mcr;
62 }
63 
66 {
67  return *(mcolptr->end()-1);
68 }
69 
70 // Index Operators
71 // ---------------
72 
74 
91 {
92  // Check if indices are valid:
93  assert( 0<=r );
94  assert( 0<=c );
95  assert( r<mrr );
96  assert( c<mcr );
97 
98  // Get index of first data element of this column:
99  Index i = (*mcolptr)[c];
100 
101  // Get index of first data element of next column. (This always works,
102  // because mcolptr has one extra element pointing behind the last
103  // column.)
104  const Index end = (*mcolptr)[c+1];
105 
106  // See if we find an element with the right row index in this
107  // range. We assume that the elements are sorted by ascending row
108  // index. We use the index i as the loop counter, which we have
109  // initialized above.
110  for ( ; i<end; ++i )
111  {
112  Index rowi = (*mrowind)[i];
113  if ( r < rowi )
114  break;
115  if ( r == rowi )
116  return (*mdata)[i];
117  }
118 
119  // If we are here, then the requested data element does not yet
120  // exist.
121 
122  // We have to adjust the array of column pointers. The values
123  // in all columns above the current one have to be increased by 1.
124  for ( vector<Index>::iterator j = mcolptr->begin() + c + 1;
125  j < mcolptr->end();
126  ++j )
127  ++(*j);
128 
129  // We have to insert the new element in *mrowind and *mdata just one
130  // position before the index i. We can use insert to achieve
131  // this. Because they return an iterator to the newly inserted
132  // element, we can return directly from the second call.
133  mrowind->insert( mrowind->begin()+i, r );
134  return *( mdata->insert( mdata->begin()+i, 0 ) );
135 }
136 
138 
150 { return this->ro(r, c); }
151 
153 
168 {
169  // Check if indices are valid:
170  assert( 0<=r );
171  assert( 0<=c );
172  assert( r<mrr );
173  assert( c<mcr );
174 
175  // Get index of first data element of this column:
176  Index begin = (*mcolptr)[c];
177 
178  // Get index of first data element of next column. (This always works,
179  // because mcolptr has one extra element pointing behind the last
180  // column.)
181  const Index end = (*mcolptr)[c+1];
182 
183  // See if we find an element with the right row index in this
184  // range. We assume that the elements are sorted by ascending row
185  // index.
186  for ( Index i=begin; i<end; ++i )
187  {
188  Index rowi = (*mrowind)[i];
189  if ( r < rowi )
190  return 0;
191  if ( r == rowi )
192  return (*mdata)[i];
193  }
194  return 0;
195 }
196 
197 
198 // Constructors
199 // ------------
200 
202 
207  mdata(NULL),
208  mrowind(NULL),
209  mcolptr(NULL),
210  mrr(0),
211  mcr(0)
212 {
213  // Nothing to do here
214 }
215 
217 
236  mdata(new vector<Numeric>),
237  mrowind(new vector<Index>),
238  mcolptr(new vector<Index>(c+1,0)),
239  mrr(r),
240  mcr(c)
241 {
242  // Nothing to do here.
243 }
244 
245 
247 
256 // mdata(new vector<Numeric>(*m.mdata)),
257 // mrowind(new vector<Index>(*m.mrowind)),
258 // mcolptr(new vector<Index>(*m.mcolptr)),
259  mdata(NULL),
260  mrowind(NULL),
261  mcolptr(NULL),
262  mrr(m.mrr),
263  mcr(m.mcr)
264 {
265  if (m.mdata) mdata = new vector<Numeric>(*m.mdata);
266  if (m.mrowind) mrowind = new vector<Index>(*m.mrowind);
267  if (m.mcolptr) mcolptr = new vector<Index>(*m.mcolptr);
268 
269 // cout << "Original:\n" << m << "\n";
270 // cout << "Copied:\n" << *this << "\n";
271 }
272 
273 
275 
282 {
283  delete mdata;
284  delete mrowind;
285  delete mcolptr;
286 }
287 
289 
304 {
305  // Check if the row index and the Vector length are valid
306  assert( 0<=r );
307  assert( r<mrr );
308  assert( v.nelem()==mcr );
309 
310  // Calculate number of non-zero elements in Vector v.
311  Index vnnz=0;
312  for (Index i=0; i<v.nelem(); i++)
313  {
314  if (v[i]!=0)
315  {
316  vnnz++;
317  }
318  }
319 
320  // Count number of already existing elements in this row. Create
321  // reference mrowind and mdata vector that copies of the real mrowind and
322  // mdata. Resize the real mrowind and mdata to the correct output size.
323  Index rnnz = vnnz - count(mrowind->begin(),mrowind->end(),r);
324  vector<Index> mrowind_ref(mrowind->size());
325  copy(mrowind->begin(), mrowind->end(), mrowind_ref.begin());
326  vector<Numeric> mdata_ref(mdata->size());
327  copy(mdata->begin(), mdata->end(), mdata_ref.begin());
328  mrowind->resize(mrowind_ref.size()+rnnz);
329  mdata->resize(mdata_ref.size()+rnnz);
330 
331  // Create iterators to the output vectors to keep track of current
332  // positions.
333  vector<Index>::iterator mrowind_it = mrowind->begin();
334  vector<Numeric>::iterator mdata_it = mdata->begin();
335 
336  // Create a variable to store the change to mcolptr for each run
337  Index colptr_mod = 0;
338 
339  // Loop through Vector v and insert the non-zero elements.
340  for (Index i=0; i<v.nelem(); i++)
341  {
342  // Get mdata- and mrowind iterators to start and end of this
343  // (the i:th) reference column.
344  vector<Numeric>::iterator dstart =
345  mdata_ref.begin()+(*mcolptr)[i];
346  vector<Numeric>::iterator dend =
347  mdata_ref.begin()+(*mcolptr)[i+1];
348  vector<Index>::iterator rstart =
349  mrowind_ref.begin()+(*mcolptr)[i];
350  vector<Index>::iterator rend =
351  mrowind_ref.begin()+(*mcolptr)[i+1];
352 
353  // Apply mcolptr change now that we have the iterators to the
354  // data and row indices.
355  (*mcolptr)[i] = colptr_mod;
356 
357  if (v[i]!=0)
358  {
359  // Check if r exist within this column, and get iterator for
360  // mdata
361  vector<Index>::iterator rpos = find(rstart,rend,r);
362  vector<Numeric>::iterator dpos = dstart+(rpos-rstart);
363  if (rpos!=rend)
364  {
365  // The index was found, replace the value in mdata with the
366  // value from v.
367  *dpos = v[i];
368 
369  // Copy this column to the ouput vectors.
370  copy(rstart,rend,mrowind_it);
371  copy(dstart,dend,mdata_it);
372 
373  // Adjust the position iterators accordingly.
374  mrowind_it += rend-rstart;
375  mdata_it += dend-dstart;
376 
377  // Set the mcolptr step, for next loop
378  colptr_mod = (*mcolptr)[i]+(rend-rstart);
379  }
380  else
381  {
382  // The row index was not found, look for the first index
383  // greater than r
384  rpos = find_if(rstart,rend,bind2nd(greater<Index>(),r));
385  dpos = dstart+(rpos-rstart);
386 
387  // Copy the first part of the column to the output vector.
388  copy(rstart,rpos,mrowind_it);
389  copy(dstart,dpos,mdata_it);
390 
391  // Make sure mrowind_it and mdata_it points at the first
392  // 'empty' position.
393  mrowind_it += rpos-rstart;
394  mdata_it += dpos-dstart;
395 
396  // Insert the new value from v in mdata and the row index r in
397  // mrowind.
398  *mrowind_it = r;
399  *mdata_it = v[i];
400 
401  // Again, make sure mrowind_it and mdata_it points at the
402  // first 'empty' position.
403  mrowind_it++;
404  mdata_it++;
405 
406  // Copy the rest of this column to the output vectors.
407  copy(rpos,rend,mrowind_it);
408  copy(dpos,dend,mdata_it);
409 
410  // Adjust the iterators a last time
411  mrowind_it += rend-rpos;
412  mdata_it += dend-dpos;
413 
414  // Set the mcolptr step, for next loop
415  colptr_mod = (*mcolptr)[i]+(rend-rstart+1);
416  }
417  }
418  else
419  {
420  // Check if r exist within this column, and get iterator for
421  // mdata
422  vector<Index>::iterator rpos = find(rstart,rend,r);
423  vector<Numeric>::iterator dpos = dstart+(rpos-rstart);
424  if (rpos!=rend)
425  {
426  // The index was found and we use remove_copy to copy the rest
427  // of the column to mrowind_new and mdata_new.
428  remove_copy(rstart,rend,mrowind_it, *rpos);
429  remove_copy(dstart,dend,mdata_it, *dpos);
430 
431  // Increase the mrowind_it and mdata_it
432  mrowind_it += rend-rstart-1;
433  mdata_it += dend-dstart-1;
434 
435  // Set the mcolptr step, for next loop
436  colptr_mod = (*mcolptr)[i]+(rend-rstart-1);
437  }
438  else
439  {
440  // The row index was not found, all we need is to copy this
441  // columns to the output mrowind and mdata vectors.
442  copy(rstart,rend,mrowind_it);
443  copy(dstart,dend,mdata_it);
444 
445  // Adjust the mrowind_it and mdata_it iterators
446  mrowind_it += rend-rstart;
447  mdata_it += dend-dstart;
448 
449  // Set the mcolptr step, for next loop
450  colptr_mod = (*mcolptr)[i]+(rend-rstart);
451  }
452  }
453  }
454  // Apply mcolptr change for the one extra mcolptr element.
455  *(mcolptr->end()-1) = colptr_mod;
456 
457  // Clean up?
458  //delete mrowind_ref;
459  //delete mdata_ref;
460 }
461 
463 
475 {
476  assert( 0<=r );
477  assert( 0<=c );
478 
479  // First get number of ones in the identity matrix
480  Index n = min(r,c);
481 
482  // Remake and assign values to vectors
483  delete mcolptr;
484  mcolptr = new vector<Index>( c+1, n);
485  delete mrowind;
486  mrowind = new vector<Index>(n);
487  delete mdata;
488  mdata = new vector<Numeric>(n,1.0);
489 
490  // Loop over number of ones and assign values [0:n-1] to mcolptr and
491  // mrowind
492  vector<Index>::iterator rit = mrowind->begin();
493  vector<Index>::iterator cit = mcolptr->begin();
494  for( Index i=0; i<n; i++ ) {
495  *rit++ = i;
496  *cit++ = i;
497  }
498 
499  mrr = r;
500  mcr = c;
501 }
502 
504 
517 {
518  assert( 0<=r );
519  assert( 0<=c );
520  if ( mrr!=r || mcr!=c )
521  {
522  delete mdata;
523  mdata = new vector<Numeric>;
524  delete mrowind;
525  mrowind = new vector<Index>;
526  delete mcolptr;
527  mcolptr = new vector<Index>(c+1,0);
528 
529  mrr = r;
530  mcr = c;
531  }
532 }
533 
535 
552 {
553  // It is important that we first delete previous content of the
554  // target, otherwise we create a memory leak!
555  //
556  // The scalar delete operator is the correct one to use here, since
557  // only one vector object has been allocated by new in each
558  // case. (That the object itself is a vector does not matter.)
559  //
560  // Caveat: We should delete only if there really *is* previous
561  // content, otherwise we will generate a core dump.
562  if (mdata!=NULL)
563  {
564  assert (mrowind!=NULL);
565  assert (mcolptr!=NULL);
566 
567  delete mdata;
568  delete mrowind;
569  delete mcolptr;
570 
571  mdata = NULL;
572  mrowind = NULL;
573  mcolptr = NULL;
574  }
575 
576  mrr = m.mrr;
577  mcr = m.mcr;
578 
579  if (m.mdata!=NULL)
580  {
581  mdata = new vector<Numeric>(*m.mdata);
582  mrowind = new vector<Index>(*m.mrowind);
583  mcolptr = new vector<Index>(*m.mcolptr);
584  }
585 
586  return *this;
587 }
588 
590 
599 ostream& operator<<(ostream& os, const Sparse& v)
600 {
601  for (size_t c=0; c<v.mcolptr->size()-1; ++c)
602  {
603  // Get index of first data element of this column:
604  Index begin = (*v.mcolptr)[c];
605 
606  // Get index of first data element of next column. (This always works,
607  // because mcolptr has one extra element pointing behind the last
608  // column.)
609  const Index end = (*v.mcolptr)[c+1];
610 
611  // Loop through the elements in this column:
612  for ( Index i=begin; i<end; ++i )
613  {
614  // Get row index:
615  Index r = (*v.mrowind)[i];
616 
617  // Output everything:
618  os << setw(3) << r << " "
619  << setw(3) << c << " "
620  << setw(3) << (*v.mdata)[i] << "\n";
621  }
622  }
623 
624  return os;
625 }
626 
627 // General matrix functions
628 
630 
641 void abs( Sparse& A,
642  const Sparse& B )
643 {
644  // Check dimensions
645  assert( A.nrows() == B.nrows() );
646  assert( A.ncols() == B.ncols() );
647 
648  // Here we allocate memory for the A.mdata vector so that it matches the
649  // input matrix, and then store the absolute values of B.mdata in it.
650  A.mdata->resize( B.mdata->size() );
651  Index end = B.mdata->size();
652  for (Index i=0; i<end; i++)
653  {
654  (*A.mdata)[i] = fabs((*B.mdata)[i]);
655  }
656 
657  // The column pointer and row index vectors are copies of the input
658  A.mcolptr->resize( B.mcolptr->size() );
659  copy(B.mcolptr->begin(), B.mcolptr->end(), A.mcolptr->begin());
660  A.mrowind->resize( B.mrowind->size() );
661  copy(B.mrowind->begin(), B.mrowind->end(), A.mrowind->begin());
662 
663 }
664 
666 
683 void mult( VectorView y,
684  const Sparse& M,
685  ConstVectorView x )
686 {
687  // Check dimensions:
688  assert( y.nelem() == M.nrows() );
689  assert( M.ncols() == x.nelem() );
690 
691  // Initialize y to all zeros:
692  y = 0.0;
693 
694  // Looping through every element of M, multiplying it with the
695  // appropriate elements of x.
696  for (size_t c=0; c<M.mcolptr->size()-1; ++c)
697  {
698  // Get index of first data element of this column:
699  Index begin = (*M.mcolptr)[c];
700 
701  // Get index of first data element of next column. (This always works,
702  // because mcolptr has one extra element pointing behind the last
703  // column.)
704  const Index end = (*M.mcolptr)[c+1];
705 
706  // Loop through the elements in this column:
707  for ( Index i=begin; i<end; ++i )
708  {
709  // Get row index:
710  Index r = (*M.mrowind)[i];
711 
712  // Compute this element:
713  y[r] += (*M.mdata)[i] * x[c];
714  }
715  }
716 }
717 
719 
736 void mult( MatrixView A,
737  const Sparse& B,
738  ConstMatrixView C )
739 {
740  // Check dimensions:
741  assert( A.nrows() == B.nrows() );
742  assert( A.ncols() == C.ncols() );
743  assert( B.ncols() == C.nrows() );
744 
745  // Set all elements of A to zero:
746  A = 0.0;
747 
748  // Loop through the elements of B:
749  for (size_t c=0; c<B.mcolptr->size()-1; ++c)
750  {
751  // Get index of first data element of this column:
752  Index begin = (*B.mcolptr)[c];
753 
754  // Get index of first data element of next column. (This always works,
755  // because mcolptr has one extra element pointing behind the last
756  // column.)
757  const Index end = (*B.mcolptr)[c+1];
758 
759  // Loop through the elements in this column:
760  for ( Index i=begin; i<end; ++i )
761  {
762  // Get row index:
763  Index r = (*B.mrowind)[i];
764 
765  // Multiply this element with the corresponding row of C and
766  // add the product to the right row of A
767  for (Index j=0; j<C.ncols(); j++)
768  {
769  /* Conceptually:
770  A(r,j) += B.ro(r,c) * C(c,j);
771  But we don't need to use the index operator, because
772  we have the right element right here: */
773  A(r,j) += (*B.mdata)[i] * C(c,j);
774  }
775  }
776  }
777 }
778 
779 
781 
792 void transpose( Sparse& A,
793  const Sparse& B )
794 {
795  // Check dimensions
796  assert( A.nrows() == B.ncols() );
797  assert( A.ncols() == B.nrows() );
798  if ( B.mdata->size() == 0) return;
799 
800  // Here we allocate memory for the A.mdata and A.mrowind vectors so that
801  // it matches the input matrix. (NB: that mdata and mrowind already has
802  // the same size.)
803  A.mdata->resize( B.mdata->size() );
804  A.mrowind->resize( B.mrowind->size() );
805 
806  // Find the minimum and maximum existing row number in B.
807  // (This maybe unnecessary in our case since we mostly treat diagonally
808  // banded matrices where the minimum and maximum existing row numbers
809  // coincide with the border numbers of the matrix.)
810  vector<Index>::iterator startrow, stoprow;
811  startrow = min_element( B.mrowind->begin(), B.mrowind->end() );
812  stoprow = max_element( B.mrowind->begin(), B.mrowind->end() );
813 
814  // To create the A.mcolptr vector we loop through the existing row
815  // numbers of B and count how many there are in B.mrowind.
816  // First we make sure it is initialized to all zeros.
817  A.mcolptr->assign( A.mcr+1, 0 );
818  for (Index i=*startrow; i<=*stoprow; i++)
819  {
820  Index n = count( B.mrowind->begin(), B.mrowind->end(), i);
821 
822  // The column pointer for the column above the current one in A
823  // are then set to the current one plus this amount.
824  (*A.mcolptr)[i+1] = (*A.mcolptr)[i] + n;
825  }
826 
827  // Next we loop through the columns of A and search for the corresponding
828  // row index within each column of B (i.e. two loops). The elements are
829  // then stored in A. We know that for every column in B we will have
830  // the corresponding rowindex in A.
831  vector<Numeric>::iterator dataA_it = A.mdata->begin();
832  vector<Index>::iterator rowindA_it = A.mrowind->begin();
833 
834  // Looping over columns in A to keep track of what row number we are
835  // looking for.
836  for (size_t c=0; c<A.mcolptr->size(); ++c)
837  {
838  // Looping over columns in B to get the elements in the right order,
839  // this will turn into row index in A.
840  for (size_t i=0; i<B.mcolptr->size()-1; i++)
841  {
842  // Since only one element can occupy one row in a column, we
843  // only need to call find() once per column in B.
844  vector<Index>::iterator elem_it =
845  find(B.mrowind->begin()+*(B.mcolptr->begin()+i),
846  B.mrowind->begin()+*(B.mcolptr->begin()+i+1), Index (c));
847 
848  // If we found the element, store it in A.mrowind and A.mdata
849  if (elem_it != B.mrowind->begin()+*(B.mcolptr->begin()+i+1))
850  {
851  *rowindA_it = i;
852  rowindA_it++;
853 
854  // To get the corresponding element in B.mdata we subtract
855  // the initial value of the row index iterator from elem_it
856  // and add the difference to a mdata iterator.
857  Index diff = elem_it - B.mrowind->begin();
858  vector<Numeric>::iterator elemdata_it=B.mdata->begin() + diff;
859  *dataA_it = *elemdata_it;
860  dataA_it++;
861  }
862  }
863  }
864 }
865 
866 
868 
883 void mult( Sparse& A,
884  const Sparse& B,
885  const Sparse& C )
886 {
887  // Check dimensions and make sure that A is empty
888  assert( A.nrows() == B.nrows() );
889  assert( A.ncols() == C.ncols() );
890  assert( B.ncols() == C.nrows() );
891  A.mcolptr->assign( A.mcr+1, 0);
892  A.mrowind->clear();
893  A.mdata->clear();
894 
895  // Transpose B to simplify multiplication algorithm, after transposing we
896  // can extract columns form the two matrices and multiply them, (which is
897  // easier than extacting rows.)
898  Sparse Bt(B.ncols(), B.nrows());
899  // cout << "B.nrows, B.ncols = " << B.nrows() << ", " << B.ncols() << "\n";
900  // cout << "B = \n" << B << "\n";
901  transpose(Bt,B);
902 
903  // By looping over columns in C and multiply them with every column in Bt
904  // (instead of the conventional loooping over Bt), we get the output
905  // elements in the right order for storing them.
906  for (size_t c=0; c<C.mcolptr->size()-1; ++c)
907  {
908  // Get row indices of this column
909  //Index beginC = (*C.mcolptr)[c];
910  //Index endC = (*C.mcolptr)[c+1];
911 
912  for (size_t b=0; b<Bt.mcolptr->size()-1; ++b)
913  {
914  // Get the intersection between the elements in the two columns and
915  // and store them in a temporary vector
916  set<Index> colintersec;
917  set_intersection(C.mrowind->begin()+*(C.mcolptr->begin()+c),
918  C.mrowind->begin()+*(C.mcolptr->begin()+c+1),
919  Bt.mrowind->begin()+*(Bt.mcolptr->begin()+b),
920  Bt.mrowind->begin()+*(Bt.mcolptr->begin()+b+1),
921  inserter(colintersec, colintersec.begin()));
922 
923  // If we got an intersection, loop through it and multiply the
924  // element pairs from C and Bt and store result in A
925  if (!colintersec.empty())
926  {
927  Numeric tempA = 0.0;
928  for (set<Index>::iterator i=colintersec.begin();
929  i!=colintersec.end(); ++i)
930  {
931  // To get iterators to the data elements in Bt and C, we
932  // subtract the iterator that points to the start of the
933  // mrowind vector from the iterators that points to the
934  // values in colintersec. We then get the number of steps
935  // from the start of the both vectors mrowind and mdata to
936  // the intersecting values and can add them to the
937  // iterator that points to the beginning of mdata.
938  vector<Index>::iterator rowindBt_it =
939  find(Bt.mrowind->begin()+*(Bt.mcolptr->begin()+b),
940  Bt.mrowind->begin()+*(Bt.mcolptr->begin()+b+1), *i);
941  vector<Index>::iterator rowindC_it =
942  find(C.mrowind->begin()+*(C.mcolptr->begin()+c),
943  C.mrowind->begin()+*(C.mcolptr->begin()+c+1), *i);
944 
945  vector<Numeric>::iterator dataBt_it =
946  Bt.mdata->begin()+(rowindBt_it-Bt.mrowind->begin());
947  vector<Numeric>::iterator dataC_it =
948  C.mdata->begin()+(rowindC_it-C.mrowind->begin());
949 
950  tempA += *dataBt_it * *dataC_it;
951  }
952  A.rw(b,c) = tempA;
953  }
954  }
955  }
956 }
957 
958 
960 
974 void add( Sparse& A,
975  const Sparse& B,
976  const Sparse& C )
977 {
978  // Check dimensions
979  assert( B.ncols() == C.ncols() );
980  assert( B.nrows() == C.nrows() );
981 
982  // We copy the smaller matrix of B or C to A. This way we can
983  // loop over the matrix with the fewer number of elements to perform
984  // the actual addition later.
985  const Sparse* D;
986  if (B.data()->size() < C.data()->size())
987  {
988  A=C;
989  D=&B;
990  }
991  else
992  {
993  A=B;
994  D=&C;
995  }
996 
997  for (size_t c = 0; c < D->mcolptr->size()-1; ++c)
998  {
999  // Loop through the elements in this column:
1000  for (Index i = (*D->mcolptr)[c]; i < (*D->mcolptr)[c+1]; ++i)
1001  {
1002  A.rw((*D->mrowind)[i], c) += (*D->mdata)[i];
1003  }
1004  }
1005 }
1006 
1007 
1009 
1023 void sub( Sparse& A,
1024  const Sparse& B,
1025  const Sparse& C )
1026 {
1027  // Check dimensions
1028  assert( B.ncols() == C.ncols() );
1029  assert( B.nrows() == C.nrows() );
1030 
1031  A=B;
1032 
1033  for (size_t c = 0; c < C.mcolptr->size()-1; ++c)
1034  {
1035  // Loop through the elements in this column:
1036  for (Index i = (*C.mcolptr)[c]; i < (*C.mcolptr)[c+1]; ++i)
1037  {
1038  A.rw((*C.mrowind)[i], c) -= (*C.mdata)[i];
1039  }
1040  }
1041 }
1042 
Sparse::mdata
vector< Numeric > * mdata
The actual data values.
Definition: matpackII.h:103
MatrixView
The MatrixView class.
Definition: matpackI.h:668
Sparse::ncols
Index ncols() const
Returns the number of columns.
Definition: matpackII.cc:59
Sparse::make_I
void make_I(Index r, Index c)
Make Identity matrix.
Definition: matpackII.cc:474
Sparse
The Sparse class.
Definition: matpackII.h:55
Sparse::Sparse
Sparse()
Default constructor.
Definition: matpackII.cc:206
Sparse::mcolptr
vector< Index > * mcolptr
Pointers to first data element for each column.
Definition: matpackII.h:107
ConstMatrixView::nrows
Index nrows() const
Returns the number of rows.
Definition: matpackI.cc:796
Sparse::ro
Numeric ro(Index r, Index c) const
Read only index operator.
Definition: matpackII.cc:167
mult
void mult(VectorView y, const Sparse &M, ConstVectorView x)
Sparse matrix - Vector multiplication.
Definition: matpackII.cc:683
Sparse::mrowind
vector< Index > * mrowind
Row indices.
Definition: matpackII.h:105
Sparse::operator=
Sparse & operator=(const Sparse &m)
Assignment from another Sparse.
Definition: matpackII.cc:551
Sparse::insert_row
void insert_row(Index r, Vector v)
Insert row function.
Definition: matpackII.cc:303
Sparse::mcr
Index mcr
Number of rows in the sparse matrix.
Definition: matpackII.h:111
Sparse::nnz
Index nnz() const
Returns the number of nonzero elements.
Definition: matpackII.cc:65
ConstMatrixView::ncols
Index ncols() const
Returns the number of columns.
Definition: matpackI.cc:802
transpose
void transpose(Sparse &A, const Sparse &B)
Transpose of sparse matrix.
Definition: matpackII.cc:792
Sparse::operator()
Numeric operator()(Index r, Index c) const
Plain index operator.
Definition: matpackII.cc:149
sub
void sub(Sparse &A, const Sparse &B, const Sparse &C)
Sparse - Sparse subtraction.
Definition: matpackII.cc:1023
ConstVectorView::nelem
Index nelem() const
Returns the number of elements.
Definition: matpackI.cc:175
VectorView
The VectorView class.
Definition: matpackI.h:373
Numeric
NUMERIC Numeric
The type to use for all floating point numbers.
Definition: matpack.h:33
operator<<
ostream & operator<<(ostream &os, const Sparse &v)
Output operator for Sparse.
Definition: matpackII.cc:599
ConstMatrixView
A constant view of a Matrix.
Definition: matpackI.h:591
Sparse::resize
void resize(Index r, Index c)
Resize function.
Definition: matpackII.cc:516
Sparse::nrows
Index nrows() const
Returns the number of rows.
Definition: matpackII.cc:53
abs
void abs(Sparse &A, const Sparse &B)
Absolute value of sparse matrix elements.
Definition: matpackII.cc:641
Sparse::rw
Numeric & rw(Index r, Index c)
Read and write index operator.
Definition: matpackII.cc:90
min
#define min(a, b)
Definition: continua.cc:13096
matpackII.h
Header file for sparse matrices.
Sparse::data
const vector< Numeric > * data() const
Definition: matpackII.h:79
Index
INDEX Index
The type to use for all integer numbers and indices.
Definition: matpack.h:39
Sparse::~Sparse
~Sparse()
Destructor for Sparse.
Definition: matpackII.cc:281
M
#define M
Definition: rng.cc:196
Vector
The Vector class.
Definition: matpackI.h:555
copy
void copy(ConstIterator1D origin, const ConstIterator1D &end, Iterator1D target)
Copy data between begin and end to target.
Definition: matpackI.cc:597
ConstVectorView
A constant view of a Vector.
Definition: matpackI.h:300
Sparse::mrr
Index mrr
Number of rows in the sparse matrix.
Definition: matpackII.h:109
add
void add(Sparse &A, const Sparse &B, const Sparse &C)
Sparse - Sparse addition.
Definition: matpackII.cc:974