00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00040 #include <iostream>
00041 #include <cmath>
00042 #include "array.h"
00043 #include "check_input.h"
00044 #include "interpolation.h"
00045 #include "logic.h"
00046
00047
00048
00049
00050
00052
00063 const Numeric sum_check_epsilon = 1e-6;
00064
00065
00067
00076 const Numeric FD_TOL = 1e-3;
00077
00078
00079
00080
00082
00091 #define LOOPIT(x) for ( const Numeric* x=&t##x.fd[1]; x>=&t##x.fd[0]; --x )
00092
00093
00094
00095
00097
00105 ostream& operator<<(ostream& os, const GridPos& gp)
00106 {
00107 os << gp.idx << " " << gp.fd[0] << " " << gp.fd[1] << "\n";
00108 return os;
00109 }
00110
00111
00113
00153 void gridpos( ArrayOfGridPos& gp,
00154 ConstVectorView old_grid,
00155 ConstVectorView new_grid,
00156 const Numeric& extpolfac )
00157 {
00158 const Index n_old = old_grid.nelem();
00159 const Index n_new = new_grid.nelem();
00160
00161
00162 assert( is_size(gp,n_new) );
00163
00164
00165 assert( 1 < n_old );
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177 bool ascending = ( old_grid[0] <= old_grid[1] );
00178
00179 if (ascending)
00180 {
00181
00182
00183
00184
00185
00186
00187
00188 assert( is_increasing(old_grid) );
00189
00190
00191 const Numeric og_min = old_grid[0] -
00192 extpolfac * ( old_grid[1] - old_grid[0] );
00193 const Numeric og_max = old_grid[n_old-1] +
00194 extpolfac * ( old_grid[n_old-1] - old_grid[n_old-2] );
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207 Numeric frac = (new_grid[0]-og_min)/(og_max-og_min);
00208
00209
00210
00211
00212
00213
00214 Index current_position = (Index) rint(frac*(Numeric)(n_old-2));
00215
00216
00217
00218
00219
00220
00221 assert( 0<= current_position );
00222 assert( current_position <= n_old-2 );
00223
00224
00225
00226 Numeric lower = old_grid[current_position];
00227 Numeric upper = old_grid[current_position+1];
00228
00229
00230 for ( Index i_new=0; i_new<n_new; ++i_new )
00231 {
00232
00233 GridPos& tgp = gp[i_new];
00234
00235 const Numeric tng = new_grid[i_new];
00236
00237
00238
00239 assert( og_min <= tng );
00240 assert( tng <= og_max );
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250 if ( tng < lower && current_position > 0 )
00251 {
00252 do
00253 {
00254 --current_position;
00255 lower = old_grid[current_position];
00256 }
00257 while ( tng < lower && current_position > 0 );
00258
00259 upper = old_grid[current_position+1];
00260
00261 tgp.idx = current_position;
00262 tgp.fd[0] = (tng-lower)/(upper-lower);
00263 tgp.fd[1] = 1.0 - tgp.fd[0];
00264 }
00265 else
00266 {
00267
00268
00269
00270 if ( tng > upper && current_position < n_old-2 )
00271 {
00272 do
00273 {
00274 ++current_position;
00275 upper = old_grid[current_position+1];
00276 }
00277 while ( tng > upper && current_position < n_old-2 );
00278
00279 lower = old_grid[current_position];
00280
00281 tgp.idx = current_position;
00282 tgp.fd[0] = (tng-lower)/(upper-lower);
00283 tgp.fd[1] = 1.0 - tgp.fd[0];
00284 }
00285 else
00286 {
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300 tgp.idx = current_position;
00301 tgp.fd[0] = (tng-lower)/(upper-lower);
00302 tgp.fd[1] = 1.0 - tgp.fd[0];
00303 }
00304 }
00305 }
00306 }
00307 else
00308 {
00309
00310
00311
00312
00313
00314
00315
00316 assert( is_decreasing(old_grid) );
00317
00318
00319
00320 const Numeric og_max = old_grid[0] -
00321 extpolfac * ( old_grid[1] - old_grid[0] );
00322 const Numeric og_min = old_grid[n_old-1] +
00323 extpolfac * ( old_grid[n_old-1] - old_grid[n_old-2] );
00324
00325
00326
00327 Numeric frac = 1 - (new_grid[0]-og_min)/(og_max-og_min);
00328
00329
00330
00331
00332
00333 Index current_position = (Index) rint(frac*(Numeric)(n_old-2));
00334
00335
00336
00337
00338
00339
00340 assert( 0<= current_position );
00341 assert( current_position <= n_old-2 );
00342
00343
00344
00345 Numeric lower = old_grid[current_position];
00346 Numeric upper = old_grid[current_position+1];
00347
00348 for ( Index i_new=0; i_new<n_new; ++i_new )
00349 {
00350 GridPos& tgp = gp[i_new];
00351 const Numeric tng = new_grid[i_new];
00352
00353
00354
00355 assert( og_min <= tng );
00356 assert( tng <= og_max );
00357
00358
00359
00360
00361
00362
00363
00364
00365 if ( tng > lower && current_position > 0 )
00366 {
00367 do
00368 {
00369 --current_position;
00370 lower = old_grid[current_position];
00371 }
00372 while ( tng > lower && current_position > 0 );
00373
00374 upper = old_grid[current_position+1];
00375
00376 tgp.idx = current_position;
00377 tgp.fd[0] = (tng-lower)/(upper-lower);
00378 tgp.fd[1] = 1.0 - tgp.fd[0];
00379 }
00380 else
00381 {
00382
00383
00384 if ( tng < upper && current_position < n_old-2 )
00385 {
00386 do
00387 {
00388 ++current_position;
00389 upper = old_grid[current_position+1];
00390 }
00391 while ( tng < upper && current_position < n_old-2 );
00392
00393 lower = old_grid[current_position];
00394
00395 tgp.idx = current_position;
00396 tgp.fd[0] = (tng-lower)/(upper-lower);
00397 tgp.fd[1] = 1.0 - tgp.fd[0];
00398 }
00399 else
00400 {
00401
00402
00403
00404
00405
00406 tgp.idx = current_position;
00407 tgp.fd[0] = (tng-lower)/(upper-lower);
00408 tgp.fd[1] = 1.0 - tgp.fd[0];
00409 }
00410 }
00411 }
00412 }
00413 }
00414
00415
00417
00438 void gridpos( GridPos& gp,
00439 ConstVectorView old_grid,
00440 const Numeric& new_grid,
00441 const Numeric& extpolfac )
00442 {
00443 ArrayOfGridPos agp(1);
00444 Vector v( 1, new_grid );
00445 gridpos( agp, old_grid, v, extpolfac );
00446 gridpos_copy( gp, agp[0] );
00447 }
00448
00449
00450
00452
00461 void gridpos_copy( GridPos& gp_new, const GridPos& gp_old )
00462 {
00463 gp_new.idx = gp_old.idx;
00464 gp_new.fd[0] = gp_old.fd[0];
00465 gp_new.fd[1] = gp_old.fd[1];
00466 }
00467
00468
00469
00471
00483 Numeric fractional_gp( const GridPos& gp )
00484 {
00485 return ( Numeric(gp.idx) + gp.fd[0] );
00486 }
00487
00488
00489
00491
00503 void gridpos_check_fd( GridPos& gp )
00504 {
00505
00506 assert( gp.fd[0] > -FD_TOL );
00507 assert( gp.fd[0] < 1.0 + FD_TOL );
00508 assert( gp.fd[1] > -FD_TOL );
00509 assert( gp.fd[1] < 1.0 + FD_TOL );
00510
00511 if( gp.fd[0] < 0 )
00512 { gp.fd[0] = 0; }
00513 else if( gp.fd[0] > 1 )
00514 { gp.fd[0] = 1; }
00515
00516 if( gp.fd[1] < 0 )
00517 { gp.fd[1] = 0; }
00518 else if( gp.fd[1] > 1 )
00519 { gp.fd[1] = 1; }
00520 }
00521
00522
00523
00525
00544 void gridpos_force_end_fd( GridPos& gp )
00545 {
00546 if( gp.fd[0] < 0.5 )
00547 {
00548
00549
00550 gp.fd[0] = 0;
00551 gp.fd[1] = 1;
00552 }
00553 else
00554 {
00555
00556
00557 gp.fd[0] = 1;
00558 gp.fd[1] = 0;
00559 }
00560 }
00561
00562
00563
00565
00577 bool is_gridpos_at_index_i(
00578 const GridPos& gp,
00579 const Index& i )
00580 {
00581 if( ( gp.fd[0] == 0 || gp.fd[0] == 1 ) &&
00582 ( gp.idx + Index(gp.fd[0]) ) == i )
00583 { return true; }
00584 else
00585 { return false; }
00586
00587
00588
00589
00590
00591
00592 }
00593
00594
00595
00597
00615 Index gridpos2gridrange(
00616 const GridPos& gp,
00617 const bool& upwards )
00618 {
00619 assert( gp.fd[0] >= 0 );
00620 assert( gp.fd[0] <= 1 );
00621 assert( is_bool( upwards ) );
00622
00623
00624 if( gp.fd[0] > 0 && gp.fd[0] < 1 )
00625 {
00626 return gp.idx;
00627 }
00628
00629
00630 else if( gp.fd[0] == 0 )
00631 {
00632 if( upwards )
00633 return gp.idx;
00634 else
00635 return gp.idx - 1;
00636 }
00637
00638
00639 else
00640 {
00641 if( upwards )
00642 return gp.idx + 1;
00643 else
00644 return gp.idx;
00645 }
00646 }
00647
00648
00649
00650
00651
00652
00654
00656
00658
00671 void interpweights( VectorView itw,
00672 const GridPos& tc )
00673 {
00674 assert(is_size(itw,2));
00675
00676
00677
00678
00679
00680
00681
00682 Index iti = 0;
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707 LOOPIT(c)
00708 {
00709 itw[iti] = *c;
00710 ++iti;
00711 }
00712 }
00713
00715
00729 void interpweights( VectorView itw,
00730 const GridPos& tr,
00731 const GridPos& tc )
00732 {
00733 assert(is_size(itw,4));
00734
00735 Index iti = 0;
00736
00737 LOOPIT(r)
00738 LOOPIT(c)
00739 {
00740 itw[iti] = (*r) * (*c);
00741 ++iti;
00742 }
00743 }
00744
00746
00761 void interpweights( VectorView itw,
00762 const GridPos& tp,
00763 const GridPos& tr,
00764 const GridPos& tc )
00765 {
00766 assert(is_size(itw,8));
00767
00768 Index iti = 0;
00769
00770 LOOPIT(p)
00771 LOOPIT(r)
00772 LOOPIT(c)
00773 {
00774 itw[iti] = (*p) * (*r) * (*c);
00775 ++iti;
00776 }
00777 }
00778
00780
00796 void interpweights( VectorView itw,
00797 const GridPos& tb,
00798 const GridPos& tp,
00799 const GridPos& tr,
00800 const GridPos& tc )
00801 {
00802 assert(is_size(itw,16));
00803
00804 Index iti = 0;
00805
00806 LOOPIT(b)
00807 LOOPIT(p)
00808 LOOPIT(r)
00809 LOOPIT(c)
00810 {
00811 itw[iti] = (*b) * (*p) * (*r) * (*c);
00812 ++iti;
00813 }
00814 }
00815
00817
00834 void interpweights( VectorView itw,
00835 const GridPos& ts,
00836 const GridPos& tb,
00837 const GridPos& tp,
00838 const GridPos& tr,
00839 const GridPos& tc )
00840 {
00841 assert(is_size(itw,32));
00842
00843 Index iti = 0;
00844
00845 LOOPIT(s)
00846 LOOPIT(b)
00847 LOOPIT(p)
00848 LOOPIT(r)
00849 LOOPIT(c)
00850 {
00851 itw[iti] = (*s) * (*b) * (*p) * (*r) * (*c);
00852 ++iti;
00853 }
00854 }
00855
00857
00875 void interpweights( VectorView itw,
00876 const GridPos& tv,
00877 const GridPos& ts,
00878 const GridPos& tb,
00879 const GridPos& tp,
00880 const GridPos& tr,
00881 const GridPos& tc )
00882 {
00883 assert(is_size(itw,64));
00884
00885 Index iti = 0;
00886
00887 LOOPIT(v)
00888 LOOPIT(s)
00889 LOOPIT(b)
00890 LOOPIT(p)
00891 LOOPIT(r)
00892 LOOPIT(c)
00893 {
00894 itw[iti] = (*v) * (*s) * (*b) * (*p) * (*r) * (*c);
00895 ++iti;
00896 }
00897 }
00898
00900
00915 Numeric interp( ConstVectorView itw,
00916 ConstVectorView a,
00917 const GridPos& tc )
00918 {
00919 assert(is_size(itw,2));
00920
00921
00922
00923
00924 assert( is_same_within_epsilon( itw.sum(),
00925 1,
00926 sum_check_epsilon ) );
00927
00928
00929 Numeric tia = 0;
00930
00931 Index iti = 0;
00932 for ( Index c=0; c<2; ++c )
00933 {
00934 tia += a[tc.idx+c] * itw[iti];
00935 ++iti;
00936 }
00937
00938 return tia;
00939 }
00940
00942
00958 Numeric interp( ConstVectorView itw,
00959 ConstMatrixView a,
00960 const GridPos& tr,
00961 const GridPos& tc )
00962 {
00963 assert(is_size(itw,4));
00964
00965
00966
00967
00968 assert( is_same_within_epsilon( itw.sum(),
00969 1,
00970 sum_check_epsilon ) );
00971
00972
00973 Numeric tia = 0;
00974
00975 Index iti = 0;
00976 for ( Index r=0; r<2; ++r )
00977 for ( Index c=0; c<2; ++c )
00978 {
00979 tia += a(tr.idx+r,
00980 tc.idx+c) * itw[iti];
00981 ++iti;
00982 }
00983
00984 return tia;
00985 }
00986
00988
01005 Numeric interp( ConstVectorView itw,
01006 ConstTensor3View a,
01007 const GridPos& tp,
01008 const GridPos& tr,
01009 const GridPos& tc )
01010 {
01011 assert(is_size(itw,8));
01012
01013
01014
01015
01016 assert( is_same_within_epsilon( itw.sum(),
01017 1,
01018 sum_check_epsilon ) );
01019
01020
01021 Numeric tia = 0;
01022
01023 Index iti = 0;
01024 for ( Index p=0; p<2; ++p )
01025 for ( Index r=0; r<2; ++r )
01026 for ( Index c=0; c<2; ++c )
01027 {
01028 tia += a(tp.idx+p,
01029 tr.idx+r,
01030 tc.idx+c) * itw[iti];
01031 ++iti;
01032 }
01033
01034 return tia;
01035 }
01036
01038
01056 Numeric interp( ConstVectorView itw,
01057 ConstTensor4View a,
01058 const GridPos& tb,
01059 const GridPos& tp,
01060 const GridPos& tr,
01061 const GridPos& tc )
01062 {
01063 assert(is_size(itw,16));
01064
01065
01066
01067
01068 assert( is_same_within_epsilon( itw.sum(),
01069 1,
01070 sum_check_epsilon ) );
01071
01072
01073 Numeric tia = 0;
01074
01075 Index iti = 0;
01076 for ( Index b=0; b<2; ++b )
01077 for ( Index p=0; p<2; ++p )
01078 for ( Index r=0; r<2; ++r )
01079 for ( Index c=0; c<2; ++c )
01080 {
01081 tia += a(tb.idx+b,
01082 tp.idx+p,
01083 tr.idx+r,
01084 tc.idx+c) * itw[iti];
01085 ++iti;
01086 }
01087
01088 return tia;
01089 }
01090
01092
01111 Numeric interp( ConstVectorView itw,
01112 ConstTensor5View a,
01113 const GridPos& ts,
01114 const GridPos& tb,
01115 const GridPos& tp,
01116 const GridPos& tr,
01117 const GridPos& tc )
01118 {
01119 assert(is_size(itw,32));
01120
01121
01122
01123
01124 assert( is_same_within_epsilon( itw.sum(),
01125 1,
01126 sum_check_epsilon ) );
01127
01128
01129 Numeric tia = 0;
01130
01131 Index iti = 0;
01132 for ( Index s=0; s<2; ++s )
01133 for ( Index b=0; b<2; ++b )
01134 for ( Index p=0; p<2; ++p )
01135 for ( Index r=0; r<2; ++r )
01136 for ( Index c=0; c<2; ++c )
01137 {
01138 tia += a(ts.idx+s,
01139 tb.idx+b,
01140 tp.idx+p,
01141 tr.idx+r,
01142 tc.idx+c) * itw[iti];
01143 ++iti;
01144 }
01145
01146 return tia;
01147 }
01148
01150
01170 Numeric interp( ConstVectorView itw,
01171 ConstTensor6View a,
01172 const GridPos& tv,
01173 const GridPos& ts,
01174 const GridPos& tb,
01175 const GridPos& tp,
01176 const GridPos& tr,
01177 const GridPos& tc )
01178 {
01179 assert(is_size(itw,64));
01180
01181
01182
01183
01184 assert( is_same_within_epsilon( itw.sum(),
01185 1,
01186 sum_check_epsilon ) );
01187
01188
01189 Numeric tia = 0;
01190
01191 Index iti = 0;
01192 for ( Index v=0; v<2; ++v )
01193 for ( Index s=0; s<2; ++s )
01194 for ( Index b=0; b<2; ++b )
01195 for ( Index p=0; p<2; ++p )
01196 for ( Index r=0; r<2; ++r )
01197 for ( Index c=0; c<2; ++c )
01198 {
01199 tia += a(tv.idx+v,
01200 ts.idx+s,
01201 tb.idx+b,
01202 tp.idx+p,
01203 tr.idx+r,
01204 tc.idx+c) * itw[iti];
01205 ++iti;
01206 }
01207
01208 return tia;
01209 }
01210
01211
01213
01215
01217
01232 void interpweights( MatrixView itw,
01233 const ArrayOfGridPos& cgp )
01234 {
01235 Index n = cgp.nelem();
01236 assert(is_size(itw,n,2));
01237
01238
01239
01240 for ( Index i=0; i<n; ++i )
01241 {
01242
01243 const GridPos& tc = cgp[i];
01244
01245
01246
01247
01248
01249
01250 Index iti = 0;
01251
01252
01253
01254
01255
01256
01257
01258
01259
01260
01261
01262
01263
01264
01265
01266
01267
01268
01269
01270
01271
01272
01273
01274
01275 LOOPIT(c)
01276 {
01277 itw(i,iti) = *c;
01278 ++iti;
01279 }
01280 }
01281 }
01282
01284
01305 void interpweights( MatrixView itw,
01306 const ArrayOfGridPos& rgp,
01307 const ArrayOfGridPos& cgp )
01308 {
01309 Index n = cgp.nelem();
01310 assert(is_size(rgp,n));
01311 assert(is_size(itw,n,4));
01312
01313
01314
01315 for ( Index i=0; i<n; ++i )
01316 {
01317
01318 const GridPos& tr = rgp[i];
01319 const GridPos& tc = cgp[i];
01320
01321
01322
01323
01324
01325
01326
01327
01328 Index iti = 0;
01329
01330 LOOPIT(r)
01331 LOOPIT(c)
01332 {
01333 itw(i,iti) = (*r) * (*c);
01334 ++iti;
01335 }
01336 }
01337 }
01338
01340
01362 void interpweights( MatrixView itw,
01363 const ArrayOfGridPos& pgp,
01364 const ArrayOfGridPos& rgp,
01365 const ArrayOfGridPos& cgp )
01366 {
01367 Index n = cgp.nelem();
01368 assert(is_size(pgp,n));
01369 assert(is_size(rgp,n));
01370 assert(is_size(itw,n,8));
01371
01372
01373
01374 for ( Index i=0; i<n; ++i )
01375 {
01376
01377 const GridPos& tp = pgp[i];
01378 const GridPos& tr = rgp[i];
01379 const GridPos& tc = cgp[i];
01380
01381 Index iti = 0;
01382 LOOPIT(p)
01383 LOOPIT(r)
01384 LOOPIT(c)
01385 {
01386 itw(i,iti) = (*p) * (*r) * (*c);
01387 ++iti;
01388 }
01389 }
01390 }
01391
01393
01416 void interpweights( MatrixView itw,
01417 const ArrayOfGridPos& bgp,
01418 const ArrayOfGridPos& pgp,
01419 const ArrayOfGridPos& rgp,
01420 const ArrayOfGridPos& cgp )
01421 {
01422 Index n = cgp.nelem();
01423 assert(is_size(bgp,n));
01424 assert(is_size(pgp,n));
01425 assert(is_size(rgp,n));
01426 assert(is_size(itw,n,16));
01427
01428
01429
01430 for ( Index i=0; i<n; ++i )
01431 {
01432
01433 const GridPos& tb = bgp[i];
01434 const GridPos& tp = pgp[i];
01435 const GridPos& tr = rgp[i];
01436 const GridPos& tc = cgp[i];
01437
01438 Index iti = 0;
01439 LOOPIT(b)
01440 LOOPIT(p)
01441 LOOPIT(r)
01442 LOOPIT(c)
01443 {
01444 itw(i,iti) = (*b) * (*p) * (*r) * (*c);
01445 ++iti;
01446 }
01447 }
01448 }
01449
01451
01475 void interpweights( MatrixView itw,
01476 const ArrayOfGridPos& sgp,
01477 const ArrayOfGridPos& bgp,
01478 const ArrayOfGridPos& pgp,
01479 const ArrayOfGridPos& rgp,
01480 const ArrayOfGridPos& cgp )
01481 {
01482 Index n = cgp.nelem();
01483 assert(is_size(sgp,n));
01484 assert(is_size(bgp,n));
01485 assert(is_size(pgp,n));
01486 assert(is_size(rgp,n));
01487 assert(is_size(itw,n,32));
01488
01489
01490
01491 for ( Index i=0; i<n; ++i )
01492 {
01493
01494 const GridPos& ts = sgp[i];
01495 const GridPos& tb = bgp[i];
01496 const GridPos& tp = pgp[i];
01497 const GridPos& tr = rgp[i];
01498 const GridPos& tc = cgp[i];
01499
01500 Index iti = 0;
01501 LOOPIT(s)
01502 LOOPIT(b)
01503 LOOPIT(p)
01504 LOOPIT(r)
01505 LOOPIT(c)
01506 {
01507 itw(i,iti) = (*s) * (*b) * (*p) * (*r) * (*c);
01508 ++iti;
01509 }
01510 }
01511 }
01512
01514
01539 void interpweights( MatrixView itw,
01540 const ArrayOfGridPos& vgp,
01541 const ArrayOfGridPos& sgp,
01542 const ArrayOfGridPos& bgp,
01543 const ArrayOfGridPos& pgp,
01544 const ArrayOfGridPos& rgp,
01545 const ArrayOfGridPos& cgp )
01546 {
01547 Index n = cgp.nelem();
01548 assert(is_size(vgp,n));
01549 assert(is_size(sgp,n));
01550 assert(is_size(bgp,n));
01551 assert(is_size(pgp,n));
01552 assert(is_size(rgp,n));
01553 assert(is_size(itw,n,64));
01554
01555
01556
01557 for ( Index i=0; i<n; ++i )
01558 {
01559
01560 const GridPos& tv = vgp[i];
01561 const GridPos& ts = sgp[i];
01562 const GridPos& tb = bgp[i];
01563 const GridPos& tp = pgp[i];
01564 const GridPos& tr = rgp[i];
01565 const GridPos& tc = cgp[i];
01566
01567 Index iti = 0;
01568 LOOPIT(v)
01569 LOOPIT(s)
01570 LOOPIT(b)
01571 LOOPIT(p)
01572 LOOPIT(r)
01573 LOOPIT(c)
01574 {
01575 itw(i,iti) = (*v) * (*s) * (*b) * (*p) * (*r) * (*c);
01576 ++iti;
01577 }
01578 }
01579 }
01580
01582
01598 void interp( VectorView ia,
01599 ConstMatrixView itw,
01600 ConstVectorView a,
01601 const ArrayOfGridPos& cgp)
01602 {
01603 Index n = cgp.nelem();
01604 assert(is_size(ia,n));
01605 assert(is_size(itw,n,2));
01606
01607
01608
01609
01610
01611 assert( is_same_within_epsilon( itw(0,Range(joker)).sum(),
01612 1,
01613 sum_check_epsilon ) );
01614
01615
01616 for ( Index i=0; i<n; ++i )
01617 {
01618
01619 const GridPos& tc = cgp[i];
01620
01621
01622
01623 Numeric& tia = ia[i];
01624 tia = 0;
01625
01626 Index iti = 0;
01627 for ( Index c=0; c<2; ++c )
01628 {
01629 tia += a[tc.idx+c] * itw(i,iti);
01630 ++iti;
01631 }
01632 }
01633 }
01634
01636
01657 void interp( VectorView ia,
01658 ConstMatrixView itw,
01659 ConstMatrixView a,
01660 const ArrayOfGridPos& rgp,
01661 const ArrayOfGridPos& cgp)
01662 {
01663 Index n = cgp.nelem();
01664 assert(is_size(ia,n));
01665 assert(is_size(rgp,n));
01666 assert(is_size(itw,n,4));
01667
01668
01669
01670
01671
01672 assert( is_same_within_epsilon( itw(0,Range(joker)).sum(),
01673 1,
01674 sum_check_epsilon ) );
01675
01676
01677 for ( Index i=0; i<n; ++i )
01678 {
01679
01680 const GridPos& tr = rgp[i];
01681 const GridPos& tc = cgp[i];
01682
01683
01684
01685 Numeric& tia = ia[i];
01686 tia = 0;
01687
01688 Index iti = 0;
01689 for ( Index r=0; r<2; ++r )
01690 for ( Index c=0; c<2; ++c )
01691 {
01692 tia += a(tr.idx+r,
01693 tc.idx+c) * itw(i,iti);
01694 ++iti;
01695 }
01696 }
01697 }
01698
01700
01722 void interp( VectorView ia,
01723 ConstMatrixView itw,
01724 ConstTensor3View a,
01725 const ArrayOfGridPos& pgp,
01726 const ArrayOfGridPos& rgp,
01727 const ArrayOfGridPos& cgp)
01728 {
01729 Index n = cgp.nelem();
01730 assert(is_size(ia,n));
01731 assert(is_size(pgp,n));
01732 assert(is_size(rgp,n));
01733 assert(is_size(itw,n,8));
01734
01735
01736
01737
01738
01739 assert( is_same_within_epsilon( itw(0,Range(joker)).sum(),
01740 1,
01741 sum_check_epsilon ) );
01742
01743
01744 for ( Index i=0; i<n; ++i )
01745 {
01746
01747 const GridPos& tp = pgp[i];
01748 const GridPos& tr = rgp[i];
01749 const GridPos& tc = cgp[i];
01750
01751
01752
01753 Numeric& tia = ia[i];
01754 tia = 0;
01755
01756 Index iti = 0;
01757 for ( Index p=0; p<2; ++p )
01758 for ( Index r=0; r<2; ++r )
01759 for ( Index c=0; c<2; ++c )
01760 {
01761 tia += a(tp.idx+p,
01762 tr.idx+r,
01763 tc.idx+c) * itw(i,iti);
01764 ++iti;
01765 }
01766 }
01767 }
01768
01770
01793 void interp( VectorView ia,
01794 ConstMatrixView itw,
01795 ConstTensor4View a,
01796 const ArrayOfGridPos& bgp,
01797 const ArrayOfGridPos& pgp,
01798 const ArrayOfGridPos& rgp,
01799 const ArrayOfGridPos& cgp)
01800 {
01801 Index n = cgp.nelem();
01802 assert(is_size(ia,n));
01803 assert(is_size(bgp,n));
01804 assert(is_size(pgp,n));
01805 assert(is_size(rgp,n));
01806 assert(is_size(itw,n,16));
01807
01808
01809
01810
01811
01812 assert( is_same_within_epsilon( itw(0,Range(joker)).sum(),
01813 1,
01814 sum_check_epsilon ) );
01815
01816
01817 for ( Index i=0; i<n; ++i )
01818 {
01819
01820 const GridPos& tb = bgp[i];
01821 const GridPos& tp = pgp[i];
01822 const GridPos& tr = rgp[i];
01823 const GridPos& tc = cgp[i];
01824
01825
01826
01827 Numeric& tia = ia[i];
01828 tia = 0;
01829
01830 Index iti = 0;
01831 for ( Index b=0; b<2; ++b )
01832 for ( Index p=0; p<2; ++p )
01833 for ( Index r=0; r<2; ++r )
01834 for ( Index c=0; c<2; ++c )
01835 {
01836 tia += a(tb.idx+b,
01837 tp.idx+p,
01838 tr.idx+r,
01839 tc.idx+c) * itw(i,iti);
01840 ++iti;
01841 }
01842 }
01843 }
01844
01846
01870 void interp( VectorView ia,
01871 ConstMatrixView itw,
01872 ConstTensor5View a,
01873 const ArrayOfGridPos& sgp,
01874 const ArrayOfGridPos& bgp,
01875 const ArrayOfGridPos& pgp,
01876 const ArrayOfGridPos& rgp,
01877 const ArrayOfGridPos& cgp)
01878 {
01879 Index n = cgp.nelem();
01880 assert(is_size(ia,n));
01881 assert(is_size(sgp,n));
01882 assert(is_size(bgp,n));
01883 assert(is_size(pgp,n));
01884 assert(is_size(rgp,n));
01885 assert(is_size(itw,n,32));
01886
01887
01888
01889
01890
01891 assert( is_same_within_epsilon( itw(0,Range(joker)).sum(),
01892 1,
01893 sum_check_epsilon ) );
01894
01895
01896 for ( Index i=0; i<n; ++i )
01897 {
01898
01899 const GridPos& ts = sgp[i];
01900 const GridPos& tb = bgp[i];
01901 const GridPos& tp = pgp[i];
01902 const GridPos& tr = rgp[i];
01903 const GridPos& tc = cgp[i];
01904
01905
01906
01907 Numeric& tia = ia[i];
01908 tia = 0;
01909
01910 Index iti = 0;
01911 for ( Index s=0; s<2; ++s )
01912 for ( Index b=0; b<2; ++b )
01913 for ( Index p=0; p<2; ++p )
01914 for ( Index r=0; r<2; ++r )
01915 for ( Index c=0; c<2; ++c )
01916 {
01917 tia += a(ts.idx+s,
01918 tb.idx+b,
01919 tp.idx+p,
01920 tr.idx+r,
01921 tc.idx+c) * itw(i,iti);
01922 ++iti;
01923 }
01924 }
01925 }
01926
01928
01953 void interp( VectorView ia,
01954 ConstMatrixView itw,
01955 ConstTensor6View a,
01956 const ArrayOfGridPos& vgp,
01957 const ArrayOfGridPos& sgp,
01958 const ArrayOfGridPos& bgp,
01959 const ArrayOfGridPos& pgp,
01960 const ArrayOfGridPos& rgp,
01961 const ArrayOfGridPos& cgp)
01962 {
01963 Index n = cgp.nelem();
01964 assert(is_size(ia,n));
01965 assert(is_size(vgp,n));
01966 assert(is_size(sgp,n));
01967 assert(is_size(bgp,n));
01968 assert(is_size(pgp,n));
01969 assert(is_size(rgp,n));
01970 assert(is_size(itw,n,64));
01971
01972
01973
01974
01975
01976 assert( is_same_within_epsilon( itw(0,Range(joker)).sum(),
01977 1,
01978 sum_check_epsilon ) );
01979
01980
01981 for ( Index i=0; i<n; ++i )
01982 {
01983
01984 const GridPos& tv = vgp[i];
01985 const GridPos& ts = sgp[i];
01986 const GridPos& tb = bgp[i];
01987 const GridPos& tp = pgp[i];
01988 const GridPos& tr = rgp[i];
01989 const GridPos& tc = cgp[i];
01990
01991
01992
01993 Numeric& tia = ia[i];
01994 tia = 0;
01995
01996 Index iti = 0;
01997 for ( Index v=0; v<2; ++v )
01998 for ( Index s=0; s<2; ++s )
01999 for ( Index b=0; b<2; ++b )
02000 for ( Index p=0; p<2; ++p )
02001 for ( Index r=0; r<2; ++r )
02002 for ( Index c=0; c<2; ++c )
02003 {
02004 tia += a(tv.idx+v,
02005 ts.idx+s,
02006 tb.idx+b,
02007 tp.idx+p,
02008 tr.idx+r,
02009 tc.idx+c) * itw(i,iti);
02010 ++iti;
02011 }
02012 }
02013 }
02014
02016
02018
02020
02041 void interpweights( Tensor3View itw,
02042 const ArrayOfGridPos& rgp,
02043 const ArrayOfGridPos& cgp )
02044 {
02045 Index nr = rgp.nelem();
02046 Index nc = cgp.nelem();
02047 assert(is_size(itw,nr,nc,4));
02048
02049
02050
02051 for ( Index ir=0; ir<nr; ++ir )
02052 {
02053
02054 const GridPos& tr = rgp[ir];
02055
02056 for ( Index ic=0; ic<nc; ++ic )
02057 {
02058
02059 const GridPos& tc = cgp[ic];
02060
02061
02062
02063
02064
02065
02066
02067
02068 Index iti = 0;
02069
02070 LOOPIT(r)
02071 LOOPIT(c)
02072 {
02073 itw(ir,ic,iti) = (*r) * (*c);
02074 ++iti;
02075 }
02076 }
02077 }
02078 }
02079
02081
02103 void interpweights( Tensor4View itw,
02104 const ArrayOfGridPos& pgp,
02105 const ArrayOfGridPos& rgp,
02106 const ArrayOfGridPos& cgp )
02107 {
02108 Index np = pgp.nelem();
02109 Index nr = rgp.nelem();
02110 Index nc = cgp.nelem();
02111
02112 assert(is_size(itw,np,nr,nc,8));
02113
02114
02115 for ( Index ip=0; ip<np; ++ip )
02116 {
02117 const GridPos& tp = pgp[ip];
02118 for ( Index ir=0; ir<nr; ++ir )
02119 {
02120 const GridPos& tr = rgp[ir];
02121 for ( Index ic=0; ic<nc; ++ic )
02122 {
02123 const GridPos& tc = cgp[ic];
02124
02125 Index iti = 0;
02126
02127 LOOPIT(p)
02128 LOOPIT(r)
02129 LOOPIT(c)
02130 {
02131 itw(ip,ir,ic,iti) =
02132 (*p) * (*r) * (*c);
02133 ++iti;
02134 }
02135 }
02136 }
02137 }
02138 }
02139
02141
02164 void interpweights( Tensor5View itw,
02165 const ArrayOfGridPos& bgp,
02166 const ArrayOfGridPos& pgp,
02167 const ArrayOfGridPos& rgp,
02168 const ArrayOfGridPos& cgp )
02169 {
02170 Index nb = bgp.nelem();
02171 Index np = pgp.nelem();
02172 Index nr = rgp.nelem();
02173 Index nc = cgp.nelem();
02174
02175 assert(is_size(itw,nb,np,nr,nc,16));
02176
02177
02178 for ( Index ib=0; ib<nb; ++ib )
02179 {
02180 const GridPos& tb = bgp[ib];
02181 for ( Index ip=0; ip<np; ++ip )
02182 {
02183 const GridPos& tp = pgp[ip];
02184 for ( Index ir=0; ir<nr; ++ir )
02185 {
02186 const GridPos& tr = rgp[ir];
02187 for ( Index ic=0; ic<nc; ++ic )
02188 {
02189 const GridPos& tc = cgp[ic];
02190
02191 Index iti = 0;
02192
02193 LOOPIT(b)
02194 LOOPIT(p)
02195 LOOPIT(r)
02196 LOOPIT(c)
02197 {
02198 itw(ib,ip,ir,ic,iti) =
02199 (*b) * (*p) * (*r) * (*c);
02200 ++iti;
02201 }
02202 }
02203 }
02204 }
02205 }
02206 }
02207
02209
02233 void interpweights( Tensor6View itw,
02234 const ArrayOfGridPos& sgp,
02235 const ArrayOfGridPos& bgp,
02236 const ArrayOfGridPos& pgp,
02237 const ArrayOfGridPos& rgp,
02238 const ArrayOfGridPos& cgp )
02239 {
02240 Index ns = sgp.nelem();
02241 Index nb = bgp.nelem();
02242 Index np = pgp.nelem();
02243 Index nr = rgp.nelem();
02244 Index nc = cgp.nelem();
02245
02246 assert(is_size(itw,ns,nb,np,nr,nc,32));
02247
02248
02249 for ( Index is=0; is<ns; ++is )
02250 {
02251 const GridPos& ts = sgp[is];
02252 for ( Index ib=0; ib<nb; ++ib )
02253 {
02254 const GridPos& tb = bgp[ib];
02255 for ( Index ip=0; ip<np; ++ip )
02256 {
02257 const GridPos& tp = pgp[ip];
02258 for ( Index ir=0; ir<nr; ++ir )
02259 {
02260 const GridPos& tr = rgp[ir];
02261 for ( Index ic=0; ic<nc; ++ic )
02262 {
02263 const GridPos& tc = cgp[ic];
02264
02265 Index iti = 0;
02266
02267 LOOPIT(s)
02268 LOOPIT(b)
02269 LOOPIT(p)
02270 LOOPIT(r)
02271 LOOPIT(c)
02272 {
02273 itw(is,ib,ip,ir,ic,iti) =
02274 (*s) * (*b) * (*p) * (*r) * (*c);
02275 ++iti;
02276 }
02277 }
02278 }
02279 }
02280 }
02281 }
02282 }
02283
02285
02310 void interpweights( Tensor7View itw,
02311 const ArrayOfGridPos& vgp,
02312 const ArrayOfGridPos& sgp,
02313 const ArrayOfGridPos& bgp,
02314 const ArrayOfGridPos& pgp,
02315 const ArrayOfGridPos& rgp,
02316 const ArrayOfGridPos& cgp )
02317 {
02318 Index nv = vgp.nelem();
02319 Index ns = sgp.nelem();
02320 Index nb = bgp.nelem();
02321 Index np = pgp.nelem();
02322 Index nr = rgp.nelem();
02323 Index nc = cgp.nelem();
02324
02325 assert(is_size(itw,nv,ns,nb,np,nr,nc,64));
02326
02327
02328 for ( Index iv=0; iv<nv; ++iv )
02329 {
02330 const GridPos& tv = vgp[iv];
02331 for ( Index is=0; is<ns; ++is )
02332 {
02333 const GridPos& ts = sgp[is];
02334 for ( Index ib=0; ib<nb; ++ib )
02335 {
02336 const GridPos& tb = bgp[ib];
02337 for ( Index ip=0; ip<np; ++ip )
02338 {
02339 const GridPos& tp = pgp[ip];
02340 for ( Index ir=0; ir<nr; ++ir )
02341 {
02342 const GridPos& tr = rgp[ir];
02343 for ( Index ic=0; ic<nc; ++ic )
02344 {
02345 const GridPos& tc = cgp[ic];
02346
02347 Index iti = 0;
02348
02349 LOOPIT(v)
02350 LOOPIT(s)
02351 LOOPIT(b)
02352 LOOPIT(p)
02353 LOOPIT(r)
02354 LOOPIT(c)
02355 {
02356 itw(iv,is,ib,ip,ir,ic,iti) =
02357 (*v) * (*s) * (*b) * (*p) * (*r) * (*c);
02358 ++iti;
02359 }
02360 }
02361 }
02362 }
02363 }
02364 }
02365 }
02366 }
02367
02369
02390 void interp( MatrixView ia,
02391 ConstTensor3View itw,
02392 ConstMatrixView a,
02393 const ArrayOfGridPos& rgp,
02394 const ArrayOfGridPos& cgp)
02395 {
02396 Index nr = rgp.nelem();
02397 Index nc = cgp.nelem();
02398 assert(is_size(ia,nr,nc));
02399 assert(is_size(itw,nr,nc,4));
02400
02401
02402
02403
02404
02405 assert( is_same_within_epsilon( itw(0,0,Range(joker)).sum(),
02406 1,
02407 sum_check_epsilon ) );
02408
02409
02410 for ( Index ir=0; ir<nr; ++ir )
02411 {
02412
02413 const GridPos& tr = rgp[ir];
02414
02415 for ( Index ic=0; ic<nc; ++ic )
02416 {
02417
02418 const GridPos& tc = cgp[ic];
02419
02420
02421
02422 Numeric& tia = ia(ir,ic);
02423 tia = 0;
02424
02425 Index iti = 0;
02426 for ( Index r=0; r<2; ++r )
02427 for ( Index c=0; c<2; ++c )
02428 {
02429 tia += a(tr.idx+r,
02430 tc.idx+c) * itw(ir,ic,iti);
02431 ++iti;
02432 }
02433 }
02434 }
02435 }
02436
02438
02460 void interp( Tensor3View ia,
02461 ConstTensor4View itw,
02462 ConstTensor3View a,
02463 const ArrayOfGridPos& pgp,
02464 const ArrayOfGridPos& rgp,
02465 const ArrayOfGridPos& cgp)
02466 {
02467 Index np = pgp.nelem();
02468 Index nr = rgp.nelem();
02469 Index nc = cgp.nelem();
02470 assert(is_size(ia,
02471 np,nr,nc));
02472 assert(is_size(itw,
02473 np,nr,nc,
02474 8));
02475
02476
02477
02478
02479 assert( is_same_within_epsilon( itw(0,0,0,Range(joker)).sum(),
02480 1,
02481 sum_check_epsilon ) );
02482
02483
02484 for ( Index ip=0; ip<np; ++ip )
02485 {
02486 const GridPos& tp = pgp[ip];
02487 for ( Index ir=0; ir<nr; ++ir )
02488 {
02489 const GridPos& tr = rgp[ir];
02490 for ( Index ic=0; ic<nc; ++ic )
02491 {
02492
02493 const GridPos& tc = cgp[ic];
02494
02495
02496
02497 Numeric& tia = ia(ip,ir,ic);
02498 tia = 0;
02499
02500 Index iti = 0;
02501 for ( Index p=0; p<2; ++p )
02502 for ( Index r=0; r<2; ++r )
02503 for ( Index c=0; c<2; ++c )
02504 {
02505 tia += a(tp.idx+p,
02506 tr.idx+r,
02507 tc.idx+c) * itw(ip,ir,ic,
02508 iti);
02509 ++iti;
02510 }
02511 }
02512 }
02513 }
02514 }
02515
02517
02540 void interp( Tensor4View ia,
02541 ConstTensor5View itw,
02542 ConstTensor4View a,
02543 const ArrayOfGridPos& bgp,
02544 const ArrayOfGridPos& pgp,
02545 const ArrayOfGridPos& rgp,
02546 const ArrayOfGridPos& cgp)
02547 {
02548 Index nb = bgp.nelem();
02549 Index np = pgp.nelem();
02550 Index nr = rgp.nelem();
02551 Index nc = cgp.nelem();
02552 assert(is_size(ia,
02553 nb,np,nr,nc));
02554 assert(is_size(itw,
02555 nb,np,nr,nc,
02556 16));
02557
02558
02559
02560
02561 assert( is_same_within_epsilon( itw(0,0,0,0,Range(joker)).sum(),
02562 1,
02563 sum_check_epsilon ) );
02564
02565
02566 for ( Index ib=0; ib<nb; ++ib )
02567 {
02568 const GridPos& tb = bgp[ib];
02569 for ( Index ip=0; ip<np; ++ip )
02570 {
02571 const GridPos& tp = pgp[ip];
02572 for ( Index ir=0; ir<nr; ++ir )
02573 {
02574 const GridPos& tr = rgp[ir];
02575 for ( Index ic=0; ic<nc; ++ic )
02576 {
02577
02578 const GridPos& tc = cgp[ic];
02579
02580
02581
02582 Numeric& tia = ia(ib,ip,ir,ic);
02583 tia = 0;
02584
02585 Index iti = 0;
02586 for ( Index b=0; b<2; ++b )
02587 for ( Index p=0; p<2; ++p )
02588 for ( Index r=0; r<2; ++r )
02589 for ( Index c=0; c<2; ++c )
02590 {
02591 tia += a(tb.idx+b,
02592 tp.idx+p,
02593 tr.idx+r,
02594 tc.idx+c) * itw(ib,ip,ir,ic,
02595 iti);
02596 ++iti;
02597 }
02598 }
02599 }
02600 }
02601 }
02602 }
02603
02605
02629 void interp( Tensor5View ia,
02630 ConstTensor6View itw,
02631 ConstTensor5View a,
02632 const ArrayOfGridPos& sgp,
02633 const ArrayOfGridPos& bgp,
02634 const ArrayOfGridPos& pgp,
02635 const ArrayOfGridPos& rgp,
02636 const ArrayOfGridPos& cgp)
02637 {
02638 Index ns = sgp.nelem();
02639 Index nb = bgp.nelem();
02640 Index np = pgp.nelem();
02641 Index nr = rgp.nelem();
02642 Index nc = cgp.nelem();
02643 assert(is_size(ia,
02644 ns,nb,np,nr,nc));
02645 assert(is_size(itw,
02646 ns,nb,np,nr,nc,
02647 32));
02648
02649
02650
02651
02652 assert( is_same_within_epsilon( itw(0,0,0,0,0,Range(joker)).sum(),
02653 1,
02654 sum_check_epsilon ) );
02655
02656
02657 for ( Index is=0; is<ns; ++is )
02658 {
02659 const GridPos& ts = sgp[is];
02660 for ( Index ib=0; ib<nb; ++ib )
02661 {
02662 const GridPos& tb = bgp[ib];
02663 for ( Index ip=0; ip<np; ++ip )
02664 {
02665 const GridPos& tp = pgp[ip];
02666 for ( Index ir=0; ir<nr; ++ir )
02667 {
02668 const GridPos& tr = rgp[ir];
02669 for ( Index ic=0; ic<nc; ++ic )
02670 {
02671
02672 const GridPos& tc = cgp[ic];
02673
02674
02675
02676 Numeric& tia = ia(is,ib,ip,ir,ic);
02677 tia = 0;
02678
02679 Index iti = 0;
02680 for ( Index s=0; s<2; ++s )
02681 for ( Index b=0; b<2; ++b )
02682 for ( Index p=0; p<2; ++p )
02683 for ( Index r=0; r<2; ++r )
02684 for ( Index c=0; c<2; ++c )
02685 {
02686 tia += a(ts.idx+s,
02687 tb.idx+b,
02688 tp.idx+p,
02689 tr.idx+r,
02690 tc.idx+c) * itw(is,ib,ip,ir,ic,
02691 iti);
02692 ++iti;
02693 }
02694 }
02695 }
02696 }
02697 }
02698 }
02699 }
02700
02702
02727 void interp( Tensor6View ia,
02728 ConstTensor7View itw,
02729 ConstTensor6View a,
02730 const ArrayOfGridPos& vgp,
02731 const ArrayOfGridPos& sgp,
02732 const ArrayOfGridPos& bgp,
02733 const ArrayOfGridPos& pgp,
02734 const ArrayOfGridPos& rgp,
02735 const ArrayOfGridPos& cgp)
02736 {
02737 Index nv = vgp.nelem();
02738 Index ns = sgp.nelem();
02739 Index nb = bgp.nelem();
02740 Index np = pgp.nelem();
02741 Index nr = rgp.nelem();
02742 Index nc = cgp.nelem();
02743 assert(is_size(ia,
02744 nv,ns,nb,np,nr,nc));
02745 assert(is_size(itw,
02746 nv,ns,nb,np,nr,nc,
02747 64));
02748
02749
02750
02751
02752 assert( is_same_within_epsilon( itw(0,0,0,0,0,0,Range(joker)).sum(),
02753 1,
02754 sum_check_epsilon ) );
02755
02756
02757 for ( Index iv=0; iv<nv; ++iv )
02758 {
02759 const GridPos& tv = vgp[iv];
02760 for ( Index is=0; is<ns; ++is )
02761 {
02762 const GridPos& ts = sgp[is];
02763 for ( Index ib=0; ib<nb; ++ib )
02764 {
02765 const GridPos& tb = bgp[ib];
02766 for ( Index ip=0; ip<np; ++ip )
02767 {
02768 const GridPos& tp = pgp[ip];
02769 for ( Index ir=0; ir<nr; ++ir )
02770 {
02771 const GridPos& tr = rgp[ir];
02772 for ( Index ic=0; ic<nc; ++ic )
02773 {
02774
02775 const GridPos& tc = cgp[ic];
02776
02777
02778
02779 Numeric& tia = ia(iv,is,ib,ip,ir,ic);
02780 tia = 0;
02781
02782 Index iti = 0;
02783 for ( Index v=0; v<2; ++v )
02784 for ( Index s=0; s<2; ++s )
02785 for ( Index b=0; b<2; ++b )
02786 for ( Index p=0; p<2; ++p )
02787 for ( Index r=0; r<2; ++r )
02788 for ( Index c=0; c<2; ++c )
02789 {
02790 tia += a(tv.idx+v,
02791 ts.idx+s,
02792 tb.idx+b,
02793 tp.idx+p,
02794 tr.idx+r,
02795 tc.idx+c) * itw(iv,is,ib,ip,ir,ic,
02796 iti);
02797 ++iti;
02798 }
02799 }
02800 }
02801 }
02802 }
02803 }
02804 }
02805 }
02806
02807
02809
02824 Numeric interp_poly(ConstVectorView x,
02825 ConstVectorView y,
02826 const Numeric& x_i,
02827 const GridPos& gp)
02828 {
02829 Index N_x = x.nelem();
02830
02831 assert(N_x == y.nelem());
02832 assert(N_x > 2);
02833
02834 Vector xa(4), ya(4);
02835 Numeric y_int;
02836 Numeric dy_int;
02837 y_int = 0.;
02838
02839
02840
02841
02842
02843 Index interp_method = 1;
02844
02845 if (interp_method == 1)
02846 {
02847
02848
02849 if((gp.fd[0] <= 0.5 && gp.idx > 0) || gp.idx == N_x-2 )
02850 {
02851 xa[0] = x[gp.idx - 1];
02852 xa[1] = x[gp.idx];
02853 xa[2] = x[gp.idx + 1];
02854
02855 ya[0] = y[gp.idx - 1];
02856 ya[1] = y[gp.idx];
02857 ya[2] = y[gp.idx + 1];
02858 }
02859
02860 else if((gp.fd[0] > 0.5 && gp.idx < N_x-2) || gp.idx == 0 )
02861 {
02862 xa[0] = x[gp.idx];
02863 xa[1] = x[gp.idx + 1];
02864 xa[2] = x[gp.idx + 2];
02865
02866 ya[0] = y[gp.idx];
02867 ya[1] = y[gp.idx + 1];
02868 ya[2] = y[gp.idx + 2];
02869 }
02870
02871 else if(gp.idx == N_x-1)
02872 {
02873 xa[0] = x[N_x - 2];
02874 xa[1] = x[N_x - 1];
02875 xa[2] = x[N_x];
02876
02877 ya[0] = y[N_x - 2];
02878 ya[1] = y[N_x - 1];
02879 ya[2] = y[N_x];
02880 }
02881 else
02882 {
02883 assert(false);
02884 arts_exit();
02885 }
02886
02887 polint(y_int, dy_int, xa, ya, 3, x_i);
02888
02889 }
02890
02891 else if (interp_method == 2)
02892 {
02893 if( gp.idx == 0 )
02894 {
02895 xa[0] = x[gp.idx];
02896 xa[1] = x[gp.idx + 1];
02897 xa[2] = x[gp.idx + 2];
02898
02899 ya[0] = y[gp.idx];
02900 ya[1] = y[gp.idx + 1];
02901 ya[2] = y[gp.idx + 2];
02902 }
02903 else if(gp.idx == N_x-1)
02904 {
02905 xa[0] = x[gp.idx - 2];
02906 xa[1] = x[gp.idx - 1];
02907 xa[2] = x[gp.idx];
02908
02909 ya[0] = y[gp.idx - 2];
02910 ya[1] = y[gp.idx - 1];
02911 ya[2] = y[gp.idx];
02912 }
02913 else
02914 {
02915 xa[0] = x[gp.idx - 1];
02916 xa[1] = x[gp.idx];
02917 xa[2] = x[gp.idx + 1];
02918
02919 ya[0] = y[gp.idx - 1];
02920 ya[1] = y[gp.idx];
02921 ya[2] = y[gp.idx + 1];
02922 }
02923
02924
02925 polint(y_int, dy_int, xa, ya, 3, x_i);
02926 }
02927
02928 else if (interp_method == 3)
02929 {
02930
02931 if( gp.idx == 0 )
02932 {
02933 xa[0] = - x[gp.idx + 1];
02934 xa[1] = x[gp.idx + 0];
02935 xa[2] = x[gp.idx + 1];
02936 xa[3] = x[gp.idx + 2];
02937
02938 ya[0] = y[gp.idx + 1];
02939 ya[1] = y[gp.idx + 0];
02940 ya[2] = y[gp.idx + 1];
02941 ya[3] = y[gp.idx + 2];
02942 }
02943 else if(gp.idx == N_x-1)
02944 {
02945 xa[0] = x[gp.idx - 1];
02946 xa[1] = x[gp.idx - 0];
02947 xa[2] = 2*x[gp.idx] - x[gp.idx-1];
02948 xa[3] = 2*x[gp.idx] - x[gp.idx-2];
02949
02950 ya[0] = y[gp.idx - 1];
02951 ya[1] = y[gp.idx - 0];
02952 ya[2] = y[gp.idx - 1];
02953 ya[3] = y[gp.idx - 2];
02954 }
02955 else if(gp.idx == N_x-2)
02956 {
02957 xa[0] = x[gp.idx - 2];
02958 xa[1] = x[gp.idx - 1];
02959 xa[2] = x[gp.idx ];
02960 xa[3] = x[gp.idx + 1];
02961
02962 ya[0] = y[gp.idx - 2];
02963 ya[1] = y[gp.idx - 1];
02964 ya[2] = y[gp.idx];
02965 ya[3] = y[gp.idx + 1];
02966 }
02967 else
02968 {
02969 xa[0] = x[gp.idx - 1];
02970 xa[1] = x[gp.idx];
02971 xa[2] = x[gp.idx + 1];
02972 xa[3] = x[gp.idx + 2];
02973
02974 ya[0] = y[gp.idx - 1];
02975 ya[1] = y[gp.idx];
02976 ya[2] = y[gp.idx + 1];
02977 ya[3] = y[gp.idx + 2];
02978 }
02979
02980 polint(y_int, dy_int, xa, ya, 4, x_i);
02981 }
02982
02983
02984 return y_int;
02985 }
02986
02987
02988
02989
02991
03010 void polint(Numeric& y_int,
03011 Numeric& dy_int,
03012 ConstVectorView xa,
03013 ConstVectorView ya,
03014 const Index& n,
03015 const Numeric& x)
03016 {
03017 Index ns = 1;
03018 Numeric den, dif, dift, ho, hp, w;
03019
03020 dif = abs(x-xa[0]);
03021
03022 Vector c(n);
03023 Vector d(n);
03024
03025
03026 for(Index i=0; i<n; i++)
03027 {
03028 if( (dift = abs(x-xa[i])) < dif)
03029 {
03030 ns = i;
03031 dif = dift;
03032 }
03033
03034 c[i] = ya[i];
03035 d[i] = ya[i];
03036 }
03037
03038 y_int = ya[ns--];
03039
03040 for(Index m=1; m<n; m++)
03041 {
03042 for(Index i=0; i < n-m; i++)
03043 {
03044 ho = xa[i] - x;
03045 hp = xa[i+m] - x;
03046 w = c[i+1] - d[i];
03047 den = ho-hp;
03048
03049 assert(den != 0.);
03050 den = w/den;
03051 d[i] = hp * den;
03052 c[i] = ho * den;
03053 }
03054 y_int += (dy_int = (2*(ns+1) < (n-m) ? c[ns+1] : d[ns--] ));
03055 }
03056 }
03057
03058
03059
03060