ARTS  2.2.66
matpackIII.cc
Go to the documentation of this file.
1 /* Copyright (C) 2002-2012 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 using std::runtime_error;
29 
30 
31 // Functions for ConstTensor3View:
32 // ------------------------------
33 
38  const Range& r,
39  const Range& c) const
40 {
41  return ConstTensor3View(mdata, mpr, mrr, mcr, p, r, c);
42 }
43 
47  const Range& r,
48  Index c) const
49 {
50  // Check that c is valid:
51  assert( 0 <= c );
52  assert( c < mcr.mextent );
53 
55  mpr, mrr,
56  p, r);
57 }
58 
62  Index r,
63  const Range& c) const
64 {
65  // Check that r is valid:
66  assert( 0 <= r );
67  assert( r < mrr.mextent );
68 
70  mpr, mcr,
71  p, c);
72 }
73 
77  const Range& r,
78  const Range& c) const
79 {
80  // Check that p is valid:
81  assert( 0 <= p );
82  assert( p < mpr.mextent );
83 
85  mrr, mcr,
86  r, c);
87 }
88 
92  Index r,
93  const Range& c) const
94 {
95  // Check that p and r are valid:
96  assert( 0 <= p );
97  assert( 0 <= r );
98  assert( p < mpr.mextent );
99  assert( r < mrr.mextent );
100 
101  return ConstVectorView(mdata +
102  mpr.mstart + p*mpr.mstride +
103  mrr.mstart + r*mrr.mstride,
104  mcr, c);
105 }
106 
110  const Range& r,
111  Index c) const
112 {
113  // Check that p and c are valid:
114  assert( 0 <= p );
115  assert( 0 <= c );
116  assert( p < mpr.mextent );
117  assert( c < mcr.mextent );
118 
119  return ConstVectorView(mdata +
120  mpr.mstart + p*mpr.mstride +
121  mcr.mstart + c*mcr.mstride,
122  mrr, r);
123 }
124 
128  Index r,
129  Index c) const
130 {
131  // Check that r and c are valid:
132  assert( 0 <= r );
133  assert( 0 <= c );
134  assert( r < mrr.mextent );
135  assert( c < mcr.mextent );
136 
137  return ConstVectorView(mdata +
138  mrr.mstart + r*mrr.mstride +
139  mcr.mstart + c*mcr.mstride,
140  mpr, p);
141 }
142 
145 {
147  mrr,
148  mcr),
149  mpr.mstride);
150 }
151 
154 {
157  mrr,
158  mcr),
159  mpr.mstride );
160 }
161 
164  mpr(0,1,a.mrr.mextent*a.mcr.mextent),
165  mrr(a.mrr),
166  mcr(a.mcr),
167  mdata(a.mdata)
168 {
169  // Nothing to do here.
170 }
171 
175  mpr(0,0,1), mrr(0,0,1), mcr(0,0,1), mdata(NULL)
176 {
177  // Nothing to do here.
178 }
179 
185  const Range& pr,
186  const Range& rr,
187  const Range& cr) :
188  mpr(pr),
189  mrr(rr),
190  mcr(cr),
191  mdata(data)
192 {
193  // Nothing to do here.
194 }
195 
204  const Range& pp,
205  const Range& pr,
206  const Range& pc,
207  const Range& np,
208  const Range& nr,
209  const Range& nc) :
210  mpr(pp,np),
211  mrr(pr,nr),
212  mcr(pc,nc),
213  mdata(data)
214 {
215  // Nothing to do here.
216 }
217 
221 std::ostream& operator<<(std::ostream& os, const ConstTensor3View& v)
222 {
223  // Page iterators:
224  ConstIterator3D ip=v.begin();
225  const ConstIterator3D end_page=v.end();
226 
227  if ( ip!=end_page )
228  {
229  os << *ip;
230  ++ip;
231  }
232 
233  for ( ; ip!=end_page; ++ip )
234  {
235  os << "\n\n";
236  os << *ip;
237  }
238 
239  return os;
240 }
241 
242 
243 // Functions for Tensor3View:
244 // -------------------------
245 
251  const Range& r,
252  const Range& c) const
253 {
254  return ConstTensor3View::operator()(p,r,c);
255 }
256 
262  const Range& r,
263  Index c) const
264 {
265  return ConstTensor3View::operator()(p,r,c);
266 }
267 
273  Index r,
274  const Range& c) const
275 {
276  return ConstTensor3View::operator()(p,r,c);
277 }
278 
284  const Range& r,
285  const Range& c) const
286 {
287  return ConstTensor3View::operator()(p,r,c);
288 }
289 
295  Index r,
296  const Range& c) const
297 {
298  return ConstTensor3View::operator()(p,r,c);
299 }
300 
306  const Range& r,
307  Index c) const
308 {
309  return ConstTensor3View::operator()(p,r,c);
310 }
311 
317  Index r,
318  Index c) const
319 {
320  return ConstTensor3View::operator()(p,r,c);
321 }
322 
323 
328  const Range& r,
329  const Range& c)
330 {
331  return Tensor3View(mdata, mpr, mrr, mcr, p, r, c);
332 }
333 
337  const Range& r,
338  Index c)
339 {
340  // Check that c is valid:
341  assert( 0 <= c );
342  assert( c < mcr.mextent );
343 
344  return MatrixView(mdata + mcr.mstart + c*mcr.mstride,
345  mpr, mrr,
346  p, r);
347 }
348 
352  Index r,
353  const Range& c)
354 {
355  // Check that r is valid:
356  assert( 0 <= r );
357  assert( r < mrr.mextent );
358 
359  return MatrixView(mdata + mrr.mstart + r*mrr.mstride,
360  mpr, mcr,
361  p, c);
362 }
363 
367  const Range& r,
368  const Range& c)
369 {
370  // Check that p is valid:
371  assert( 0 <= p );
372  assert( p < mpr.mextent );
373 
374  return MatrixView(mdata + mpr.mstart + p*mpr.mstride,
375  mrr, mcr,
376  r, c);
377 }
378 
382  Index r,
383  const Range& c)
384 {
385  // Check that p and r are valid:
386  assert( 0 <= p );
387  assert( 0 <= r );
388  assert( p < mpr.mextent );
389  assert( r < mrr.mextent );
390 
391  return VectorView(mdata +
392  mpr.mstart + p*mpr.mstride +
393  mrr.mstart + r*mrr.mstride,
394  mcr, c);
395 }
396 
400  const Range& r,
401  Index c)
402 {
403  // Check that p and c are valid:
404  assert( 0 <= p );
405  assert( 0 <= c );
406  assert( p < mpr.mextent );
407  assert( c < mcr.mextent );
408 
409  return VectorView(mdata +
410  mpr.mstart + p*mpr.mstride +
411  mcr.mstart + c*mcr.mstride,
412  mrr, r);
413 }
414 
418  Index r,
419  Index c)
420 {
421  // Check that r and r are valid:
422  assert( 0 <= r );
423  assert( 0 <= c );
424  assert( r < mrr.mextent );
425  assert( c < mcr.mextent );
426 
427  return VectorView(mdata +
428  mrr.mstart + r*mrr.mstride +
429  mcr.mstart + c*mcr.mstride,
430  mpr, p);
431 }
432 
440 {
441  if (mpr.mstart != 0 || mpr.mstride != mrr.mextent * mcr.mextent
442  || mrr.mstart != 0 || mrr.mstride != mcr.mextent
443  || mcr.mstart != 0 || mcr.mstride != 1)
444  throw std::runtime_error("A Tensor3View can only be converted to a plain C-array if it's pointing to a continuous block of data");
445 
446  return mdata;
447 }
448 
456 {
457  if (mpr.mstart != 0 || mpr.mstride != mrr.mextent * mcr.mextent
458  || mrr.mstart != 0 || mrr.mstride != mcr.mextent
459  || mcr.mstart != 0 || mcr.mstride != 1)
460  throw std::runtime_error("A Tensor3View can only be converted to a plain C-array if it's pointing to a continuous block of data");
461 
462  return mdata;
463 }
464 
468 {
469  return ConstTensor3View::begin();
470 }
471 
474 {
475  return ConstTensor3View::end();
476 }
477 
480 {
482  mrr,
483  mcr),
484  mpr.mstride);
485 }
486 
489 {
490  return Iterator3D( MatrixView(mdata + mpr.mstart +
492  mrr,
493  mcr),
494  mpr.mstride );
495 }
496 
502 {
503  // Check that sizes are compatible:
504  assert(mpr.mextent==m.mpr.mextent);
505  assert(mrr.mextent==m.mrr.mextent);
506  assert(mcr.mextent==m.mcr.mextent);
507 
508  copy( m.begin(), m.end(), begin() );
509  return *this;
510 }
511 
518 {
519  // Check that sizes are compatible:
520  assert(mpr.mextent==m.mpr.mextent);
521  assert(mrr.mextent==m.mrr.mextent);
522  assert(mcr.mextent==m.mcr.mextent);
523 
524  copy( m.begin(), m.end(), begin() );
525  return *this;
526 }
527 
532 {
533  // Check that sizes are compatible:
534  assert(mpr.mextent==m.mpr.mextent);
535  assert(mrr.mextent==m.mrr.mextent);
536  assert(mcr.mextent==m.mcr.mextent);
537 
538  copy( m.begin(), m.end(), begin() );
539  return *this;
540 }
541 
545 {
546  copy( x, begin(), end() );
547  return *this;
548 }
549 
550 // Some little helper functions:
551 //------------------------------
552 
554 {
555  return x+y;
556 }
557 
560 {
561  const Iterator3D ep=end();
562  for ( Iterator3D p=begin(); p!=ep ; ++p )
563  {
564  *p *= x;
565  }
566  return *this;
567 }
568 
571 {
572  const Iterator3D ep=end();
573  for ( Iterator3D p=begin(); p!=ep ; ++p )
574  {
575  *p /= x;
576  }
577  return *this;
578 }
579 
582 {
583  const Iterator3D ep=end();
584  for ( Iterator3D p=begin(); p!=ep ; ++p )
585  {
586  *p += x;
587  }
588  return *this;
589 }
590 
593 {
594  const Iterator3D ep=end();
595  for ( Iterator3D p=begin(); p!=ep ; ++p )
596  {
597  *p -= x;
598  }
599  return *this;
600 }
601 
604 {
605  assert( npages() == x.npages() );
606  assert( nrows() == x.nrows() );
607  assert( ncols() == x.ncols() );
608  ConstIterator3D xp = x.begin();
609  Iterator3D p = begin();
610  const Iterator3D ep = end();
611  for ( ; p!=ep ; ++p,++xp )
612  {
613  *p *= *xp;
614  }
615  return *this;
616 }
617 
620 {
621  assert( npages() == x.npages() );
622  assert( nrows() == x.nrows() );
623  assert( ncols() == x.ncols() );
624  ConstIterator3D xp = x.begin();
625  Iterator3D p = begin();
626  const Iterator3D ep = end();
627  for ( ; p!=ep ; ++p,++xp )
628  {
629  *p /= *xp;
630  }
631  return *this;
632 }
633 
636 {
637  assert( npages() == x.npages() );
638  assert( nrows() == x.nrows() );
639  assert( ncols() == x.ncols() );
640  ConstIterator3D xp = x.begin();
641  Iterator3D p = begin();
642  const Iterator3D ep = end();
643  for ( ; p!=ep ; ++p,++xp )
644  {
645  *p += *xp;
646  }
647  return *this;
648 }
649 
652 {
653  assert( npages() == x.npages() );
654  assert( nrows() == x.nrows() );
655  assert( ncols() == x.ncols() );
656  ConstIterator3D xp = x.begin();
657  Iterator3D p = begin();
658  const Iterator3D ep = end();
659  for ( ; p!=ep ; ++p,++xp )
660  {
661  *p -= *xp;
662  }
663  return *this;
664 }
665 
669  Range(0,1,a.mrr.mextent*a.mcr.mextent),
670  a.mrr,
671  a.mcr )
672 {
673  // Nothing to do here.
674 }
675 
680 {
681  // Nothing to do here.
682 }
683 
688  const Range& pr,
689  const Range& rr,
690  const Range& cr) :
691  ConstTensor3View(data, pr, rr, cr)
692 {
693  // Nothing to do here.
694 }
695 
713  const Range& pp,
714  const Range& pr,
715  const Range& pc,
716  const Range& np,
717  const Range& nr,
718  const Range& nc) :
719  ConstTensor3View(data,pp,pr,pc,np,nr,nc)
720 {
721  // Nothing to do here.
722 }
723 
728 void copy(ConstIterator3D origin,
729  const ConstIterator3D& end,
730  Iterator3D target)
731 {
732  for ( ; origin!=end ; ++origin,++target )
733  {
734  // We use the copy function for the next smaller rank of tensor
735  // recursively:
736  copy(origin->begin(),
737  origin->end(),
738  target->begin());
739  }
740 }
741 
743 void copy(Numeric x,
744  Iterator3D target,
745  const Iterator3D& end)
746 {
747  for ( ; target!=end ; ++target )
748  {
749  // We use the copy function for the next smaller rank of tensor
750  // recursively:
751  copy(x,target->begin(),target->end());
752  }
753 }
754 
755 
756 // Functions for Tensor3:
757 // ---------------------
758 
762 {
763  // Nothing to do here. However, note that the default constructor
764  // for Tensor3View has been called in the initializer list. That is
765  // crucial, otherwise internal range objects will not be properly
766  // initialized.
767 }
768 
772  Tensor3View( new Numeric[p*r*c],
773  Range(0,p,r*c),
774  Range(0,r,c),
775  Range(0,c))
776 {
777  // Nothing to do here.
778 }
779 
782  Tensor3View( new Numeric[p*r*c],
783  Range(0,p,r*c),
784  Range(0,r,c),
785  Range(0,c))
786 {
787  // Here we can access the raw memory directly, for slightly
788  // increased efficiency:
789  const Numeric *stop = mdata+p*r*c;
790  for ( Numeric *x=mdata; x<stop; ++x )
791  *x = fill;
792 }
793 
797  Tensor3View( new Numeric[m.npages()*m.nrows()*m.ncols()],
798  Range( 0, m.npages(), m.nrows()*m.ncols() ),
799  Range( 0, m.nrows(), m.ncols() ),
800  Range( 0, m.ncols() ) )
801 {
802  copy(m.begin(),m.end(),begin());
803 }
804 
808  Tensor3View( new Numeric[m.npages()*m.nrows()*m.ncols()],
809  Range( 0, m.npages(), m.nrows()*m.ncols() ),
810  Range( 0, m.nrows(), m.ncols() ),
811  Range( 0, m.ncols() ) )
812 {
813  // There is a catch here: If m is an empty tensor, then it will have
814  // dimensions of size 0. But these are used to initialize the stride
815  // for higher dimensions! Thus, this method has to be consistent
816  // with the behaviour of Range::Range. For now, Range::Range allows
817  // also stride 0.
818  copy(m.begin(),m.end(),begin());
819 }
820 
822 
846 {
847  swap(*this, x);
848  return *this;
849 }
850 
854 {
855  copy( x, begin(), end() );
856  return *this;
857 }
858 
863 {
864  assert( 0<=p );
865  assert( 0<=r );
866  assert( 0<=c );
867 
868  if ( mpr.mextent!=p ||
869  mrr.mextent!=r ||
870  mcr.mextent!=c )
871  {
872  delete[] mdata;
873  mdata = new Numeric[p*r*c];
874 
875  mpr.mstart = 0;
876  mpr.mextent = p;
877  mpr.mstride = r*c;
878 
879  mrr.mstart = 0;
880  mrr.mextent = r;
881  mrr.mstride = c;
882 
883  mcr.mstart = 0;
884  mcr.mextent = c;
885  mcr.mstride = 1;
886  }
887 }
888 
889 
891 void swap(Tensor3& t1, Tensor3& t2)
892 {
893  std::swap(t1.mpr, t2.mpr);
894  std::swap(t1.mrr, t2.mrr);
895  std::swap(t1.mcr, t2.mcr);
896  std::swap(t1.mdata, t2.mdata);
897 }
898 
899 
903 {
904 // cout << "Destroying a Tensor3:\n"
905 // << *this << "\n........................................\n";
906  delete[] mdata;
907 }
908 
909 
926  double (&my_func)(double),
927  ConstTensor3View x )
928 {
929  // Check dimensions:
930  assert( y.npages() == x.npages() );
931  assert( y.nrows() == x.nrows() );
932  assert( y.ncols() == x.ncols() );
933 
934  const ConstIterator3D xe = x.end();
935  ConstIterator3D xi = x.begin();
936  Iterator3D yi = y.begin();
937  for ( ; xi!=xe; ++xi, ++yi )
938  {
939  // Use the transform function of lower dimensional tensors
940  // recursively:
941  transform(*yi,my_func,*xi);
942  }
943 }
944 
947 {
948  const ConstIterator3D xe = x.end();
949  ConstIterator3D xi = x.begin();
950 
951  // Initial value for max:
952  Numeric themax = max(*xi);
953  ++xi;
954 
955  for ( ; xi!=xe ; ++xi )
956  {
957  // Use the max function of lower dimensional tensors
958  // recursively:
959  Numeric maxi = max(*xi);
960  if ( maxi > themax )
961  themax = maxi;
962  }
963 
964  return themax;
965 }
966 
969 {
970  const ConstIterator3D xe = x.end();
971  ConstIterator3D xi = x.begin();
972 
973  // Initial value for min:
974  Numeric themin = min(*xi);
975  ++xi;
976 
977  for ( ; xi!=xe ; ++xi )
978  {
979  // Use the min function of lower dimensional tensors
980  // recursively:
981  Numeric mini = min(*xi);
982  if ( mini < themin )
983  themin = mini;
984  }
985 
986  return themin;
987 }
988 
989 
991 // Helper function for debugging
992 #ifndef NDEBUG
993 
1009  Index p, Index r, Index c)
1010 {
1011  return tv(p, r, c);
1012 }
1013 
1014 #endif
1015 
1018 
1034  const ConstVectorView B, const ConstMatrixView C){
1035  assert(A.npages() == B.nelem());
1036  assert(A.nrows() == C.nrows());
1037  assert(A.ncols() == C.ncols());
1038 
1039  for(Index ii = 0; ii < B.nelem(); ii++){
1040  A(ii,joker,joker) = C;
1041  A(ii,joker,joker) *= B[ii];
1042  }
1043 }
INDEX Index
The type to use for all integer numbers and indices.
Definition: matpack.h:35
The VectorView class.
Definition: matpackI.h:372
Index mstride
The stride.
Definition: matpackI.h:209
#define C(a, b)
Definition: Faddeeva.cc:254
void swap(Tensor3 &t1, Tensor3 &t2)
Swaps two objects.
Definition: matpackIII.cc:891
Index mstart
The start index.
Definition: matpackI.h:204
ConstIterator2D begin() const
Return const iterator to first row.
Definition: matpackI.cc:1065
Range mcr
The column range of mdata that is actually used.
Definition: matpackIII.h:218
The MatrixView class.
Definition: matpackI.h:679
ConstIterator2D end() const
Return const iterator behind last row.
Definition: matpackI.cc:1071
The range class.
Definition: matpackI.h:148
void copy(ConstIterator3D origin, const ConstIterator3D &end, Iterator3D target)
Copy data between begin and end to target.
Definition: matpackIII.cc:728
Range mpr
The page range of mdata that is actually used.
Definition: matpackIII.h:214
Numeric max(const ConstTensor3View &x)
Max function, tensor version.
Definition: matpackIII.cc:946
Index nrows() const
Returns the number of rows.
Definition: matpackIII.h:146
Tensor3View & operator-=(Numeric x)
Subtraction of scalar.
Definition: matpackIII.cc:592
ConstTensor3View operator()(const Range &p, const Range &r, const Range &c) const
Const index operator for subrange.
Definition: matpackIII.cc:250
Index nelem() const
Returns the number of elements.
Definition: matpackI.cc:180
virtual ~Tensor3()
Destructor for Tensor3.
Definition: matpackIII.cc:902
ConstIterator2D begin() const
Return const iterator to first row.
Definition: matpackI.cc:883
Index ncols() const
Returns the number of columns.
Definition: matpackI.cc:838
The Tensor3 class.
Definition: matpackIII.h:348
ConstIterator3D end() const
Return const iterator behind last page.
Definition: matpackIII.cc:153
Tensor3View & operator/=(Numeric x)
Division by scalar.
Definition: matpackIII.cc:570
Tensor3()
Default constructor.
Definition: matpackIII.cc:760
ConstTensor3View()
Default constructor.
Definition: matpackIII.cc:174
friend class Tensor3View
Definition: matpackIII.h:192
Index ncols() const
Returns the number of columns.
Definition: matpackIII.h:149
The Tensor3View class.
Definition: matpackIII.h:232
Tensor3View & operator*=(Numeric x)
Multiplication by scalar.
Definition: matpackIII.cc:559
The declarations of all the exception classes.
ConstIterator2D end() const
Return const iterator behind last row.
Definition: matpackI.cc:891
Numeric debug_tensor3view_get_elem(Tensor3View &tv, Index p, Index r, Index c)
Helper function to access tensor elements.
Definition: matpackIII.cc:1008
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:925
const Joker joker
friend void swap(Tensor3 &t1, Tensor3 &t2)
Swaps two objects.
Definition: matpackIII.cc:891
NUMERIC Numeric
The type to use for all floating point numbers.
Definition: matpack.h:29
Index mextent
The number of elements.
Definition: matpackI.h:207
void resize(Index p, Index r, Index c)
Resize function.
Definition: matpackIII.cc:862
Numeric min(const ConstTensor3View &x)
Min function, tensor version.
Definition: matpackIII.cc:968
Index npages() const
Returns the number of pages.
Definition: matpackIII.h:143
ConstIterator3D begin() const
Return const iterator to first page.
Definition: matpackIII.cc:144
A constant view of a Tensor3.
Definition: matpackIII.h:139
A constant view of a Vector.
Definition: matpackI.h:292
Tensor3View & operator+=(Numeric x)
Addition of scalar.
Definition: matpackIII.cc:581
ConstTensor3View operator()(const Range &p, const Range &r, const Range &c) const
Const index operator for subrange.
Definition: matpackIII.cc:37
Numeric * mdata
Pointer to the plain C array that holds the data.
Definition: matpackIII.h:220
A constant view of a Matrix.
Definition: matpackI.h:596
ConstIterator3D begin() const
Return const iterator to first row.
Definition: matpackIII.cc:467
Implementation of Tensors of Rank 3.
Definition: matpackIII.h:34
Tensor3View & operator=(const ConstTensor3View &v)
Assignment operator.
Definition: matpackIII.cc:501
Range mrr
The row range of mdata that is actually used.
Definition: matpackIII.h:216
Tensor3View()
Default constructor.
Definition: matpackIII.cc:678
const Numeric * get_c_array() const
Conversion to plain C-array.
Definition: matpackIII.cc:455
std::ostream & operator<<(std::ostream &os, const ConstTensor3View &v)
Output operator.
Definition: matpackIII.cc:221
Const version of Iterator3D.
Definition: matpackIII.h:78
Tensor3 & operator=(Tensor3 x)
Assignment operator from another tensor.
Definition: matpackIII.cc:845
Index nrows() const
Returns the number of rows.
Definition: matpackI.cc:832
ConstIterator3D end() const
Return const iterator behind last row.
Definition: matpackIII.cc:473
void mult(Tensor3View A, const ConstVectorView B, const ConstMatrixView C)
mult Tensor3
Definition: matpackIII.cc:1033
Numeric add(Numeric x, Numeric y)
Definition: matpackIII.cc:553