ARTS  2.0.49
matpackIII.cc
Go to the documentation of this file.
1 /* Copyright (C) 2002-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 "matpackIII.h"
26 #include "exceptions.h"
27 
28 // Functions for ConstTensor3View:
29 // ------------------------------
30 
35  const Range& r,
36  const Range& c) const
37 {
38  return ConstTensor3View(mdata, mpr, mrr, mcr, p, r, c);
39 }
40 
44  const Range& r,
45  Index c) const
46 {
47  // Check that c is valid:
48  assert( 0 <= c );
49  assert( c < mcr.mextent );
50 
52  mpr, mrr,
53  p, r);
54 }
55 
59  Index r,
60  const Range& c) const
61 {
62  // Check that r is valid:
63  assert( 0 <= r );
64  assert( r < mrr.mextent );
65 
67  mpr, mcr,
68  p, c);
69 }
70 
74  const Range& r,
75  const Range& c) const
76 {
77  // Check that p is valid:
78  assert( 0 <= p );
79  assert( p < mpr.mextent );
80 
82  mrr, mcr,
83  r, c);
84 }
85 
89  Index r,
90  const Range& c) const
91 {
92  // Check that p and r are valid:
93  assert( 0 <= p );
94  assert( 0 <= r );
95  assert( p < mpr.mextent );
96  assert( r < mrr.mextent );
97 
98  return ConstVectorView(mdata +
99  mpr.mstart + p*mpr.mstride +
100  mrr.mstart + r*mrr.mstride,
101  mcr, c);
102 }
103 
107  const Range& r,
108  Index c) const
109 {
110  // Check that p and c are valid:
111  assert( 0 <= p );
112  assert( 0 <= c );
113  assert( p < mpr.mextent );
114  assert( c < mcr.mextent );
115 
116  return ConstVectorView(mdata +
117  mpr.mstart + p*mpr.mstride +
118  mcr.mstart + c*mcr.mstride,
119  mrr, r);
120 }
121 
125  Index r,
126  Index c) const
127 {
128  // Check that r and c are valid:
129  assert( 0 <= r );
130  assert( 0 <= c );
131  assert( r < mrr.mextent );
132  assert( c < mcr.mextent );
133 
134  return ConstVectorView(mdata +
135  mrr.mstart + r*mrr.mstride +
136  mcr.mstart + c*mcr.mstride,
137  mpr, p);
138 }
139 
142 {
144  mrr,
145  mcr),
146  mpr.mstride);
147 }
148 
151 {
154  mrr,
155  mcr),
156  mpr.mstride );
157 }
158 
161  mpr(0,1,a.mrr.mextent*a.mcr.mextent),
162  mrr(a.mrr),
163  mcr(a.mcr),
164  mdata(a.mdata)
165 {
166  // Nothing to do here.
167 }
168 
172  mpr(0,0,1), mrr(0,0,1), mcr(0,0,1), mdata(NULL)
173 {
174  // Nothing to do here.
175 }
176 
182  const Range& pr,
183  const Range& rr,
184  const Range& cr) :
185  mpr(pr),
186  mrr(rr),
187  mcr(cr),
188  mdata(data)
189 {
190  // Nothing to do here.
191 }
192 
201  const Range& pp,
202  const Range& pr,
203  const Range& pc,
204  const Range& np,
205  const Range& nr,
206  const Range& nc) :
207  mpr(pp,np),
208  mrr(pr,nr),
209  mcr(pc,nc),
210  mdata(data)
211 {
212  // Nothing to do here.
213 }
214 
218 ostream& operator<<(ostream& os, const ConstTensor3View& v)
219 {
220  // Page iterators:
221  ConstIterator3D ip=v.begin();
222  const ConstIterator3D end_page=v.end();
223 
224  if ( ip!=end_page )
225  {
226  os << *ip;
227  ++ip;
228  }
229 
230  for ( ; ip!=end_page; ++ip )
231  {
232  os << "\n\n";
233  os << *ip;
234  }
235 
236  return os;
237 }
238 
239 
240 // Functions for Tensor3View:
241 // -------------------------
242 
248  const Range& r,
249  const Range& c) const
250 {
251  return ConstTensor3View::operator()(p,r,c);
252 }
253 
259  const Range& r,
260  Index c) const
261 {
262  return ConstTensor3View::operator()(p,r,c);
263 }
264 
270  Index r,
271  const Range& c) const
272 {
273  return ConstTensor3View::operator()(p,r,c);
274 }
275 
281  const Range& r,
282  const Range& c) const
283 {
284  return ConstTensor3View::operator()(p,r,c);
285 }
286 
292  Index r,
293  const Range& c) const
294 {
295  return ConstTensor3View::operator()(p,r,c);
296 }
297 
303  const Range& r,
304  Index c) const
305 {
306  return ConstTensor3View::operator()(p,r,c);
307 }
308 
314  Index r,
315  Index c) const
316 {
317  return ConstTensor3View::operator()(p,r,c);
318 }
319 
320 
325  const Range& r,
326  const Range& c)
327 {
328  return Tensor3View(mdata, mpr, mrr, mcr, p, r, c);
329 }
330 
334  const Range& r,
335  Index c)
336 {
337  // Check that c is valid:
338  assert( 0 <= c );
339  assert( c < mcr.mextent );
340 
341  return MatrixView(mdata + mcr.mstart + c*mcr.mstride,
342  mpr, mrr,
343  p, r);
344 }
345 
349  Index r,
350  const Range& c)
351 {
352  // Check that r is valid:
353  assert( 0 <= r );
354  assert( r < mrr.mextent );
355 
356  return MatrixView(mdata + mrr.mstart + r*mrr.mstride,
357  mpr, mcr,
358  p, c);
359 }
360 
364  const Range& r,
365  const Range& c)
366 {
367  // Check that p is valid:
368  assert( 0 <= p );
369  assert( p < mpr.mextent );
370 
371  return MatrixView(mdata + mpr.mstart + p*mpr.mstride,
372  mrr, mcr,
373  r, c);
374 }
375 
379  Index r,
380  const Range& c)
381 {
382  // Check that p and r are valid:
383  assert( 0 <= p );
384  assert( 0 <= r );
385  assert( p < mpr.mextent );
386  assert( r < mrr.mextent );
387 
388  return VectorView(mdata +
389  mpr.mstart + p*mpr.mstride +
390  mrr.mstart + r*mrr.mstride,
391  mcr, c);
392 }
393 
397  const Range& r,
398  Index c)
399 {
400  // Check that p and c are valid:
401  assert( 0 <= p );
402  assert( 0 <= c );
403  assert( p < mpr.mextent );
404  assert( c < mcr.mextent );
405 
406  return VectorView(mdata +
407  mpr.mstart + p*mpr.mstride +
408  mcr.mstart + c*mcr.mstride,
409  mrr, r);
410 }
411 
415  Index r,
416  Index c)
417 {
418  // Check that r and r are valid:
419  assert( 0 <= r );
420  assert( 0 <= c );
421  assert( r < mrr.mextent );
422  assert( c < mcr.mextent );
423 
424  return VectorView(mdata +
425  mrr.mstart + r*mrr.mstride +
426  mcr.mstart + c*mcr.mstride,
427  mpr, p);
428 }
429 
437 {
438  if (mpr.mstart != 0 || mpr.mstride != mrr.mextent * mcr.mextent
439  || mrr.mstart != 0 || mrr.mstride != mcr.mextent
440  || mcr.mstart != 0 || mcr.mstride != 1)
441  throw runtime_error("A Tensor3View can only be converted to a plain C-array if mpr.mstart == 0 and mpr.mstride == mrr.extent*mcr.extent and mrr.mstart == 0 and mrr.mstride == mcr.extent and mcr.mstart == 0 and mcr.mstride == 1");
442 
443  return mdata;
444 }
445 
453 {
454  if (mpr.mstart != 0 || mpr.mstride != mrr.mextent * mcr.mextent
455  || mrr.mstart != 0 || mrr.mstride != mcr.mextent
456  || mcr.mstart != 0 || mcr.mstride != 1)
457  throw runtime_error("A Tensor3View can only be converted to a plain C-array if mpr.mstart == 0 and mpr.mstride == mrr.extent*mcr.extent and mrr.mstart == 0 and mrr.mstride == mcr.extent and mcr.mstart == 0 and mcr.mstride == 1");
458 
459  return mdata;
460 }
461 
465 {
466  return ConstTensor3View::begin();
467 }
468 
471 {
472  return ConstTensor3View::end();
473 }
474 
477 {
479  mrr,
480  mcr),
481  mpr.mstride);
482 }
483 
486 {
487  return Iterator3D( MatrixView(mdata + mpr.mstart +
489  mrr,
490  mcr),
491  mpr.mstride );
492 }
493 
499 {
500  // Check that sizes are compatible:
501  assert(mpr.mextent==m.mpr.mextent);
502  assert(mrr.mextent==m.mrr.mextent);
503  assert(mcr.mextent==m.mcr.mextent);
504 
505  copy( m.begin(), m.end(), begin() );
506  return *this;
507 }
508 
515 {
516  // Check that sizes are compatible:
517  assert(mpr.mextent==m.mpr.mextent);
518  assert(mrr.mextent==m.mrr.mextent);
519  assert(mcr.mextent==m.mcr.mextent);
520 
521  copy( m.begin(), m.end(), begin() );
522  return *this;
523 }
524 
529 {
530  // Check that sizes are compatible:
531  assert(mpr.mextent==m.mpr.mextent);
532  assert(mrr.mextent==m.mrr.mextent);
533  assert(mcr.mextent==m.mcr.mextent);
534 
535  copy( m.begin(), m.end(), begin() );
536  return *this;
537 }
538 
542 {
543  copy( x, begin(), end() );
544  return *this;
545 }
546 
547 // Some little helper functions:
548 //------------------------------
549 
551 {
552  return x+y;
553 }
554 
557 {
558  const Iterator3D ep=end();
559  for ( Iterator3D p=begin(); p!=ep ; ++p )
560  {
561  *p *= x;
562  }
563  return *this;
564 }
565 
568 {
569  const Iterator3D ep=end();
570  for ( Iterator3D p=begin(); p!=ep ; ++p )
571  {
572  *p /= x;
573  }
574  return *this;
575 }
576 
579 {
580  const Iterator3D ep=end();
581  for ( Iterator3D p=begin(); p!=ep ; ++p )
582  {
583  *p += x;
584  }
585  return *this;
586 }
587 
590 {
591  const Iterator3D ep=end();
592  for ( Iterator3D p=begin(); p!=ep ; ++p )
593  {
594  *p -= x;
595  }
596  return *this;
597 }
598 
601 {
602  assert( npages() == x.npages() );
603  assert( nrows() == x.nrows() );
604  assert( ncols() == x.ncols() );
605  ConstIterator3D xp = x.begin();
606  Iterator3D p = begin();
607  const Iterator3D ep = end();
608  for ( ; p!=ep ; ++p,++xp )
609  {
610  *p *= *xp;
611  }
612  return *this;
613 }
614 
617 {
618  assert( npages() == x.npages() );
619  assert( nrows() == x.nrows() );
620  assert( ncols() == x.ncols() );
621  ConstIterator3D xp = x.begin();
622  Iterator3D p = begin();
623  const Iterator3D ep = end();
624  for ( ; p!=ep ; ++p,++xp )
625  {
626  *p /= *xp;
627  }
628  return *this;
629 }
630 
633 {
634  assert( npages() == x.npages() );
635  assert( nrows() == x.nrows() );
636  assert( ncols() == x.ncols() );
637  ConstIterator3D xp = x.begin();
638  Iterator3D p = begin();
639  const Iterator3D ep = end();
640  for ( ; p!=ep ; ++p,++xp )
641  {
642  *p += *xp;
643  }
644  return *this;
645 }
646 
649 {
650  assert( npages() == x.npages() );
651  assert( nrows() == x.nrows() );
652  assert( ncols() == x.ncols() );
653  ConstIterator3D xp = x.begin();
654  Iterator3D p = begin();
655  const Iterator3D ep = end();
656  for ( ; p!=ep ; ++p,++xp )
657  {
658  *p -= *xp;
659  }
660  return *this;
661 }
662 
665  ConstTensor3View( a.mdata,
666  Range(0,1,a.mrr.mextent*a.mcr.mextent),
667  a.mrr,
668  a.mcr )
669 {
670  // Nothing to do here.
671 }
672 
677 {
678  // Nothing to do here.
679 }
680 
685  const Range& pr,
686  const Range& rr,
687  const Range& cr) :
688  ConstTensor3View(data, pr, rr, cr)
689 {
690  // Nothing to do here.
691 }
692 
710  const Range& pp,
711  const Range& pr,
712  const Range& pc,
713  const Range& np,
714  const Range& nr,
715  const Range& nc) :
716  ConstTensor3View(data,pp,pr,pc,np,nr,nc)
717 {
718  // Nothing to do here.
719 }
720 
725 void copy(ConstIterator3D origin,
726  const ConstIterator3D& end,
727  Iterator3D target)
728 {
729  for ( ; origin!=end ; ++origin,++target )
730  {
731  // We use the copy function for the next smaller rank of tensor
732  // recursively:
733  copy(origin->begin(),
734  origin->end(),
735  target->begin());
736  }
737 }
738 
740 void copy(Numeric x,
741  Iterator3D target,
742  const Iterator3D& end)
743 {
744  for ( ; target!=end ; ++target )
745  {
746  // We use the copy function for the next smaller rank of tensor
747  // recursively:
748  copy(x,target->begin(),target->end());
749  }
750 }
751 
752 
753 // Functions for Tensor3:
754 // ---------------------
755 
759 {
760  // Nothing to do here. However, note that the default constructor
761  // for Tensor3View has been called in the initializer list. That is
762  // crucial, otherwise internal range objects will not be properly
763  // initialized.
764 }
765 
769  Tensor3View( new Numeric[p*r*c],
770  Range(0,p,r*c),
771  Range(0,r,c),
772  Range(0,c))
773 {
774  // Nothing to do here.
775 }
776 
779  Tensor3View( new Numeric[p*r*c],
780  Range(0,p,r*c),
781  Range(0,r,c),
782  Range(0,c))
783 {
784  // Here we can access the raw memory directly, for slightly
785  // increased efficiency:
786  const Numeric *stop = mdata+p*r*c;
787  for ( Numeric *x=mdata; x<stop; ++x )
788  *x = fill;
789 }
790 
794  Tensor3View( new Numeric[m.npages()*m.nrows()*m.ncols()],
795  Range( 0, m.npages(), m.nrows()*m.ncols() ),
796  Range( 0, m.nrows(), m.ncols() ),
797  Range( 0, m.ncols() ) )
798 {
799  copy(m.begin(),m.end(),begin());
800 }
801 
805  Tensor3View( new Numeric[m.npages()*m.nrows()*m.ncols()],
806  Range( 0, m.npages(), m.nrows()*m.ncols() ),
807  Range( 0, m.nrows(), m.ncols() ),
808  Range( 0, m.ncols() ) )
809 {
810  // There is a catch here: If m is an empty tensor, then it will have
811  // dimensions of size 0. But these are used to initialize the stride
812  // for higher dimensions! Thus, this method has to be consistent
813  // with the behaviour of Range::Range. For now, Range::Range allows
814  // also stride 0.
815  copy(m.begin(),m.end(),begin());
816 }
817 
819 
843 {
844  // cout << "Tensor3 copy: m = " << m.nrows() << " " << m.ncols() << "\n";
845  // cout << " n = " << nrows() << " " << ncols() << "\n";
846 
847  resize( m.mpr.mextent, m.mrr.mextent, m.mcr.mextent );
848  copy( m.begin(), m.end(), begin() );
849  return *this;
850 }
851 
855 {
856  copy( x, begin(), end() );
857  return *this;
858 }
859 
864 {
865  assert( 0<=p );
866  assert( 0<=r );
867  assert( 0<=c );
868 
869  if ( mpr.mextent!=p ||
870  mrr.mextent!=r ||
871  mcr.mextent!=c )
872  {
873  delete[] mdata;
874  mdata = new Numeric[p*r*c];
875 
876  mpr.mstart = 0;
877  mpr.mextent = p;
878  mpr.mstride = r*c;
879 
880  mrr.mstart = 0;
881  mrr.mextent = r;
882  mrr.mstride = c;
883 
884  mcr.mstart = 0;
885  mcr.mextent = c;
886  mcr.mstride = 1;
887  }
888 }
889 
893 {
894 // cout << "Destroying a Tensor3:\n"
895 // << *this << "\n........................................\n";
896  delete[] mdata;
897 }
898 
899 
916  double (&my_func)(double),
917  ConstTensor3View x )
918 {
919  // Check dimensions:
920  assert( y.npages() == x.npages() );
921  assert( y.nrows() == x.nrows() );
922  assert( y.ncols() == x.ncols() );
923 
924  const ConstIterator3D xe = x.end();
925  ConstIterator3D xi = x.begin();
926  Iterator3D yi = y.begin();
927  for ( ; xi!=xe; ++xi, ++yi )
928  {
929  // Use the transform function of lower dimensional tensors
930  // recursively:
931  transform(*yi,my_func,*xi);
932  }
933 }
934 
937 {
938  const ConstIterator3D xe = x.end();
939  ConstIterator3D xi = x.begin();
940 
941  // Initial value for max:
942  Numeric themax = max(*xi);
943  ++xi;
944 
945  for ( ; xi!=xe ; ++xi )
946  {
947  // Use the max function of lower dimensional tensors
948  // recursively:
949  Numeric maxi = max(*xi);
950  if ( maxi > themax )
951  themax = maxi;
952  }
953 
954  return themax;
955 }
956 
959 {
960  const ConstIterator3D xe = x.end();
961  ConstIterator3D xi = x.begin();
962 
963  // Initial value for min:
964  Numeric themin = min(*xi);
965  ++xi;
966 
967  for ( ; xi!=xe ; ++xi )
968  {
969  // Use the min function of lower dimensional tensors
970  // recursively:
971  Numeric mini = min(*xi);
972  if ( mini < themin )
973  themin = mini;
974  }
975 
976  return themin;
977 }
978 
979 
981 // Helper function for debugging
982 #ifndef NDEBUG
983 
999  Index p, Index r, Index c)
1000 {
1001  return tv(p, r, c);
1002 }
1003 
1004 #endif
1005 
Tensor3View::Tensor3View
Tensor3View()
Default constructor.
Definition: matpackIII.cc:675
Tensor3View::end
ConstIterator3D end() const
Return const iterator behind last row.
Definition: matpackIII.cc:470
MatrixView
The MatrixView class.
Definition: matpackI.h:668
exceptions.h
The declarations of all the exception classes.
ConstTensor3View::operator()
ConstTensor3View operator()(const Range &p, const Range &r, const Range &c) const
Const index operator for subrange.
Definition: matpackIII.cc:34
operator<<
ostream & operator<<(ostream &os, const ConstTensor3View &v)
Output operator.
Definition: matpackIII.cc:218
Tensor3
The Tensor3 class.
Definition: matpackIII.h:340
ConstIterator3D
Const version of Iterator3D.
Definition: matpackIII.h:82
ConstTensor3View::ConstTensor3View
ConstTensor3View()
Default constructor.
Definition: matpackIII.cc:171
Tensor3View::operator()
ConstTensor3View operator()(const Range &p, const Range &r, const Range &c) const
Const index operator for subrange.
Definition: matpackIII.cc:247
Tensor3::~Tensor3
virtual ~Tensor3()
Destructor for Tensor3.
Definition: matpackIII.cc:892
Range::mstart
Index mstart
The start index.
Definition: matpackI.h:204
add
Numeric add(Numeric x, Numeric y)
Definition: matpackIII.cc:550
Tensor3::resize
void resize(Index p, Index r, Index c)
Resize function.
Definition: matpackIII.cc:863
Tensor3View::operator-=
Tensor3View & operator-=(Numeric x)
Subtraction of scalar.
Definition: matpackIII.cc:589
ConstTensor3View::npages
Index npages() const
Returns the number of pages.
Definition: matpackIII.h:151
Tensor3View
The Tensor3View class.
Definition: matpackIII.h:234
Iterator3D
Implementation of Tensors of Rank 3.
Definition: matpackIII.h:34
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
ConstTensor3View::begin
ConstIterator3D begin() const
Return const iterator to first page.
Definition: matpackIII.cc:141
ConstTensor3View::mrr
Range mrr
The row range of mdata that is actually used.
Definition: matpackIII.h:218
ConstTensor3View::mcr
Range mcr
The column range of mdata that is actually used.
Definition: matpackIII.h:220
VectorView
The VectorView class.
Definition: matpackI.h:373
ConstTensor3View::mpr
Range mpr
The page range of mdata that is actually used.
Definition: matpackIII.h:216
Numeric
NUMERIC Numeric
The type to use for all floating point numbers.
Definition: matpack.h:33
transform
void transform(Tensor3View y, double(&my_func)(double), ConstTensor3View x)
A generic transform function for tensors, which can be used to implement mathematical functions opera...
Definition: matpackIII.cc:915
ConstTensor3View::mdata
Numeric * mdata
Pointer to the plain C array that holds the data.
Definition: matpackIII.h:222
matpackIII.h
debug_tensor3view_get_elem
Numeric debug_tensor3view_get_elem(Tensor3View &tv, Index p, Index r, Index c)
Helper function to access tensor elements.
Definition: matpackIII.cc:998
Tensor3View::operator/=
Tensor3View & operator/=(Numeric x)
Division by scalar.
Definition: matpackIII.cc:567
ConstTensor3View::nrows
Index nrows() const
Returns the number of rows.
Definition: matpackIII.h:154
ConstMatrixView
A constant view of a Matrix.
Definition: matpackI.h:591
Tensor3View::operator*=
Tensor3View & operator*=(Numeric x)
Multiplication by scalar.
Definition: matpackIII.cc:556
ConstTensor3View::end
ConstIterator3D end() const
Return const iterator behind last page.
Definition: matpackIII.cc:150
Range
The range class.
Definition: matpackI.h:148
max
Numeric max(const ConstTensor3View &x)
Max function, tensor version.
Definition: matpackIII.cc:936
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
ConstTensor3View::ncols
Index ncols() const
Returns the number of columns.
Definition: matpackIII.h:157
Tensor3View::begin
ConstIterator3D begin() const
Return const iterator to first row.
Definition: matpackIII.cc:464
ConstTensor3View
A constant view of a Tensor3.
Definition: matpackIII.h:147
Tensor3::operator=
Tensor3 & operator=(const Tensor3 &x)
Assignment operator from another tensor.
Definition: matpackIII.cc:842
ConstMatrixView::begin
ConstIterator2D begin() const
Return const iterator to first row.
Definition: matpackI.cc:847
Tensor3View::operator+=
Tensor3View & operator+=(Numeric x)
Addition of scalar.
Definition: matpackIII.cc:578
Index
INDEX Index
The type to use for all integer numbers and indices.
Definition: matpack.h:39
Tensor3View::operator=
Tensor3View & operator=(const ConstTensor3View &v)
Assignment operator.
Definition: matpackIII.cc:498
Tensor3View::get_c_array
const Numeric * get_c_array() const
Conversion to plain C-array.
Definition: matpackIII.cc:452
min
Numeric min(const ConstTensor3View &x)
Min function, tensor version.
Definition: matpackIII.cc:958
Range::mstride
Index mstride
The stride.
Definition: matpackI.h:209
ConstVectorView
A constant view of a Vector.
Definition: matpackI.h:300
Tensor3::Tensor3
Tensor3()
Default constructor.
Definition: matpackIII.cc:757
copy
void copy(ConstIterator3D origin, const ConstIterator3D &end, Iterator3D target)
Copy data between begin and end to target.
Definition: matpackIII.cc:725