ARTS  1.0.222
math_funcs.cc
Go to the documentation of this file.
1 /* Copyright (C) 2000, 2001 Patrick Eriksson <patrick@rss.chalmers.se>
2  Stefan Buehler <sbuehler@uni-bremen.de>
3 
4  This program is free software; you can redistribute it and/or modify it
5  under the terms of the GNU General Public License as published by the
6  Free Software Foundation; either version 2, or (at your option) any
7  later version.
8 
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with this program; if not, write to the Free Software
16  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
17  USA. */
18 
19 
20 
22 // File description
24 
44 // External declarations
47 
48 #include <time.h>
49 #include <math.h>
50 #include <stdexcept>
51 #include "arts.h"
52 #include "math_funcs.h"
53 #include "make_vector.h"
54 #include "array.h"
55 
56 
57 
61 //
71 {
72  return x[0];
73 }
74 
84 {
85  return x[x.nelem()-1];
86 }
87 
88 
89 
91 // Logical functions
93 
95 //
104 bool any( const ArrayOfIndex& x )
105 {
106  for ( Index i=0; i<x.nelem(); i++ ) {
107  if ( x[i] )
108  return true;
109  }
110  return false;
111 }
112 
113 
114 
115 
117 // Functions to generate vectors
119 
121 //
139 void linspace(
140  Vector& x,
141  const Numeric start,
142  const Numeric stop,
143  const Numeric step )
144 {
145  Index n = (Index) floor( (stop-start)/step ) + 1;
146  if ( n<1 )
147  n=1;
148  x.resize(n);
149  for ( Index i=0; i<n; i++ )
150  x[i] = start + (Numeric)i*step;
151 }
152 
168 void nlinspace(
169  Vector& x,
170  const Numeric start,
171  const Numeric stop,
172  const Index n )
173 {
174  assert( 1<n ); // Number of points must be greatere 1.
175  x.resize(n);
176  Numeric step = (stop-start)/(Numeric)(n-1) ;
177  for ( Index i=0; i<n; i++ )
178  x[i] = start + (Numeric)i*step;
179 }
180 
182 //
198 void nlogspace(
199  Vector& x,
200  const Numeric start,
201  const Numeric stop,
202  const Index n )
203 {
204  // Number of points must be greatere 1:
205  assert( 1<n );
206  // Only positive numbers are allowed for start and stop:
207  assert( 0<start );
208  assert( 0<stop );
209 
210  x.resize(n);
211  Numeric a = log(start);
212  Numeric step = (log(stop)-a)/(Numeric)(n-1);
213  x[0] = start;
214  for ( Index i=1; i<n-1; i++ )
215  x[i] = exp(a + (Numeric)i*step);
216  x[n-1] = stop;
217 }
218 
235  const Numeric start,
236  const Numeric stop,
237  const Index n )
238 {
239  Vector x;
240  nlogspace( x, start, stop, n );
241  return x;
242 }
243 
244 
245 
246 
248 // Interpolation routines
250 
260  ConstVectorView xi,
261  const Index n_y )
262 {
263  const Index n = x.nelem();
264  const Index ni = xi.nelem();
265  Index order=1; // flag for pos. or neg. order, assume pos.
266 
267  // Determine the order, -1=decreasing and 1=increasing
268  if ( x[0] > x[n-1] )
269  order = -1;
270 
271  if ( n < 2 )
272  throw runtime_error("Vector length for interpolation must be >= 2.");
273 
274  if ( n != n_y )
275  throw runtime_error("Sizes of input data to interpolation do not match.");
276 
277  // Make lower and upper bounds tolerate the new point to be half a
278  // grid distance outside the original grid.
279  const Numeric lower_bound = x[0] - 0.5*(x[1]-x[0]);
280  const Numeric upper_bound = x[n-1] + 0.5*(x[n-1]-x[n-2]);
281 
282  if ( ((Numeric)order*xi[0]<(Numeric)order*lower_bound)
283  || ((Numeric)order*xi[ni-1]>(Numeric)order*upper_bound) )
284  {
285  ostringstream os;
286  os << "Interpolation points must be not more than\n"
287  << "half a grid spacing outside the original range.\n"
288  << "Int.: xi[0] = " << xi[0] << ", xi[ni-1] = " << xi[ni-1] << '\n'
289  << "Orig.: x[0] = " << x[0] << ", x[n-1] = " << x[n-1];
290  throw runtime_error(os.str());
291  }
292 
293  for ( Index i=0; i<n-1; i++ )
294  {
295  if ( (Numeric)order*x[i+1] < (Numeric)order*x[i] )
296  throw runtime_error("Original interpolation grid must be ordered");
297  }
298 
299  for ( Index i=0; i<ni-1; i++ )
300  {
301  if ( (Numeric)order*xi[i+1] < (Numeric)order*xi[i] )
302  throw runtime_error("Interpolation points must be ordered");
303  }
304 
305  return order;
306 }
307 
330  ConstVectorView x,
331  ConstVectorView y,
332  ConstVectorView xi )
333 {
334  // Check grids and get order of grids
335  Index order = interp_check( x, xi, y.nelem() );
336 
337  Index i, j=0;
338  const Index n=xi.nelem();
339  const Index nx=x.nelem();
340  Numeric w;
341 
342  // Check that output vector has the right size:
343  assert( n==yi.nelem() );
344 
345  for ( i=0; i<n; i++ )
346  {
347  // Find right place:
348  while ( j<nx-2 && (Numeric)order*x[j+1]<(Numeric)order*xi[i] )
349  {
350  ++j;
351  }
352  // j should now point to the place in the old grid below the
353  // interpolation point. If the interpolation point is below the
354  // original grid, j=0. If the interpolation point is above the
355  // original grid, j=nx-2.
356 
357  assert( x[j+1]!=x[j] );
358  w = (xi[i]-x[j]) / (x[j+1]-x[j]);
359  // This expression should also be correct for points just outside
360  // the original grid. In that case w can be negative or larger
361  // than 1.
362  yi[i] = y[j] + w * (y[j+1]-y[j]);
363  }
364 }
365 
384  MatrixView Yi,
385  ConstVectorView x,
386  ConstMatrixView Y,
387  ConstVectorView xi )
388 {
389  // Check grids and get order of grids
390  Index order = interp_check( x, xi, Y.ncols() );
391 
392  Index j=0;
393  const Index n=xi.nelem(), nrow=Y.nrows(), nx=x.nelem();
394  Numeric w;
395 
396  assert( nrow == Yi.nrows() );
397  assert( n == Yi.ncols() );
398 
399  for (Index i=0; i<n; i++ )
400  {
401  // Find right place:
402  while ( j<nx-2 && (Numeric)order*x[j+1]<(Numeric)order*xi[i] )
403  {
404  ++j;
405  }
406  // j should now point to the place in the old grid below the
407  // interpolation point. If the interpolation point is below the
408  // original grid, j=0. If the interpolation point is above the
409  // original grid, j=nx-2.
410 
411  assert( x[j+1]!=x[j] );
412  w = (xi[i]-x[j]) / (x[j+1]-x[j]);
413  // This expression should also be correct for points just outside
414  // the original grid. In that case w can be negative or larger
415  // than 1.
416  for( Index k=0; k<nrow; k++ )
417  {
418  Yi(k,i) = Y(k,j) + w * (Y(k,j+1)-Y(k,j));
419  }
420  }
421 }
422 
436  ConstVectorView x,
437  ConstVectorView y,
438  const Numeric xi )
439 {
440  Vector Yi(1);
441  MakeVector Xi(xi); // MakeVector is a special kind of vector that
442  // can be initialized explicitly with one or
443  // more arguments of type Numeric.
444 
445  interp_lin_vector( Yi, x, y, Xi );
446  return Yi[0];
447 }
448 
449 
450 
451 
453 // Check of function input
455 
457 //
468 void check_if_bool( const Index& x, const String& x_name )
469 {
470  if ( !(x==0 || x==1) )
471  {
472  ostringstream os;
473  os << "The boolean *" << x_name << "* must either be 0 or 1.\n"
474  << "The present value of *"<< x_name << "* is " << x << ".";
475  throw runtime_error( os.str() );
476  }
477 }
478 
479 
480 
482 //
496  const Numeric& x_low,
497  const Numeric& x_high,
498  const Numeric& x,
499  const String& x_name )
500 {
501  if ( (x<x_low) || (x>x_high) )
502  {
503  ostringstream os;
504  os << "The variable *" << x_name << "* must fulfill:\n"
505  << " " << x_low << " <= " << x_name << " <= " << x_high << "\n"
506  << "The present value of *"<< x_name << "* is " << x << ".";
507  throw runtime_error( os.str() );
508  }
509 }
510 
511 
512 
514 //
527 void check_lengths( const Vector& x1, const String& x1_name,
528  const Vector& x2, const String& x2_name )
529 {
530  if ( x1.nelem() != x2.nelem() )
531  {
532  ostringstream os;
533  os << "The vectors *" << x1_name << "* and *" << x2_name << "*\n"
534  << "must have the same lengths. \nThe lengths are: \n"
535  << x1_name << ": " << x1.nelem() << "\n"
536  << x2_name << ": " << x2.nelem();
537  throw runtime_error( os.str() );
538  }
539 }
540 
541 
542 
544 //
559 void check_length_nrow( const Vector& x, const String& x_name,
560  const Matrix& A, const String& A_name )
561 {
562  if ( x.nelem() != A.nrows() )
563  {
564  ostringstream os;
565  os << "The length of vector *" << x_name << "* must be the\n"
566  << "same as the number of rows of *" << A_name << "*.\n"
567  << "The length of *" << x_name << "* is " << x.nelem() << ".\n"
568  << "The number of rows of *" << A_name << "* is " << A.nrows()
569  << ".";
570  throw runtime_error( os.str() );
571  }
572 }
573 
574 
575 
577 //
592 void check_length_ncol( const Vector& x, const String& x_name,
593  const Matrix& A, const String& A_name )
594 {
595  if ( x.nelem() != A.ncols() )
596  {
597  ostringstream os;
598  os << "The length of vector *" << x_name << "* must be the\n"
599  << "same as the number of columns of *" << A_name << "*.\n"
600  << "The length of *" << x_name << "* is " << x.nelem() << ".\n"
601  << "The number of columns of *" << A_name << "* is " << A.ncols()
602  << ".";
603  throw runtime_error( os.str() );
604  }
605 }
606 
608 //
622 void check_ncol_nrow( const Matrix& A, const String& A_name,
623  const Matrix& B, const String& B_name )
624 {
625  if ( A.ncols() != B.nrows() )
626  {
627  ostringstream os;
628  os << "The number of columns of *" << A_name << "* must be the\n"
629  << "same as the number of rows of *" << B_name << "*."
630  << "The number of columns of *" << A_name << "* is " << A.ncols()
631  << ".\n"
632  << "The number of rows of *" << B_name << "* is " << B.nrows()
633  << ".";
634  throw runtime_error( os.str() );
635  }
636 }
interp_check
Index interp_check(ConstVectorView x, ConstVectorView xi, const Index n_y)
Local help function to check input grids.
Definition: math_funcs.cc:259
check_ncol_nrow
void check_ncol_nrow(const Matrix &A, const String &A_name, const Matrix &B, const String &B_name)
Checks that the number of columns of the first matrix is the same as the number of rows of the second...
Definition: math_funcs.cc:622
Matrix
The Matrix class.
Definition: matpackI.h:544
MatrixView
The MatrixView class.
Definition: matpackI.h:476
check_length_ncol
void check_length_ncol(const Vector &x, const String &x_name, const Matrix &A, const String &A_name)
Checkss that the length of a vector and the number of columns of a matrix match.
Definition: math_funcs.cc:592
last
Numeric last(ConstVectorView x)
Gives the last value of a vector.
Definition: math_funcs.cc:83
first
Numeric first(ConstVectorView x)
Gives the first value of a vector.
Definition: math_funcs.cc:70
check_lengths
void check_lengths(const Vector &x1, const String &x1_name, const Vector &x2, const String &x2_name)
Checks that two vectors have the same length.
Definition: math_funcs.cc:527
Vector::resize
void resize(Index n)
Resize function.
Definition: matpackI.h:1467
ConstMatrixView::nrows
Index nrows() const
Returns the number of rows.
Definition: matpackI.h:1491
array.h
This file contains the definition of Array.
nlogspace
void nlogspace(Vector &x, const Numeric start, const Numeric stop, const Index n)
Logarithmically spaced vector with specified length.
Definition: math_funcs.cc:198
Array
This can be used to make arrays out of anything.
Definition: array.h:48
check_if_bool
void check_if_bool(const Index &x, const String &x_name)
Checks if an integer is 0 or 1.
Definition: math_funcs.cc:468
ConstMatrixView::ncols
Index ncols() const
Returns the number of columns.
Definition: matpackI.h:1497
my_basic_string
The implementation for String, the ARTS string class.
Definition: mystring.h:61
Numeric
NUMERIC Numeric
The type to use for all floating point numbers.
Definition: arts.h:147
ConstVectorView::nelem
Index nelem() const
Returns the number of elements.
Definition: matpackI.h:937
VectorView
The VectorView class.
Definition: matpackI.h:281
interp_lin
Numeric interp_lin(ConstVectorView x, ConstVectorView y, const Numeric xi)
Single linear interpolation of a vector (return version).
Definition: math_funcs.cc:435
math_funcs.h
Contains declerations of basic mathematical and vector/matrix functions.
check_length_nrow
void check_length_nrow(const Vector &x, const String &x_name, const Matrix &A, const String &A_name)
Checks that the length of a vector and the number of rows of a matrix match.
Definition: math_funcs.cc:559
make_vector.h
The class MakeVector is a special kind of Vector that can be initialized explicitly from one or more ...
nlinspace
void nlinspace(Vector &x, const Numeric start, const Numeric stop, const Index n)
Linearly spaced vector with specified length.
Definition: math_funcs.cc:168
ConstMatrixView
A constant view of a Matrix.
Definition: matpackI.h:426
MakeVector
Definition: make_vector.h:42
interp_lin_vector
void interp_lin_vector(VectorView yi, ConstVectorView x, ConstVectorView y, ConstVectorView xi)
Multiple linear interpolation of a vector.
Definition: math_funcs.cc:329
Index
INDEX Index
The type to use for all integer numbers and indices.
Definition: arts.h:153
any
bool any(const ArrayOfIndex &x)
True if any element of a boolean vector, b, is not 0.
Definition: math_funcs.cc:104
interp_lin_matrix
void interp_lin_matrix(MatrixView Yi, ConstVectorView x, ConstMatrixView Y, ConstVectorView xi)
Multiple linear interpolation of matrix rows.
Definition: math_funcs.cc:383
linspace
void linspace(Vector &x, const Numeric start, const Numeric stop, const Numeric step)
Linearly spaced vector with specified spacing.
Definition: math_funcs.cc:139
Vector
The Vector class.
Definition: matpackI.h:389
ConstVectorView
A constant view of a Vector.
Definition: matpackI.h:232
Array::nelem
Index nelem() const
Number of elements.
Definition: array.h:115
check_if_in_range
void check_if_in_range(const Numeric &x_low, const Numeric &x_high, const Numeric &x, const String &x_name)
Checks if a numeric variable is inside a specified range.
Definition: math_funcs.cc:495
arts.h
The global header file for ARTS.