00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00036
00037
00038
00039
00040 #include <iostream>
00041 #include <cmath>
00042 #include <stdexcept>
00043 #include "array.h"
00044 #include "math_funcs.h"
00045 #include "logic.h"
00046 #include "mystring.h"
00047 extern const Numeric DEG2RAD;
00048 extern const Numeric PI;
00049
00050
00051
00052
00053
00054
00055
00057
00068 Numeric fac(const Index n)
00069 {
00070 Numeric sum;
00071
00072 if (n == 0) return (1.0);
00073
00074 sum = 1.0;
00075 for (Index i = 1; i <= n; i++)
00076 sum *= Numeric(i);
00077
00078 return(sum);
00079 }
00080
00081
00083
00095 Index integer_div( const Index& x, const Index& y )
00096 {
00097 assert( is_multiple( x, y ) );
00098 return x/y;
00099 }
00100
00101
00102
00104
00124 Numeric LagrangeInterpol4( ConstVectorView x,
00125 ConstVectorView y,
00126 const Numeric a)
00127 {
00128
00129 const Numeric Dlimit = 1.00000e-15;
00130
00131
00132 const Index n_x = x.nelem();
00133 const Index n_y = y.nelem();
00134 if ( (n_x != 4) || (n_y != 4) )
00135 {
00136 ostringstream os;
00137 os << "The vectors x and y must all have the same length of 4 elements!\n"
00138 << "Actual lengths:\n"
00139 << "x:" << n_x << ", " << "y:" << n_y << ".";
00140 throw runtime_error(os.str());
00141 }
00142
00143
00144 if ( (a < x[1]) || (a > x[2]) )
00145 {
00146 ostringstream os;
00147 os << "LagrangeInterpol4: the relation x[1] =< a < x[2] is not satisfied. "
00148 << "No interpolation can be calculated.\n";
00149 throw runtime_error(os.str());
00150 };
00151
00152
00153 Numeric b[4];
00154 for (Index i=0 ; i < 4 ; ++i)
00155 {
00156 b[i] = 1.000e0;
00157 for (Index k=0 ; k < 4 ; ++k)
00158 {
00159 if ( (k != i) && (fabs(x[i]-x[k]) > Dlimit) )
00160 b[i] = b[i] * ( (a-x[k]) / (x[i]-x[k]) );
00161 };
00162 };
00163
00164 Numeric ya = 0.000e0;
00165 for (Index i=0 ; i < n_x ; ++i) ya = ya + b[i]*y[i];
00166
00167 return ya;
00168 }
00169
00170
00171
00172
00174
00183 Numeric last( ConstVectorView x )
00184 {
00185 assert( x.nelem() > 0 );
00186 return x[x.nelem()-1];
00187 }
00188
00189
00190
00192
00201 Index last( const ArrayOfIndex& x )
00202 {
00203 assert( x.nelem() > 0 );
00204 return x[x.nelem()-1];
00205 }
00206
00207
00208
00210
00228 void linspace(
00229 Vector& x,
00230 const Numeric start,
00231 const Numeric stop,
00232 const Numeric step )
00233 {
00234 Index n = (Index) floor( (stop-start)/step ) + 1;
00235 if ( n<1 )
00236 n=1;
00237 x.resize(n);
00238 for ( Index i=0; i<n; i++ )
00239 x[i] = start + (double)i*step;
00240 }
00241
00242
00243
00245
00261 void nlinspace(
00262 Vector& x,
00263 const Numeric start,
00264 const Numeric stop,
00265 const Index n )
00266 {
00267 assert( 1<n );
00268 x.resize(n);
00269 Numeric step = (stop-start)/((double)n-1) ;
00270 for ( Index i=0; i<n-1; i++ )
00271 x[i] = start + (double)i*step;
00272 x[n-1] = stop;
00273 }
00274
00275
00276
00278
00294 void nlogspace(
00295 Vector& x,
00296 const Numeric start,
00297 const Numeric stop,
00298 const Index n )
00299 {
00300
00301 assert( 1<n );
00302
00303 assert( 0<start );
00304 assert( 0<stop );
00305
00306 x.resize(n);
00307 Numeric a = log(start);
00308 Numeric step = (log(stop)-a)/((double)n-1);
00309 x[0] = start;
00310 for ( Index i=1; i<n-1; i++ )
00311 x[i] = exp(a + (double)i*step);
00312 x[n-1] = stop;
00313 }
00314
00315
00317
00327 Numeric AngIntegrate_trapezoid(ConstMatrixView Integrand,
00328 ConstVectorView za_grid,
00329 ConstVectorView aa_grid)
00330 {
00331
00332 Index n = za_grid.nelem();
00333 Index m = aa_grid.nelem();
00334 Vector res1(n);
00335 assert (is_size(Integrand, n, m));
00336
00337 for (Index i = 0; i < n ; ++i)
00338 {
00339 res1[i] = 0.0;
00340
00341 for (Index j = 0; j < m - 1; ++j)
00342 {
00343 res1[i] += 0.5 * DEG2RAD * (Integrand(i, j) + Integrand(i, j + 1)) *
00344 (aa_grid[j + 1] - aa_grid[j]) * sin(za_grid[i] * DEG2RAD);
00345 }
00346 }
00347 Numeric res = 0.0;
00348 for (Index i = 0; i < n - 1; ++i)
00349 {
00350 res += 0.5 * DEG2RAD * (res1[i] + res1[i + 1]) *
00351 (za_grid[i + 1] - za_grid[i]);
00352 }
00353
00354 return res;
00355 }
00356
00357
00359
00377 Numeric AngIntegrate_trapezoid_opti(ConstMatrixView Integrand,
00378 ConstVectorView za_grid,
00379 ConstVectorView aa_grid,
00380 ConstVectorView grid_stepsize)
00381 {
00382 Numeric res = 0;
00383 if ((grid_stepsize[0] > 0) && (grid_stepsize[1] > 0))
00384 {
00385 Index n = za_grid.nelem();
00386 Index m = aa_grid.nelem();
00387 Numeric stepsize_za = grid_stepsize[0];
00388 Numeric stepsize_aa = grid_stepsize[1];
00389 Vector res1(n);
00390 assert (is_size(Integrand, n, m));
00391
00392 Numeric temp = 0.0;
00393
00394 for (Index i = 0; i < n ; ++i)
00395 {
00396 temp = Integrand(i, 0);
00397 for (Index j = 1; j < m - 1; j++)
00398 {
00399 temp += Integrand(i, j) * 2;
00400 }
00401 temp += Integrand(i, m-1);
00402 temp *= 0.5 * DEG2RAD * stepsize_aa * sin(za_grid[i] * DEG2RAD);
00403 res1[i] = temp;
00404 }
00405
00406 res = res1[0];
00407 for (Index i = 1; i < n - 1; i++)
00408 {
00409 res += res1[i] * 2;
00410 }
00411 res += res1[n-1];
00412 res *= 0.5 * DEG2RAD * stepsize_za;
00413 }
00414 else
00415 {
00416 res = AngIntegrate_trapezoid(Integrand, za_grid, aa_grid);
00417 }
00418
00419 return res;
00420 }
00421
00422
00424
00438 Numeric AngIntegrate_trapezoid(ConstVectorView Integrand,
00439 ConstVectorView za_grid)
00440 {
00441
00442 Index n = za_grid.nelem();
00443 assert (is_size(Integrand, n));
00444
00445 Numeric res = 0.0;
00446 for (Index i = 0; i < n - 1; ++i)
00447 {
00448
00449 res += PI * DEG2RAD * (Integrand[i]* sin(za_grid[i] * DEG2RAD)
00450 + Integrand[i + 1] * sin(za_grid[i + 1] * DEG2RAD))
00451 * (za_grid[i + 1] - za_grid[i]);
00452 }
00453
00454 return res;
00455 }
00456
00457
00458
00459
00461
00473 Numeric sign( const Numeric& x )
00474 {
00475 if( x < 0 )
00476 return -1.0;
00477 else if( x == 0 )
00478 return 0.0;
00479 else
00480 return 1.0;
00481 }
00482
00483
00484