ARTS  2.0.49
matpackI.cc
Go to the documentation of this file.
1 /* Copyright (C) 2001-2008 Stefan Buehler <sbuehler@ltu.se>
2 
3  This program is free software; you can redistribute it and/or modify it
4  under the terms of the GNU General Public License as published by the
5  Free Software Foundation; either version 2, or (at your option) any
6  later version.
7 
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  GNU General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License
14  along with this program; if not, write to the Free Software
15  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
16  USA. */
17 
25 #include <cstring>
26 #include "matpackI.h"
27 #include "exceptions.h"
28 
29 
30 // Define the global joker object:
31 extern const Joker joker = Joker();
32 
33 
34 // Functions for Range:
35 // --------------------
36 
37 /* Explicit constructor.
38 
39  \param Start must be >= 0.
40 
41  \param Extent also. Although internally negative extent means "to the end",
42  this can not be created this way, only with the joker. Zero
43  extent is allowed, though, which corresponds to an empty range.
44 
45  \param Stride can be anything. It can be omitted, in which case the
46  default value is 1. */
47 Range::Range(Index start, Index extent, Index stride) :
48  mstart(start), mextent(extent), mstride(stride)
49 {
50  // Start must be >= 0:
51  assert( 0<=mstart );
52  // Extent also. Although internally negative extent means "to the end",
53  // this can not be created this way, only with the joker. Zero
54  // extent is allowed, though, which corresponds to an empty range.
55  assert( 0<=mextent );
56  // Stride can be anything except 0.
57  // SAB 2001-09-21: Allow 0 stride.
58  // assert( 0!=mstride);
59 }
60 
63 Range::Range(Index start, Joker, Index stride) :
64  mstart(start), mextent(-1), mstride(stride)
65 {
66  // Start must be >= 0:
67  assert( 0<=mstart );
68 }
69 
74  mstart(0), mextent(-1), mstride(stride)
75 {
76  // Nothing to do here.
77 }
78 
84 Range::Range(Index max_size, const Range& r) :
85  mstart(r.mstart),
86  mextent(r.mextent),
87  mstride(r.mstride)
88 {
89  // Start must be >= 0:
90  assert( 0<=mstart );
91  // ... and < max_size:
92  assert( mstart<max_size );
93 
94  // Stride must be != 0:
95  assert( 0!=mstride);
96 
97  // Convert negative extent (joker) to explicit extent
98  if ( mextent<0 )
99  {
100  if ( 0<mstride )
101  mextent = 1 + (max_size-1-mstart)/mstride;
102  else
103  mextent = 1 + (0-mstart)/mstride;
104  }
105  else
106  {
107 #ifndef NDEBUG
108  // Check that extent is ok:
109  Index fin = mstart+(mextent-1)*mstride;
110  assert( 0 <= fin );
111  assert( fin < max_size );
112 #endif
113  }
114 }
115 
121 Range::Range(const Range& p, const Range& n) :
122  mstart(p.mstart + n.mstart*p.mstride),
123  mextent(n.mextent),
124  mstride(p.mstride*n.mstride)
125 {
126  // We have to juggle here a bit with previous, new, and resulting
127  // quantities. I.e.;
128  // p.mstride: Previous stride
129  // n.mstride: New stride (as specified)
130  // mstride: Resulting stride (old*new)
131 
132  // Get the previous final element:
133  Index prev_fin = p.mstart+(p.mextent-1)*p.mstride;
134 
135  // Resulting start must be >= previous start:
136  assert( p.mstart<=mstart );
137  // and <= prev_fin:
138  assert( mstart<=prev_fin );
139 
140  // Resulting stride must be != 0:
141  assert( 0!=mstride);
142 
143  // Convert negative extent (joker) to explicit extent
144  if ( mextent<0 )
145  {
146  if ( 0<mstride )
147  mextent = 1 + (prev_fin-mstart)/mstride;
148  else
149  mextent = 1 + (p.mstart-mstart)/mstride;
150  }
151  else
152  {
153 #ifndef NDEBUG
154  // Check that extent is ok:
155  Index fin = mstart+(mextent-1)*mstride;
156  assert( p.mstart <= fin );
157  assert( fin <= prev_fin );
158 #endif
159  }
160 
161 }
162 
163 // Functions for ConstVectorView:
164 // ------------------------------
165 
176 {
177  return mrange.mextent;
178 }
179 
182 {
183  Numeric s=0;
184  ConstIterator1D i = begin();
185  const ConstIterator1D e = end();
186 
187  for ( ; i!=e; ++i )
188  s += *i;
189 
190  return s;
191 }
192 
197 {
198  return ConstVectorView(mdata, mrange, r);
199 }
200 
203 {
205 }
206 
209 {
210  return ConstIterator1D( mdata +
211  mrange.mstart +
213  mrange.mstride );
214 }
215 
217 ConstVectorView::operator ConstMatrixView() const
218 {
219  return ConstMatrixView(mdata,mrange,Range(mrange.mstart,1));
220 }
221 
230  mrange(0,1), mdata(&const_cast<Numeric&>(a))
231 {
232  // Nothing to do here.
233 }
234 
238  mrange(0,0), mdata(NULL)
239 {
240  // Nothing to do here.
241 }
242 
246  const Range& range) :
247  mrange(range),
248  mdata(data)
249 {
250  // Nothing to do here.
251 }
252 
264  const Range& p,
265  const Range& n) :
266  mrange(p,n),
267  mdata(data)
268 {
269  // Nothing to do here.
270 }
271 
275 ostream& operator<<(ostream& os, const ConstVectorView& v)
276 {
277  ConstIterator1D i=v.begin();
278  const ConstIterator1D end=v.end();
279 
280  if ( i!=end )
281  {
282  os << setw(3) << *i;
283  ++i;
284  }
285  for ( ; i!=end ; ++i )
286  {
287  os << " " << setw(3) << *i;
288  }
289 
290  return os;
291 }
292 
293 
294 // Functions for VectorView:
295 // ------------------------
296 
300 {
301  throw runtime_error("Creating a VectorView from a const Vector is not allowed.");
302  // This is not really a runtime error, but I don't want to start
303  // producing direct output from inside matpack. And just exiting is
304  // not so nice.
305  // If you see this error, there is a bug in the code, not in the
306  // ARTS input.
307 }
308 
311 {
312  mdata = v.mdata;
313  mrange = v.mrange;
314 }
315 
321 {
322  return ConstVectorView::operator[](r);
323 }
324 
329 {
330  return VectorView(mdata, mrange, r);
331 }
332 
337 {
338  return ConstVectorView::begin();
339 }
340 
345 {
346  return ConstVectorView::end();
347 }
348 
351 {
353 }
354 
357 {
358  return Iterator1D( mdata +
359  mrange.mstart +
361  mrange.mstride );
362 }
363 
369 {
370  // cout << "Assigning VectorView from ConstVectorView.\n";
371 
372  // Check that sizes are compatible:
373  assert(mrange.mextent==v.mrange.mextent);
374 
375  copy( v.begin(), v.end(), begin() );
376 
377  return *this;
378 }
379 
386 {
387  // cout << "Assigning VectorView from VectorView.\n";
388 
389  // Check that sizes are compatible:
390  assert(mrange.mextent==v.mrange.mextent);
391 
392  copy( v.begin(), v.end(), begin() );
393 
394  return *this;
395 }
396 
400 {
401  // cout << "Assigning VectorView from Vector.\n";
402 
403  // Check that sizes are compatible:
404  assert(mrange.mextent==v.mrange.mextent);
405 
406  copy( v.begin(), v.end(), begin() );
407 
408  return *this;
409 }
410 
414 {
415  copy( x, begin(), end() );
416  return *this;
417 }
418 
421 {
422  const Iterator1D e=end();
423  for ( Iterator1D i=begin(); i!=e ; ++i )
424  *i *= x;
425  return *this;
426 }
427 
430 {
431  const Iterator1D e=end();
432  for ( Iterator1D i=begin(); i!=e ; ++i )
433  *i /= x;
434  return *this;
435 }
436 
439 {
440  const Iterator1D e=end();
441  for ( Iterator1D i=begin(); i!=e ; ++i )
442  *i += x;
443  return *this;
444 }
445 
448 {
449  const Iterator1D e=end();
450  for ( Iterator1D i=begin(); i!=e ; ++i )
451  *i -= x;
452  return *this;
453 }
454 
457 {
458  assert( nelem()==x.nelem() );
459 
460  ConstIterator1D s=x.begin();
461 
462  Iterator1D i=begin();
463  const Iterator1D e=end();
464 
465  for ( ; i!=e ; ++i,++s )
466  *i *= *s;
467  return *this;
468 }
469 
472 {
473  assert( nelem()==x.nelem() );
474 
475  ConstIterator1D s=x.begin();
476 
477  Iterator1D i=begin();
478  const Iterator1D e=end();
479 
480  for ( ; i!=e ; ++i,++s )
481  *i /= *s;
482  return *this;
483 }
484 
487 {
488  assert( nelem()==x.nelem() );
489 
490  ConstIterator1D s=x.begin();
491 
492  Iterator1D i=begin();
493  const Iterator1D e=end();
494 
495  for ( ; i!=e ; ++i,++s )
496  *i += *s;
497  return *this;
498 }
499 
502 {
503  assert( nelem()==x.nelem() );
504 
505  ConstIterator1D s=x.begin();
506 
507  Iterator1D i=begin();
508  const Iterator1D e=end();
509 
510  for ( ; i!=e ; ++i,++s )
511  *i -= *s;
512  return *this;
513 }
514 
516 VectorView::operator MatrixView()
517 {
518  return MatrixView(mdata,mrange,Range(mrange.mstart,1));
519 }
520 
528 {
529  if (mrange.mstart != 0 || mrange.mstride != 1)
530  throw runtime_error("A VectorView can only be converted to a plain C-array if mrange.mstart == 0 and mrange.mstride == 1");
531 
532  return mdata;
533 }
534 
542 {
543  if (mrange.mstart != 0 || mrange.mstride != 1)
544  throw runtime_error("A VectorView can only be converted to a plain C-array if mrange.mstart == 0 and mrange.mstride == 1");
545 
546  return mdata;
547 }
548 
553  ConstVectorView(a)
554 {
555  // Nothing to do here.
556 }
557 
562 {
563  // Nothing to do here.
564 }
565 
569  const Range& range) :
570  ConstVectorView(data,range)
571 {
572  // Nothing to do here.
573 }
574 
586  const Range& p,
587  const Range& n) :
588  ConstVectorView(data,p,n)
589 {
590  // Nothing to do here.
591 }
592 
597 void copy(ConstIterator1D origin,
598  const ConstIterator1D& end,
599  Iterator1D target)
600 {
601  if (origin.mstride == 1 && target.mstride == 1)
602  memcpy((void *)target.mx,
603  (void *)origin.mx,
604  sizeof(Numeric) * (end.mx - origin.mx));
605  else
606  for ( ; origin!=end ; ++origin,++target )
607  *target = *origin;
608 }
609 
611 void copy(Numeric x,
612  Iterator1D target,
613  const Iterator1D& end)
614 {
615  for ( ; target!=end ; ++target )
616  *target = x;
617 }
618 
619 
620 // Functions for Vector:
621 // ---------------------
622 
625 {
626  // Nothing to do here
627 }
628 
631  VectorView( new Numeric[n],
632  Range(0,n))
633 {
634  // Nothing to do here.
635 }
636 
639  VectorView( new Numeric[n],
640  Range(0,n))
641 {
642  // Here we can access the raw memory directly, for slightly
643  // increased efficiency:
644  const Numeric *stop = mdata+n;
645  for ( Numeric *x=mdata; x<stop; ++x )
646  *x = fill;
647 }
648 
657 Vector::Vector(Numeric start, Index extent, Numeric stride) :
658  VectorView( new Numeric[extent],
659  Range(0,extent))
660 {
661  // Fill with values:
662  Numeric x = start;
663  Iterator1D i=begin();
664  const Iterator1D e=end();
665  for ( ; i!=e; ++i )
666  {
667  *i = x;
668  x += stride;
669  }
670 }
671 
678  VectorView( new Numeric[v.nelem()],
679  Range(0,v.nelem()))
680 {
681  copy(v.begin(),v.end(),begin());
682 }
683 
687  VectorView( new Numeric[v.nelem()],
688  Range(0,v.nelem()))
689 {
690  copy(v.begin(),v.end(),begin());
691 }
692 
694 
719 {
720  resize( v.nelem() );
721  copy( v.begin(), v.end(), begin() );
722  return *this;
723 }
724 
726 
743 {
744  resize( x.nelem() );
746  return *this;
747 }
748 
752 {
754  return *this;
755 }
756 
757 // /** Assignment operator from VectorView. Assignment operators are not
758 // inherited. */
759 // inline Vector& Vector::operator=(const VectorView v)
760 // {
761 // cout << "Assigning Vector from Vector View.\n";
762 // // Check that sizes are compatible:
763 // assert(mrange.mextent==v.mrange.mextent);
764 // VectorView::operator=(v);
765 // return *this;
766 // }
767 
772 {
773  assert( 0<=n );
774  if ( mrange.mextent != n )
775  {
776  delete[] mdata;
777  mdata = new Numeric[n];
778  mrange.mstart = 0;
779  mrange.mextent = n;
780  mrange.mstride = 1;
781  }
782 }
783 
787 {
788  delete[] mdata;
789 }
790 
791 
792 // Functions for ConstMatrixView:
793 // ------------------------------
794 
797 {
798  return mrr.mextent;
799 }
800 
803 {
804  return mcr.mextent;
805 }
806 
811  const Range& c) const
812 {
813  return ConstMatrixView(mdata, mrr, mcr, r, c);
814 }
815 
822 {
823  // Check that c is valid:
824  assert( 0 <= c );
825  assert( c < mcr.mextent );
826 
827  return ConstVectorView(mdata + mcr.mstart + c*mcr.mstride,
828  mrr, r);
829 }
830 
837 {
838  // Check that r is valid:
839  assert( 0 <= r );
840  assert( r < mrr.mextent );
841 
842  return ConstVectorView(mdata + mrr.mstart + r*mrr.mstride,
843  mcr, c);
844 }
845 
848 {
850  mcr),
851  mrr.mstride);
852 }
853 
856 {
858  mcr),
859  mrr.mstride );
860 }
861 
865  mrr(0,0,1), mcr(0,0,1), mdata(NULL)
866 {
867  // Nothing to do here.
868 }
869 
874  const Range& rr,
875  const Range& cr) :
876  mrr(rr),
877  mcr(cr),
878  mdata(data)
879 {
880  // Nothing to do here.
881 }
882 
898  const Range& pr, const Range& pc,
899  const Range& nr, const Range& nc) :
900  mrr(pr,nr),
901  mcr(pc,nc),
902  mdata(data)
903 {
904  // Nothing to do here.
905 }
906 
914 ostream& operator<<(ostream& os, const ConstMatrixView& v)
915 {
916  // Row iterators:
917  ConstIterator2D ir=v.begin();
918  const ConstIterator2D end_row=v.end();
919 
920  if ( ir!=end_row )
921  {
922  ConstIterator1D ic = ir->begin();
923  const ConstIterator1D end_col = ir->end();
924 
925  if ( ic!=end_col )
926  {
927  os << setw(3) << *ic;
928  ++ic;
929  }
930  for ( ; ic!=end_col ; ++ic )
931  {
932  os << " " << setw(3) << *ic;
933  }
934  ++ir;
935  }
936  for ( ; ir!=end_row ; ++ir )
937  {
938  ConstIterator1D ic = ir->begin();
939  const ConstIterator1D end_col = ir->end();
940 
941  os << "\n";
942  if ( ic!=end_col )
943  {
944  os << setw(3) << *ic;
945  ++ic;
946  }
947  for ( ; ic!=end_col ; ++ic )
948  {
949  os << " " << setw(3) << *ic;
950  }
951  }
952 
953  return os;
954 }
955 
956 
957 // Functions for MatrixView:
958 // -------------------------
959 
965 {
966  return ConstMatrixView::operator()(r,c);
967 }
968 
976 {
977  return ConstMatrixView::operator()(r,c);
978 }
979 
987 {
988  return ConstMatrixView::operator()(r,c);
989 }
990 
995 {
996  return MatrixView(mdata, mrr, mcr, r, c);
997 }
998 
1004 {
1005  // Check that c is valid:
1006  assert( 0 <= c );
1007  assert( c < mcr.mextent );
1008 
1009  return VectorView(mdata + mcr.mstart + c*mcr.mstride,
1010  mrr, r);
1011 }
1012 
1018 {
1019  // Check that r is valid:
1020  assert( 0 <= r );
1021  assert( r < mrr.mextent );
1022 
1023  return VectorView(mdata + mrr.mstart + r*mrr.mstride,
1024  mcr, c);
1025 }
1026 
1030 {
1031  return ConstMatrixView::begin();
1032 }
1033 
1036 {
1037  return ConstMatrixView::end();
1038 }
1039 
1042 {
1044  mrr.mstride);
1045 }
1046 
1049 {
1051  mcr),
1052  mrr.mstride );
1053 }
1054 
1060 {
1061  // Check that sizes are compatible:
1062  assert(mrr.mextent==m.mrr.mextent);
1063  assert(mcr.mextent==m.mcr.mextent);
1064 
1065  copy( m.begin(), m.end(), begin() );
1066  return *this;
1067 }
1068 
1075 {
1076  // Check that sizes are compatible:
1077  assert(mrr.mextent==m.mrr.mextent);
1078  assert(mcr.mextent==m.mcr.mextent);
1079 
1080  copy( m.begin(), m.end(), begin() );
1081  return *this;
1082 }
1083 
1088 {
1089  // Check that sizes are compatible:
1090  assert(mrr.mextent==m.mrr.mextent);
1091  assert(mcr.mextent==m.mcr.mextent);
1092 
1093  copy( m.begin(), m.end(), begin() );
1094  return *this;
1095 }
1096 
1102 {
1103  // Check that sizes are compatible:
1104  assert( mrr.mextent==v.nelem() );
1105  assert( mcr.mextent==1 );
1106  // dummy = ConstMatrixView(v.mdata,v.mrange,Range(v.mrange.mstart,1));;
1107  ConstMatrixView dummy(v);
1108  copy( dummy.begin(), dummy.end(), begin() );
1109  return *this;
1110 }
1111 
1115 {
1116  copy( x, begin(), end() );
1117  return *this;
1118 }
1119 
1122 {
1123  const Iterator2D er=end();
1124  for ( Iterator2D r=begin(); r!=er ; ++r )
1125  {
1126  const Iterator1D ec = r->end();
1127  for ( Iterator1D c = r->begin(); c!=ec ; ++c )
1128  *c *= x;
1129  }
1130  return *this;
1131 }
1132 
1135 {
1136  const Iterator2D er=end();
1137  for ( Iterator2D r=begin(); r!=er ; ++r )
1138  {
1139  const Iterator1D ec = r->end();
1140  for ( Iterator1D c = r->begin(); c!=ec ; ++c )
1141  *c /= x;
1142  }
1143  return *this;
1144 }
1145 
1148 {
1149  const Iterator2D er=end();
1150  for ( Iterator2D r=begin(); r!=er ; ++r )
1151  {
1152  const Iterator1D ec = r->end();
1153  for ( Iterator1D c = r->begin(); c!=ec ; ++c )
1154  *c += x;
1155  }
1156  return *this;
1157 }
1158 
1161 {
1162  const Iterator2D er=end();
1163  for ( Iterator2D r=begin(); r!=er ; ++r )
1164  {
1165  const Iterator1D ec = r->end();
1166  for ( Iterator1D c = r->begin(); c!=ec ; ++c )
1167  *c -= x;
1168  }
1169  return *this;
1170 }
1171 
1179 {
1180  if (mrr.mstart != 0 || mrr.mstride != mcr.mextent
1181  || mcr.mstart != 0 || mcr.mstride != 1)
1182  throw runtime_error("A MatrixView can only be converted to a plain C-array if mrr.mstart == 0 and mrr.mstride == mcr.extent and mcr.mstart == 0 and mcr.mstride == 1");
1183 
1184  return mdata;
1185 }
1186 
1194 {
1195  if (mrr.mstart != 0 || mrr.mstride != mcr.mextent
1196  || mcr.mstart != 0 || mcr.mstride != 1)
1197  throw runtime_error("A MatrixView can only be converted to a plain C-array if mrr.mstart == 0 and mrr.mstride == mcr.extent and mcr.mstart == 0 and mcr.mstride == 1");
1198 
1199  return mdata;
1200 }
1201 
1204 {
1205  assert(nrows()==x.nrows());
1206  assert(ncols()==x.ncols());
1207  ConstIterator2D sr = x.begin();
1208  Iterator2D r = begin();
1209  const Iterator2D er = end();
1210  for ( ; r!=er ; ++r,++sr )
1211  {
1212  ConstIterator1D sc = sr->begin();
1213  Iterator1D c = r->begin();
1214  const Iterator1D ec = r->end();
1215  for ( ; c!=ec ; ++c,++sc )
1216  *c *= *sc;
1217  }
1218  return *this;
1219 }
1220 
1223 {
1224  assert(nrows()==x.nrows());
1225  assert(ncols()==x.ncols());
1226  ConstIterator2D sr = x.begin();
1227  Iterator2D r = begin();
1228  const Iterator2D er = end();
1229  for ( ; r!=er ; ++r,++sr )
1230  {
1231  ConstIterator1D sc = sr->begin();
1232  Iterator1D c = r->begin();
1233  const Iterator1D ec = r->end();
1234  for ( ; c!=ec ; ++c,++sc )
1235  *c /= *sc;
1236  }
1237  return *this;
1238 }
1239 
1242 {
1243  assert(nrows()==x.nrows());
1244  assert(ncols()==x.ncols());
1245  ConstIterator2D sr = x.begin();
1246  Iterator2D r = begin();
1247  const Iterator2D er = end();
1248  for ( ; r!=er ; ++r,++sr )
1249  {
1250  ConstIterator1D sc = sr->begin();
1251  Iterator1D c = r->begin();
1252  const Iterator1D ec = r->end();
1253  for ( ; c!=ec ; ++c,++sc )
1254  *c += *sc;
1255  }
1256  return *this;
1257 }
1258 
1261 {
1262  assert(nrows()==x.nrows());
1263  assert(ncols()==x.ncols());
1264  ConstIterator2D sr = x.begin();
1265  Iterator2D r = begin();
1266  const Iterator2D er = end();
1267  for ( ; r!=er ; ++r,++sr )
1268  {
1269  ConstIterator1D sc = sr->begin();
1270  Iterator1D c = r->begin();
1271  const Iterator1D ec = r->end();
1272  for ( ; c!=ec ; ++c,++sc )
1273  *c -= *sc;
1274  }
1275  return *this;
1276 }
1277 
1280 {
1281  assert(nrows()==x.nelem());
1282  assert(ncols()==1);
1283  ConstIterator1D sc = x.begin();
1284  Iterator2D r = begin();
1285  const Iterator2D er = end();
1286  for ( ; r!=er ; ++r,++sc )
1287  {
1288  Iterator1D c = r->begin();
1289  *c *= *sc;
1290  }
1291  return *this;
1292 }
1293 
1296 {
1297  assert(nrows()==x.nelem());
1298  assert(ncols()==1);
1299  ConstIterator1D sc = x.begin();
1300  Iterator2D r = begin();
1301  const Iterator2D er = end();
1302  for ( ; r!=er ; ++r,++sc )
1303  {
1304  Iterator1D c = r->begin();
1305  *c /= *sc;
1306  }
1307  return *this;
1308 }
1309 
1312 {
1313  assert(nrows()==x.nelem());
1314  assert(ncols()==1);
1315  ConstIterator1D sc = x.begin();
1316  Iterator2D r = begin();
1317  const Iterator2D er = end();
1318  for ( ; r!=er ; ++r,++sc )
1319  {
1320  Iterator1D c = r->begin();
1321  *c += *sc;
1322  }
1323  return *this;
1324 }
1325 
1328 {
1329  assert(nrows()==x.nelem());
1330  assert(ncols()==1);
1331  ConstIterator1D sc = x.begin();
1332  Iterator2D r = begin();
1333  const Iterator2D er = end();
1334  for ( ; r!=er ; ++r,++sc )
1335  {
1336  Iterator1D c = r->begin();
1337  *c -= *sc;
1338  }
1339  return *this;
1340 }
1341 
1345  ConstMatrixView()
1346 {
1347  // Nothing to do here.
1348 }
1349 
1354  const Range& rr,
1355  const Range& cr) :
1356  ConstMatrixView(data, rr, cr)
1357 {
1358  // Nothing to do here.
1359 }
1360 
1376  const Range& pr, const Range& pc,
1377  const Range& nr, const Range& nc) :
1378  ConstMatrixView(data,pr,pc,nr,nc)
1379 {
1380  // Nothing to do here.
1381 }
1382 
1392 void copy(ConstIterator2D origin,
1393  const ConstIterator2D& end,
1394  Iterator2D target)
1395 {
1396  for ( ; origin!=end ; ++origin,++target )
1397  {
1398  ConstIterator1D o = origin->begin();
1399  const ConstIterator1D e = origin->end();
1400  Iterator1D t = target->begin();
1401  for ( ; o!=e ; ++o,++t )
1402  *t = *o;
1403  }
1404 }
1405 
1407 void copy(Numeric x,
1408  Iterator2D target,
1409  const Iterator2D& end)
1410 {
1411  for ( ; target!=end ; ++target )
1412  {
1413  Iterator1D t = target->begin();
1414  const Iterator1D e = target->end();
1415  for ( ; t!=e ; ++t )
1416  *t = x;
1417  }
1418 }
1419 
1420 
1421 // Functions for Matrix:
1422 // ---------------------
1423 
1427 {
1428  // Nothing to do here. However, note that the default constructor
1429  // for MatrixView has been called in the initializer list. That is
1430  // crucial, otherwise internal range objects will not be properly
1431  // initialized.
1432 }
1433 
1437  MatrixView( new Numeric[r*c],
1438  Range(0,r,c),
1439  Range(0,c))
1440 {
1441  // Nothing to do here.
1442 }
1443 
1446  MatrixView( new Numeric[r*c],
1447  Range(0,r,c),
1448  Range(0,c))
1449 {
1450  // Here we can access the raw memory directly, for slightly
1451  // increased efficiency:
1452  const Numeric *stop = mdata+r*c;
1453  for ( Numeric *x=mdata; x<stop; ++x )
1454  *x = fill;
1455 }
1456 
1460  MatrixView( new Numeric[m.nrows()*m.ncols()],
1461  Range( 0, m.nrows(), m.ncols() ),
1462  Range( 0, m.ncols() ) )
1463 {
1464  copy(m.begin(),m.end(),begin());
1465 }
1466 
1470  MatrixView( new Numeric[m.nrows()*m.ncols()],
1471  Range( 0, m.nrows(), m.ncols() ),
1472  Range( 0, m.ncols() ) )
1473 {
1474  // There is a catch here: If m is an empty matrix, then it will have
1475  // 0 colunns. But this is used to initialize the stride of the row
1476  // Range! Thus, this method has to be consistent with the behaviour
1477  // of Range::Range. For now, Range::Range allows also stride 0.
1478  copy(m.begin(),m.end(),begin());
1479 }
1480 
1482 
1507 {
1508  // cout << "Matrix copy: m = " << m.nrows() << " " << m.ncols() << "\n";
1509  // cout << " n = " << nrows() << " " << ncols() << "\n";
1510 
1511  resize( m.mrr.mextent, m.mcr.mextent );
1512 
1513  copy( m.begin(), m.end(), begin() );
1514  return *this;
1515 }
1516 
1520 {
1521  copy( x, begin(), end() );
1522  return *this;
1523 }
1524 
1526 
1539 {
1540  resize( v.nelem(), 1 );
1541  ConstMatrixView dummy(v);
1542  copy( dummy.begin(), dummy.end(), begin() );
1543  return *this;
1544 }
1545 
1550 {
1551  assert( 0<=r );
1552  assert( 0<=c );
1553 
1554  if ( mrr.mextent!=r || mcr.mextent!=c )
1555  {
1556  delete[] mdata;
1557  mdata = new Numeric[r*c];
1558 
1559  mrr.mstart = 0;
1560  mrr.mextent = r;
1561  mrr.mstride = c;
1562 
1563  mcr.mstart = 0;
1564  mcr.mextent = c;
1565  mcr.mstride = 1;
1566  }
1567 }
1568 
1572 {
1573 // cout << "Destroying a Matrix:\n"
1574 // << *this << "\n........................................\n";
1575  delete[] mdata;
1576 }
1577 
1578 
1579 // Some general Matrix Vector functions:
1580 
1583 {
1584  // Check dimensions:
1585  assert( a.nelem() == b.nelem() );
1586 
1587  const ConstIterator1D ae = a.end();
1588  ConstIterator1D ai = a.begin();
1589  ConstIterator1D bi = b.begin();
1590 
1591  Numeric res = 0;
1592  for ( ; ai!=ae ; ++ai, ++bi )
1593  res += (*ai) * (*bi);
1594 
1595  return res;
1596 }
1597 
1608  const ConstMatrixView& M,
1609  const ConstVectorView& x )
1610 {
1611  // Check dimensions:
1612  assert( y.mrange.mextent == M.mrr.mextent );
1613  assert( M.mcr.mextent == x.mrange.mextent );
1614  assert( M.mcr.mextent != 0 && M.mrr.mextent != 0);
1615 
1616  // Let's first find the pointers to the starting positions
1617  Numeric *mdata = M.mdata + M.mcr.mstart + M.mrr.mstart;
1618  Numeric *xdata = x.mdata + x.mrange.mstart;
1619  Numeric *yelem = y.mdata + y.mrange.mstart;
1620 
1621  Index i = M.mrr.mextent;
1622  while (i--)
1623  {
1624  Numeric *melem = mdata;
1625  Numeric *xelem = xdata; // Reset xelem to first element of source vector
1626 
1627  // Multiply first element of matrix row with first element of source
1628  // vector. This is done outside the loop to avoid initialization of the
1629  // target vector's element with zero (saves one assignment)
1630  *yelem = *melem * *xelem;
1631 
1632  Index j = M.mcr.mextent; // --j (instead of j-- like in the outer loop)
1633  while (--j) // is important here because we only want
1634  { // mextent-1 cycles
1635  melem += M.mcr.mstride;
1636  xelem += x.mrange.mstride;
1637  *yelem += *melem * *xelem;
1638  }
1639 
1640  mdata += M.mrr.mstride; // Jump to next matrix row
1641  yelem += y.mrange.mstride; // Jump to next element in target vector
1642  }
1643 }
1644 
1645 
1653  const ConstMatrixView& B,
1654  const ConstMatrixView& C )
1655 {
1656  // Check dimensions:
1657  assert( A.nrows() == B.nrows() );
1658  assert( A.ncols() == C.ncols() );
1659  assert( B.ncols() == C.nrows() );
1660 
1661  // Let's get the transpose of C, so that we can use 2D iterators to
1662  // access the columns (= rows of the transpose).
1663  ConstMatrixView CT = transpose(C);
1664 
1665  const Iterator2D ae = A.end();
1666  Iterator2D ai = A.begin();
1667  ConstIterator2D bi = B.begin();
1668 
1669  // This walks through the rows of A and B:
1670  for ( ; ai!=ae ; ++ai, ++bi )
1671  {
1672  const Iterator1D ace = ai->end();
1673  Iterator1D aci = ai->begin();
1674  ConstIterator2D cti = CT.begin();
1675 
1676  // This walks through the columns of A with a 1D iterator, and
1677  // at the same time through the rows of CT, which are the columns of
1678  // C, with a 2D iterator:
1679  for ( ; aci!=ace ; ++aci, ++cti )
1680  {
1681  // The operator * is used to compute the scalar product
1682  // between rows of B and rows of C.transpose().
1683  *aci = (*bi) * (*cti);
1684  }
1685  }
1686 }
1687 
1690 {
1691  return ConstMatrixView(m.mdata, m.mcr, m.mrr);
1692 }
1693 
1697 {
1698  return MatrixView(m.mdata, m.mcr, m.mrr);
1699 }
1700 
1704 {
1705  return transpose((MatrixView)v);
1706 }
1707 
1729  double (&my_func)(double),
1730  ConstVectorView x )
1731 {
1732  // Check dimensions:
1733  assert( y.nelem()==x.nelem() );
1734 
1735  const ConstIterator1D xe = x.end();
1736  ConstIterator1D xi = x.begin();
1737  Iterator1D yi = y.begin();
1738  for ( ; xi!=xe; ++xi, ++yi )
1739  *yi = my_func(*xi);
1740 }
1741 
1761  double (&my_func)(double),
1762  ConstMatrixView x )
1763 {
1764  // Check dimensions:
1765  assert( y.nrows()==x.nrows() );
1766  assert( y.ncols()==x.ncols() );
1767 
1768  const ConstIterator2D rxe = x.end();
1769  ConstIterator2D rx = x.begin();
1770  Iterator2D ry = y.begin();
1771  for ( ; rx!=rxe; ++rx, ++ry )
1772  {
1773  const ConstIterator1D cxe = rx->end();
1774  ConstIterator1D cx = rx->begin();
1775  Iterator1D cy = ry->begin();
1776  for ( ; cx!=cxe; ++cx, ++cy )
1777  *cy = my_func(*cx);
1778  }
1779 }
1780 
1783 {
1784  // Initial value for max:
1785  Numeric max = x[0];
1786 
1787  const ConstIterator1D xe = x.end();
1788  ConstIterator1D xi = x.begin();
1789 
1790  for ( ; xi!=xe ; ++xi )
1791  {
1792  if ( *xi > max )
1793  max = *xi;
1794  }
1795 
1796  return max;
1797 }
1798 
1801 {
1802  // Initial value for max:
1803  Numeric max = x(0,0);
1804 
1805  const ConstIterator2D rxe = x.end();
1806  ConstIterator2D rx = x.begin();
1807 
1808  for ( ; rx!=rxe ; ++rx )
1809  {
1810  const ConstIterator1D cxe = rx->end();
1811  ConstIterator1D cx = rx->begin();
1812 
1813  for ( ; cx!=cxe ; ++cx )
1814  if ( *cx > max )
1815  max = *cx;
1816  }
1817 
1818  return max;
1819 }
1820 
1823 {
1824  // Initial value for min:
1825  Numeric min = x[0];
1826 
1827  const ConstIterator1D xe = x.end();
1828  ConstIterator1D xi = x.begin();
1829 
1830  for ( ; xi!=xe ; ++xi )
1831  {
1832  if ( *xi < min )
1833  min = *xi;
1834  }
1835 
1836  return min;
1837 }
1838 
1841 {
1842  // Initial value for min:
1843  Numeric min = x(0,0);
1844 
1845  const ConstIterator2D rxe = x.end();
1846  ConstIterator2D rx = x.begin();
1847 
1848  for ( ; rx!=rxe ; ++rx )
1849  {
1850  const ConstIterator1D cxe = rx->end();
1851  ConstIterator1D cx = rx->begin();
1852 
1853  for ( ; cx!=cxe ; ++cx )
1854  if ( *cx < min )
1855  min = *cx;
1856  }
1857 
1858  return min;
1859 }
1860 
1863 {
1864  // Initial value for mean:
1865  Numeric mean = 0;
1866 
1867  const ConstIterator1D xe = x.end();
1868  ConstIterator1D xi = x.begin();
1869 
1870  for ( ; xi!=xe ; ++xi ) mean += *xi;
1871 
1872  mean /= (Numeric)x.nelem();
1873 
1874  return mean;
1875 }
1876 
1879 {
1880  // Initial value for mean:
1881  Numeric mean = 0;
1882 
1883  const ConstIterator2D rxe = x.end();
1884  ConstIterator2D rx = x.begin();
1885 
1886  for ( ; rx!=rxe ; ++rx )
1887  {
1888  const ConstIterator1D cxe = rx->end();
1889  ConstIterator1D cx = rx->begin();
1890 
1891  for ( ; cx!=cxe ; ++cx ) mean += *cx;
1892  }
1893 
1894  mean /= (Numeric)(x.nrows()*x.ncols());
1895 
1896  return mean;
1897 }
1898 
1909 {
1910  // cout << "Assigning VectorView from Array<Numeric>.\n";
1911 
1912  // Check that sizes are compatible:
1913  assert(mrange.mextent==v.nelem());
1914 
1915  // Iterators for Array:
1916  Array<Numeric>::const_iterator i=v.begin();
1917  const Array<Numeric>::const_iterator e=v.end();
1918  // Iterator for Vector:
1919  Iterator1D target = begin();
1920 
1921  for ( ; i!=e ; ++i,++target )
1922  *target = *i;
1923 
1924  return *this;
1925 }
1926 
1928 // Helper function for debugging
1929 #ifndef NDEBUG
1930 
1945 {
1946  return mv(r, c);
1947 }
1948 
1949 #endif
1950 
1952 
Matrix
The Matrix class.
Definition: matpackI.h:767
MatrixView::operator()
Numeric operator()(Index r, Index c) const
Plain const index operator.
Definition: matpackI.h:676
transform
void transform(VectorView y, double(&my_func)(double), ConstVectorView x)
A generic transform function for vectors, which can be used to implement mathematical functions opera...
Definition: matpackI.cc:1728
Iterator1D::mx
Numeric * mx
Current position.
Definition: matpackI.h:246
MatrixView
The MatrixView class.
Definition: matpackI.h:668
VectorView::VectorView
VectorView()
Default constructor.
Definition: matpackI.cc:560
exceptions.h
The declarations of all the exception classes.
MatrixView::operator=
MatrixView & operator=(const ConstMatrixView &v)
Assignment operator.
Definition: matpackI.cc:1059
Vector::Vector
Vector()
Default constructor.
Definition: matpackI.cc:624
ConstIterator1D
The constant iterator class for sub vectors.
Definition: matpackI.h:253
MatrixView::MatrixView
MatrixView()
Default constructor.
Definition: matpackI.cc:1344
joker
const Joker joker
ConstIterator1D::mstride
Index mstride
Stride.
Definition: matpackI.h:286
ConstMatrixView::mdata
Numeric * mdata
Pointer to the plain C array that holds the data.
Definition: matpackI.h:656
Vector::resize
void resize(Index n)
Resize function.
Definition: matpackI.cc:771
max
Numeric max(const ConstVectorView &x)
Max function, vector version.
Definition: matpackI.cc:1782
ConstVectorView::ConstVectorView
ConstVectorView()
Default constructor.
Definition: matpackI.cc:237
MatrixView::operator+=
MatrixView & operator+=(Numeric x)
Addition of scalar.
Definition: matpackI.cc:1147
ConstMatrixView::nrows
Index nrows() const
Returns the number of rows.
Definition: matpackI.cc:796
ConstVectorView::mrange
Range mrange
The range of mdata that is actually used.
Definition: matpackI.h:357
Range::mstart
Index mstart
The start index.
Definition: matpackI.h:204
MatrixView::operator-=
MatrixView & operator-=(Numeric x)
Subtraction of scalar.
Definition: matpackI.cc:1160
MatrixView::operator/=
MatrixView & operator/=(Numeric x)
Division by scalar.
Definition: matpackI.cc:1134
ConstMatrixView::mcr
Range mcr
The column range of mdata that is actually used.
Definition: matpackI.h:654
VectorView::operator=
VectorView & operator=(const ConstVectorView &v)
Assignment operator.
Definition: matpackI.cc:368
VectorView::operator/=
VectorView operator/=(Numeric x)
Division by scalar.
Definition: matpackI.cc:429
ConstMatrixView::mrr
Range mrr
The row range of mdata that is actually used.
Definition: matpackI.h:652
matpackI.h
Array< Numeric >
ConstVectorView::end
ConstIterator1D end() const
Return const iterator behind last element.
Definition: matpackI.cc:208
MatrixView::begin
ConstIterator2D begin() const
Return const iterator to first row.
Definition: matpackI.cc:1029
ConstMatrixView::end
ConstIterator2D end() const
Return const iterator behind last row.
Definition: matpackI.cc:855
mult
void mult(VectorView y, const ConstMatrixView &M, const ConstVectorView &x)
Matrix Vector multiplication.
Definition: matpackI.cc:1607
Matrix::~Matrix
virtual ~Matrix()
Destructor for Matrix.
Definition: matpackI.cc:1571
Vector::operator=
Vector & operator=(const Vector &v)
Assignment from another Vector.
Definition: matpackI.cc:718
ConstMatrixView::ncols
Index ncols() const
Returns the number of columns.
Definition: matpackI.cc:802
Iterator1D
The iterator class for sub vectors.
Definition: matpackI.h:214
ConstVectorView::nelem
Index nelem() const
Returns the number of elements.
Definition: matpackI.cc:175
Vector::~Vector
virtual ~Vector()
Destructor for Vector.
Definition: matpackI.cc:786
VectorView
The VectorView class.
Definition: matpackI.h:373
mean
Numeric mean(const ConstVectorView &x)
Mean function, vector version.
Definition: matpackI.cc:1862
ConstVectorView::begin
ConstIterator1D begin() const
Return const iterator to first element.
Definition: matpackI.cc:202
Range::Range
Range(Index start, Index extent, Index stride=1)
Definition: matpackI.cc:47
ConstVectorView::sum
Numeric sum() const
The sum of all elements of a Vector.
Definition: matpackI.cc:181
Numeric
NUMERIC Numeric
The type to use for all floating point numbers.
Definition: matpack.h:33
MatrixView::VectorView
friend class VectorView
Definition: matpackI.h:740
transpose
ConstMatrixView transpose(ConstMatrixView m)
Const version of transpose.
Definition: matpackI.cc:1689
ConstVectorView::mdata
Numeric * mdata
Pointer to the plain C array that holds the data.
Definition: matpackI.h:359
ConstVectorView::operator[]
Numeric operator[](Index n) const
Plain const index operator.
Definition: matpackI.h:311
ConstMatrixView::operator()
Numeric operator()(Index r, Index c) const
Plain const index operator.
Definition: matpackI.h:602
Matrix::resize
void resize(Index r, Index c)
Resize function.
Definition: matpackI.cc:1549
VectorView::begin
ConstIterator1D begin() const
Return const iterator to first element.
Definition: matpackI.cc:336
ConstIterator2D
The const row iterator class for sub matrices.
Definition: matpackI.h:503
ConstMatrixView
A constant view of a Matrix.
Definition: matpackI.h:591
min
Numeric min(const ConstVectorView &x)
Min function, vector version.
Definition: matpackI.cc:1822
Range
The range class.
Definition: matpackI.h:148
Range::mextent
Index mextent
The number of elements.
Definition: matpackI.h:207
MatrixView::end
ConstIterator2D end() const
Return const iterator behind last row.
Definition: matpackI.cc:1035
Matrix::Matrix
Matrix()
Default constructor.
Definition: matpackI.cc:1425
VectorView::operator*=
VectorView operator*=(Numeric x)
Multiplication by scalar.
Definition: matpackI.cc:420
VectorView::operator-=
VectorView operator-=(Numeric x)
Subtraction of scalar.
Definition: matpackI.cc:447
Joker
The Joker class.
Definition: matpackI.h:114
Iterator1D::mstride
Index mstride
Stride.
Definition: matpackI.h:248
operator<<
ostream & operator<<(ostream &os, const ConstVectorView &v)
Output operator.
Definition: matpackI.cc:275
ConstMatrixView::ConstMatrixView
ConstMatrixView()
Default constructor.
Definition: matpackI.cc:864
ConstMatrixView::begin
ConstIterator2D begin() const
Return const iterator to first row.
Definition: matpackI.cc:847
Matrix::operator=
Matrix & operator=(const Matrix &x)
Assignment operator from another matrix.
Definition: matpackI.cc:1506
VectorView::end
ConstIterator1D end() const
Return const iterator behind last element.
Definition: matpackI.cc:344
Iterator2D
The row iterator class for sub matrices.
Definition: matpackI.h:459
operator*
Numeric operator*(const ConstVectorView &a, const ConstVectorView &b)
Scalar product.
Definition: matpackI.cc:1582
Index
INDEX Index
The type to use for all integer numbers and indices.
Definition: matpack.h:39
debug_matrixview_get_elem
Numeric debug_matrixview_get_elem(MatrixView &mv, Index r, Index c)
Helper function to access matrix elements.
Definition: matpackI.cc:1944
MatrixView::operator*=
MatrixView & operator*=(Numeric x)
Multiplication by scalar.
Definition: matpackI.cc:1121
MatrixView::get_c_array
const Numeric * get_c_array() const
Conversion to plain C-array.
Definition: matpackI.cc:1178
M
#define M
Definition: rng.cc:196
ConstMatrixView::ConstVectorView
friend class ConstVectorView
Definition: matpackI.h:630
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
Range::mstride
Index mstride
The stride.
Definition: matpackI.h:209
ConstVectorView
A constant view of a Vector.
Definition: matpackI.h:300
VectorView::operator+=
VectorView operator+=(Numeric x)
Addition of scalar.
Definition: matpackI.cc:438
Array::nelem
Index nelem() const
Number of elements.
Definition: array.h:172
ConstIterator1D::mx
const Numeric * mx
Current position.
Definition: matpackI.h:284
VectorView::get_c_array
const Numeric * get_c_array() const
Conversion to plain C-array.
Definition: matpackI.cc:527
VectorView::operator[]
Numeric operator[](Index n) const
Plain const index operator.
Definition: matpackI.h:384