gphys 1.2.2.1 → 1.4.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +8 -17
- data/.rspec +2 -0
- data/.travis.yml +3 -0
- data/ChangeLog +5762 -753
- data/LICENSE.txt +30 -18
- data/Rakefile +1 -0
- data/bin/console +14 -0
- data/bin/gpcat +43 -2
- data/bin/gpcut +16 -0
- data/bin/gpvect +167 -15
- data/bin/gpview +254 -51
- data/bin/setup +7 -0
- data/dim_op.c +1220 -0
- data/doc/attribute.html +19 -0
- data/doc/attributenetcdf.html +15 -0
- data/doc/axis.html +387 -0
- data/doc/coordmapping.html +111 -0
- data/doc/coordtransform.html +36 -0
- data/doc/dclext.html +821 -0
- data/doc/derivative/gphys-derivative.html +100 -0
- data/doc/derivative/index.html +21 -0
- data/doc/derivative/index.rd +14 -0
- data/doc/derivative/math-doc/document.pdf +0 -0
- data/doc/derivative/math-doc/document.tex +158 -0
- data/doc/derivative/math-doc/document/document.css +30 -0
- data/doc/derivative/math-doc/document/document.html +57 -0
- data/doc/derivative/math-doc/document/images.aux +1 -0
- data/doc/derivative/math-doc/document/images.log +385 -0
- data/doc/derivative/math-doc/document/images.pl +186 -0
- data/doc/derivative/math-doc/document/images.tex +364 -0
- data/doc/derivative/math-doc/document/img1.png +0 -0
- data/doc/derivative/math-doc/document/img10.png +0 -0
- data/doc/derivative/math-doc/document/img11.png +0 -0
- data/doc/derivative/math-doc/document/img12.png +0 -0
- data/doc/derivative/math-doc/document/img13.png +0 -0
- data/doc/derivative/math-doc/document/img14.png +0 -0
- data/doc/derivative/math-doc/document/img15.png +0 -0
- data/doc/derivative/math-doc/document/img16.png +0 -0
- data/doc/derivative/math-doc/document/img17.png +0 -0
- data/doc/derivative/math-doc/document/img18.png +0 -0
- data/doc/derivative/math-doc/document/img19.png +0 -0
- data/doc/derivative/math-doc/document/img2.png +0 -0
- data/doc/derivative/math-doc/document/img20.png +0 -0
- data/doc/derivative/math-doc/document/img21.png +0 -0
- data/doc/derivative/math-doc/document/img22.png +0 -0
- data/doc/derivative/math-doc/document/img23.png +0 -0
- data/doc/derivative/math-doc/document/img24.png +0 -0
- data/doc/derivative/math-doc/document/img25.png +0 -0
- data/doc/derivative/math-doc/document/img26.png +0 -0
- data/doc/derivative/math-doc/document/img27.png +0 -0
- data/doc/derivative/math-doc/document/img28.png +0 -0
- data/doc/derivative/math-doc/document/img29.png +0 -0
- data/doc/derivative/math-doc/document/img3.png +0 -0
- data/doc/derivative/math-doc/document/img30.png +0 -0
- data/doc/derivative/math-doc/document/img4.png +0 -0
- data/doc/derivative/math-doc/document/img5.png +0 -0
- data/doc/derivative/math-doc/document/img6.png +0 -0
- data/doc/derivative/math-doc/document/img7.png +0 -0
- data/doc/derivative/math-doc/document/img8.png +0 -0
- data/doc/derivative/math-doc/document/img9.png +0 -0
- data/doc/derivative/math-doc/document/index.html +57 -0
- data/doc/derivative/math-doc/document/labels.pl +13 -0
- data/doc/derivative/math-doc/document/next.png +0 -0
- data/doc/derivative/math-doc/document/next_g.png +0 -0
- data/doc/derivative/math-doc/document/node1.html +238 -0
- data/doc/derivative/math-doc/document/node2.html +75 -0
- data/doc/derivative/math-doc/document/prev.png +0 -0
- data/doc/derivative/math-doc/document/prev_g.png +0 -0
- data/doc/derivative/math-doc/document/up.png +0 -0
- data/doc/derivative/math-doc/document/up_g.png +0 -0
- data/doc/derivative/numru-derivative.html +158 -0
- data/doc/ep_flux/ep_flux.html +469 -0
- data/doc/ep_flux/ggraph_on_merdional_section.html +71 -0
- data/doc/ep_flux/index.html +31 -0
- data/doc/ep_flux/index.rd +24 -0
- data/doc/ep_flux/math-doc/document.pdf +0 -0
- data/doc/ep_flux/math-doc/document.tex +2018 -0
- data/doc/ep_flux/math-doc/document/WARNINGS +1 -0
- data/doc/ep_flux/math-doc/document/contents.png +0 -0
- data/doc/ep_flux/math-doc/document/crossref.png +0 -0
- data/doc/ep_flux/math-doc/document/document.css +30 -0
- data/doc/ep_flux/math-doc/document/document.html +101 -0
- data/doc/ep_flux/math-doc/document/images.aux +1 -0
- data/doc/ep_flux/math-doc/document/images.log +1375 -0
- data/doc/ep_flux/math-doc/document/images.pl +1328 -0
- data/doc/ep_flux/math-doc/document/images.tex +1471 -0
- data/doc/ep_flux/math-doc/document/img1.png +0 -0
- data/doc/ep_flux/math-doc/document/img10.png +0 -0
- data/doc/ep_flux/math-doc/document/img100.png +0 -0
- data/doc/ep_flux/math-doc/document/img101.png +0 -0
- data/doc/ep_flux/math-doc/document/img102.png +0 -0
- data/doc/ep_flux/math-doc/document/img103.png +0 -0
- data/doc/ep_flux/math-doc/document/img104.png +0 -0
- data/doc/ep_flux/math-doc/document/img105.png +0 -0
- data/doc/ep_flux/math-doc/document/img106.png +0 -0
- data/doc/ep_flux/math-doc/document/img107.png +0 -0
- data/doc/ep_flux/math-doc/document/img108.png +0 -0
- data/doc/ep_flux/math-doc/document/img109.png +0 -0
- data/doc/ep_flux/math-doc/document/img11.png +0 -0
- data/doc/ep_flux/math-doc/document/img110.png +0 -0
- data/doc/ep_flux/math-doc/document/img111.png +0 -0
- data/doc/ep_flux/math-doc/document/img112.png +0 -0
- data/doc/ep_flux/math-doc/document/img113.png +0 -0
- data/doc/ep_flux/math-doc/document/img114.png +0 -0
- data/doc/ep_flux/math-doc/document/img115.png +0 -0
- data/doc/ep_flux/math-doc/document/img116.png +0 -0
- data/doc/ep_flux/math-doc/document/img117.png +0 -0
- data/doc/ep_flux/math-doc/document/img118.png +0 -0
- data/doc/ep_flux/math-doc/document/img119.png +0 -0
- data/doc/ep_flux/math-doc/document/img12.png +0 -0
- data/doc/ep_flux/math-doc/document/img120.png +0 -0
- data/doc/ep_flux/math-doc/document/img121.png +0 -0
- data/doc/ep_flux/math-doc/document/img122.png +0 -0
- data/doc/ep_flux/math-doc/document/img123.png +0 -0
- data/doc/ep_flux/math-doc/document/img124.png +0 -0
- data/doc/ep_flux/math-doc/document/img125.png +0 -0
- data/doc/ep_flux/math-doc/document/img126.png +0 -0
- data/doc/ep_flux/math-doc/document/img127.png +0 -0
- data/doc/ep_flux/math-doc/document/img128.png +0 -0
- data/doc/ep_flux/math-doc/document/img129.png +0 -0
- data/doc/ep_flux/math-doc/document/img13.png +0 -0
- data/doc/ep_flux/math-doc/document/img130.png +0 -0
- data/doc/ep_flux/math-doc/document/img131.png +0 -0
- data/doc/ep_flux/math-doc/document/img132.png +0 -0
- data/doc/ep_flux/math-doc/document/img133.png +0 -0
- data/doc/ep_flux/math-doc/document/img134.png +0 -0
- data/doc/ep_flux/math-doc/document/img135.png +0 -0
- data/doc/ep_flux/math-doc/document/img136.png +0 -0
- data/doc/ep_flux/math-doc/document/img137.png +0 -0
- data/doc/ep_flux/math-doc/document/img138.png +0 -0
- data/doc/ep_flux/math-doc/document/img139.png +0 -0
- data/doc/ep_flux/math-doc/document/img14.png +0 -0
- data/doc/ep_flux/math-doc/document/img140.png +0 -0
- data/doc/ep_flux/math-doc/document/img141.png +0 -0
- data/doc/ep_flux/math-doc/document/img142.png +0 -0
- data/doc/ep_flux/math-doc/document/img143.png +0 -0
- data/doc/ep_flux/math-doc/document/img144.png +0 -0
- data/doc/ep_flux/math-doc/document/img145.png +0 -0
- data/doc/ep_flux/math-doc/document/img146.png +0 -0
- data/doc/ep_flux/math-doc/document/img147.png +0 -0
- data/doc/ep_flux/math-doc/document/img148.png +0 -0
- data/doc/ep_flux/math-doc/document/img149.png +0 -0
- data/doc/ep_flux/math-doc/document/img15.png +0 -0
- data/doc/ep_flux/math-doc/document/img150.png +0 -0
- data/doc/ep_flux/math-doc/document/img151.png +0 -0
- data/doc/ep_flux/math-doc/document/img152.png +0 -0
- data/doc/ep_flux/math-doc/document/img153.png +0 -0
- data/doc/ep_flux/math-doc/document/img154.png +0 -0
- data/doc/ep_flux/math-doc/document/img155.png +0 -0
- data/doc/ep_flux/math-doc/document/img156.png +0 -0
- data/doc/ep_flux/math-doc/document/img157.png +0 -0
- data/doc/ep_flux/math-doc/document/img158.png +0 -0
- data/doc/ep_flux/math-doc/document/img159.png +0 -0
- data/doc/ep_flux/math-doc/document/img16.png +0 -0
- data/doc/ep_flux/math-doc/document/img160.png +0 -0
- data/doc/ep_flux/math-doc/document/img161.png +0 -0
- data/doc/ep_flux/math-doc/document/img162.png +0 -0
- data/doc/ep_flux/math-doc/document/img163.png +0 -0
- data/doc/ep_flux/math-doc/document/img164.png +0 -0
- data/doc/ep_flux/math-doc/document/img165.png +0 -0
- data/doc/ep_flux/math-doc/document/img166.png +0 -0
- data/doc/ep_flux/math-doc/document/img167.png +0 -0
- data/doc/ep_flux/math-doc/document/img168.png +0 -0
- data/doc/ep_flux/math-doc/document/img169.png +0 -0
- data/doc/ep_flux/math-doc/document/img17.png +0 -0
- data/doc/ep_flux/math-doc/document/img170.png +0 -0
- data/doc/ep_flux/math-doc/document/img171.png +0 -0
- data/doc/ep_flux/math-doc/document/img172.png +0 -0
- data/doc/ep_flux/math-doc/document/img173.png +0 -0
- data/doc/ep_flux/math-doc/document/img174.png +0 -0
- data/doc/ep_flux/math-doc/document/img175.png +0 -0
- data/doc/ep_flux/math-doc/document/img176.png +0 -0
- data/doc/ep_flux/math-doc/document/img177.png +0 -0
- data/doc/ep_flux/math-doc/document/img178.png +0 -0
- data/doc/ep_flux/math-doc/document/img179.png +0 -0
- data/doc/ep_flux/math-doc/document/img18.png +0 -0
- data/doc/ep_flux/math-doc/document/img180.png +0 -0
- data/doc/ep_flux/math-doc/document/img181.png +0 -0
- data/doc/ep_flux/math-doc/document/img182.png +0 -0
- data/doc/ep_flux/math-doc/document/img183.png +0 -0
- data/doc/ep_flux/math-doc/document/img184.png +0 -0
- data/doc/ep_flux/math-doc/document/img185.png +0 -0
- data/doc/ep_flux/math-doc/document/img186.png +0 -0
- data/doc/ep_flux/math-doc/document/img187.png +0 -0
- data/doc/ep_flux/math-doc/document/img188.png +0 -0
- data/doc/ep_flux/math-doc/document/img189.png +0 -0
- data/doc/ep_flux/math-doc/document/img19.png +0 -0
- data/doc/ep_flux/math-doc/document/img190.png +0 -0
- data/doc/ep_flux/math-doc/document/img191.png +0 -0
- data/doc/ep_flux/math-doc/document/img192.png +0 -0
- data/doc/ep_flux/math-doc/document/img193.png +0 -0
- data/doc/ep_flux/math-doc/document/img194.png +0 -0
- data/doc/ep_flux/math-doc/document/img195.png +0 -0
- data/doc/ep_flux/math-doc/document/img196.png +0 -0
- data/doc/ep_flux/math-doc/document/img197.png +0 -0
- data/doc/ep_flux/math-doc/document/img198.png +0 -0
- data/doc/ep_flux/math-doc/document/img199.png +0 -0
- data/doc/ep_flux/math-doc/document/img2.png +0 -0
- data/doc/ep_flux/math-doc/document/img20.png +0 -0
- data/doc/ep_flux/math-doc/document/img200.png +0 -0
- data/doc/ep_flux/math-doc/document/img21.png +0 -0
- data/doc/ep_flux/math-doc/document/img22.png +0 -0
- data/doc/ep_flux/math-doc/document/img23.png +0 -0
- data/doc/ep_flux/math-doc/document/img24.png +0 -0
- data/doc/ep_flux/math-doc/document/img25.png +0 -0
- data/doc/ep_flux/math-doc/document/img26.png +0 -0
- data/doc/ep_flux/math-doc/document/img27.png +0 -0
- data/doc/ep_flux/math-doc/document/img28.png +0 -0
- data/doc/ep_flux/math-doc/document/img29.png +0 -0
- data/doc/ep_flux/math-doc/document/img3.png +0 -0
- data/doc/ep_flux/math-doc/document/img30.png +0 -0
- data/doc/ep_flux/math-doc/document/img31.png +0 -0
- data/doc/ep_flux/math-doc/document/img32.png +0 -0
- data/doc/ep_flux/math-doc/document/img33.png +0 -0
- data/doc/ep_flux/math-doc/document/img34.png +0 -0
- data/doc/ep_flux/math-doc/document/img35.png +0 -0
- data/doc/ep_flux/math-doc/document/img36.png +0 -0
- data/doc/ep_flux/math-doc/document/img37.png +0 -0
- data/doc/ep_flux/math-doc/document/img38.png +0 -0
- data/doc/ep_flux/math-doc/document/img39.png +0 -0
- data/doc/ep_flux/math-doc/document/img4.png +0 -0
- data/doc/ep_flux/math-doc/document/img40.png +0 -0
- data/doc/ep_flux/math-doc/document/img41.png +0 -0
- data/doc/ep_flux/math-doc/document/img42.png +0 -0
- data/doc/ep_flux/math-doc/document/img43.png +0 -0
- data/doc/ep_flux/math-doc/document/img44.png +0 -0
- data/doc/ep_flux/math-doc/document/img45.png +0 -0
- data/doc/ep_flux/math-doc/document/img46.png +0 -0
- data/doc/ep_flux/math-doc/document/img47.png +0 -0
- data/doc/ep_flux/math-doc/document/img48.png +0 -0
- data/doc/ep_flux/math-doc/document/img49.png +0 -0
- data/doc/ep_flux/math-doc/document/img5.png +0 -0
- data/doc/ep_flux/math-doc/document/img50.png +0 -0
- data/doc/ep_flux/math-doc/document/img51.png +0 -0
- data/doc/ep_flux/math-doc/document/img52.png +0 -0
- data/doc/ep_flux/math-doc/document/img53.png +0 -0
- data/doc/ep_flux/math-doc/document/img54.png +0 -0
- data/doc/ep_flux/math-doc/document/img55.png +0 -0
- data/doc/ep_flux/math-doc/document/img56.png +0 -0
- data/doc/ep_flux/math-doc/document/img57.png +0 -0
- data/doc/ep_flux/math-doc/document/img58.png +0 -0
- data/doc/ep_flux/math-doc/document/img59.png +0 -0
- data/doc/ep_flux/math-doc/document/img6.png +0 -0
- data/doc/ep_flux/math-doc/document/img60.png +0 -0
- data/doc/ep_flux/math-doc/document/img61.png +0 -0
- data/doc/ep_flux/math-doc/document/img62.png +0 -0
- data/doc/ep_flux/math-doc/document/img63.png +0 -0
- data/doc/ep_flux/math-doc/document/img64.png +0 -0
- data/doc/ep_flux/math-doc/document/img65.png +0 -0
- data/doc/ep_flux/math-doc/document/img66.png +0 -0
- data/doc/ep_flux/math-doc/document/img67.png +0 -0
- data/doc/ep_flux/math-doc/document/img68.png +0 -0
- data/doc/ep_flux/math-doc/document/img69.png +0 -0
- data/doc/ep_flux/math-doc/document/img7.png +0 -0
- data/doc/ep_flux/math-doc/document/img70.png +0 -0
- data/doc/ep_flux/math-doc/document/img71.png +0 -0
- data/doc/ep_flux/math-doc/document/img72.png +0 -0
- data/doc/ep_flux/math-doc/document/img73.png +0 -0
- data/doc/ep_flux/math-doc/document/img74.png +0 -0
- data/doc/ep_flux/math-doc/document/img75.png +0 -0
- data/doc/ep_flux/math-doc/document/img76.png +0 -0
- data/doc/ep_flux/math-doc/document/img77.png +0 -0
- data/doc/ep_flux/math-doc/document/img78.png +0 -0
- data/doc/ep_flux/math-doc/document/img79.png +0 -0
- data/doc/ep_flux/math-doc/document/img8.png +0 -0
- data/doc/ep_flux/math-doc/document/img80.png +0 -0
- data/doc/ep_flux/math-doc/document/img81.png +0 -0
- data/doc/ep_flux/math-doc/document/img82.png +0 -0
- data/doc/ep_flux/math-doc/document/img83.png +0 -0
- data/doc/ep_flux/math-doc/document/img84.png +0 -0
- data/doc/ep_flux/math-doc/document/img85.png +0 -0
- data/doc/ep_flux/math-doc/document/img86.png +0 -0
- data/doc/ep_flux/math-doc/document/img87.png +0 -0
- data/doc/ep_flux/math-doc/document/img88.png +0 -0
- data/doc/ep_flux/math-doc/document/img89.png +0 -0
- data/doc/ep_flux/math-doc/document/img9.png +0 -0
- data/doc/ep_flux/math-doc/document/img90.png +0 -0
- data/doc/ep_flux/math-doc/document/img91.png +0 -0
- data/doc/ep_flux/math-doc/document/img92.png +0 -0
- data/doc/ep_flux/math-doc/document/img93.png +0 -0
- data/doc/ep_flux/math-doc/document/img94.png +0 -0
- data/doc/ep_flux/math-doc/document/img95.png +0 -0
- data/doc/ep_flux/math-doc/document/img96.png +0 -0
- data/doc/ep_flux/math-doc/document/img97.png +0 -0
- data/doc/ep_flux/math-doc/document/img98.png +0 -0
- data/doc/ep_flux/math-doc/document/img99.png +0 -0
- data/doc/ep_flux/math-doc/document/index.html +101 -0
- data/doc/ep_flux/math-doc/document/internals.pl +258 -0
- data/doc/ep_flux/math-doc/document/labels.pl +265 -0
- data/doc/ep_flux/math-doc/document/next.png +0 -0
- data/doc/ep_flux/math-doc/document/next_g.png +0 -0
- data/doc/ep_flux/math-doc/document/node1.html +104 -0
- data/doc/ep_flux/math-doc/document/node10.html +164 -0
- data/doc/ep_flux/math-doc/document/node11.html +86 -0
- data/doc/ep_flux/math-doc/document/node12.html +166 -0
- data/doc/ep_flux/math-doc/document/node13.html +897 -0
- data/doc/ep_flux/math-doc/document/node14.html +1065 -0
- data/doc/ep_flux/math-doc/document/node15.html +72 -0
- data/doc/ep_flux/math-doc/document/node16.html +81 -0
- data/doc/ep_flux/math-doc/document/node2.html +82 -0
- data/doc/ep_flux/math-doc/document/node3.html +91 -0
- data/doc/ep_flux/math-doc/document/node4.html +149 -0
- data/doc/ep_flux/math-doc/document/node5.html +330 -0
- data/doc/ep_flux/math-doc/document/node6.html +99 -0
- data/doc/ep_flux/math-doc/document/node7.html +98 -0
- data/doc/ep_flux/math-doc/document/node8.html +83 -0
- data/doc/ep_flux/math-doc/document/node9.html +140 -0
- data/doc/ep_flux/math-doc/document/prev.png +0 -0
- data/doc/ep_flux/math-doc/document/prev_g.png +0 -0
- data/doc/ep_flux/math-doc/document/up.png +0 -0
- data/doc/ep_flux/math-doc/document/up_g.png +0 -0
- data/doc/gdir.html +412 -0
- data/doc/gdir_client.html +16 -0
- data/doc/gdir_connect_ftp-like.html +61 -0
- data/doc/gdir_server.html +45 -0
- data/doc/ggraph.html +1119 -0
- data/doc/gpcat.html +45 -0
- data/doc/gpcut.html +47 -0
- data/doc/gphys.html +624 -0
- data/doc/gphys_fft.html +324 -0
- data/doc/gphys_grads_io.html +69 -0
- data/doc/gphys_grib_io.html +82 -0
- data/doc/gphys_io.html +183 -0
- data/doc/gphys_io_common.html +18 -0
- data/doc/gphys_netcdf_io.html +283 -0
- data/doc/gplist.html +24 -0
- data/doc/gpmath.html +52 -0
- data/doc/gpmaxmin.html +32 -0
- data/doc/gpprint.html +35 -0
- data/doc/gpview.html +349 -0
- data/doc/grads2nc_with_gphys.html +21 -0
- data/doc/grads_gridded.html +307 -0
- data/doc/grib.html +149 -0
- data/doc/grid.html +224 -0
- data/doc/index.html +145 -0
- data/doc/index.rd +138 -0
- data/doc/netcdf_convention.html +136 -0
- data/doc/unumeric.html +176 -0
- data/doc/update +69 -0
- data/doc/update_rdoc +8 -0
- data/doc/varray.html +299 -0
- data/doc/varraycomposite.html +67 -0
- data/ext_init.c +1 -0
- data/extconf.rb +16 -6
- data/gphys.gemspec +33 -26
- data/interpo.c +1 -1
- data/lib/numru/dclext.rb +718 -546
- data/lib/numru/derivative.rb +2 -0
- data/lib/numru/ganalysis.rb +38 -0
- data/lib/numru/ganalysis/beta_plane.rb +103 -0
- data/lib/numru/ganalysis/eof.rb +3 -2
- data/lib/numru/ganalysis/fitting.rb +559 -0
- data/lib/numru/ganalysis/histogram.rb +36 -19
- data/lib/numru/ganalysis/log_p.rb +130 -0
- data/lib/numru/ganalysis/met.rb +396 -2
- data/lib/numru/ganalysis/met_z.rb +300 -0
- data/lib/numru/ganalysis/planet.rb +17 -7
- data/lib/numru/ganalysis/qg.rb +685 -0
- data/lib/numru/ganalysis/sigma_coord.rb +90 -0
- data/lib/numru/gdir.rb +2 -1
- data/lib/numru/ggraph.rb +204 -60
- data/lib/numru/ggraph_on_merdional_section.rb +1 -1
- data/lib/numru/gphys.rb +6 -0
- data/lib/numru/gphys/assoccoords.rb +18 -3
- data/lib/numru/gphys/axis.rb +209 -8
- data/lib/numru/gphys/derivative.rb +11 -0
- data/lib/numru/gphys/gphys.rb +539 -48
- data/lib/numru/gphys/gphys_dim_op.rb +331 -0
- data/lib/numru/gphys/gphys_fft.rb +48 -2
- data/lib/numru/gphys/gphys_io.rb +241 -13
- data/lib/numru/gphys/gphys_netcdf_io.rb +77 -39
- data/lib/numru/gphys/gphys_nusdas_io.rb +3 -0
- data/lib/numru/gphys/grib.rb +133 -54
- data/lib/numru/gphys/grib_params.rb +26 -3
- data/lib/numru/gphys/grid.rb +75 -34
- data/lib/numru/gphys/interpolate.rb +24 -10
- data/lib/numru/gphys/mdstorage.rb +160 -0
- data/lib/numru/gphys/netcdf_convention.rb +4 -2
- data/lib/numru/gphys/subsetmapping.rb +0 -1
- data/lib/numru/gphys/unumeric.rb +50 -5
- data/lib/numru/gphys/varray.rb +15 -30
- data/lib/numru/gphys/varraycomposite.rb +107 -24
- data/lib/numru/gphys/varraynetcdf.rb +9 -3
- data/lib/numru/gphys/version.rb +5 -0
- data/sample/druby_cli1.rb +2 -0
- data/sample/druby_cli2.rb +0 -6
- data/sample/druby_serv2.rb +0 -13
- data/spec/gphys_spec.rb +11 -0
- data/spec/spec_helper.rb +2 -0
- data/test/test_assoccoords.rb +102 -0
- data/test/test_axis.rb +61 -0
- data/test/test_fitting.rb +116 -0
- data/test/test_gphys.rb +20 -0
- data/test/test_met_z.rb +96 -0
- data/test/test_sigma_coord.rb +50 -0
- data/{test → test_old}/eof_slp.rb +0 -0
- data/{test → test_old}/mltbit.dat +0 -0
- data/{test → test_old}/test_ep_flux.rb +0 -0
- data/{test → test_old}/test_multibitIO.rb +0 -0
- metadata +530 -191
- data/README.md +0 -29
- data/lib/gphys.rb +0 -2
- data/lib/numru/dclext_datetime_ax.rb +0 -220
- data/lib/version.rb +0 -3
data/bin/setup
ADDED
data/dim_op.c
ADDED
@@ -0,0 +1,1220 @@
|
|
1
|
+
/* dim_op.c : engine of operations along a dimension (e.g. running mean)
|
2
|
+
*/
|
3
|
+
|
4
|
+
#include<stdio.h>
|
5
|
+
#include<string.h>
|
6
|
+
#include "ruby.h"
|
7
|
+
#include "narray.h"
|
8
|
+
#include<math.h>
|
9
|
+
|
10
|
+
#ifndef RARRAY_PTR
|
11
|
+
# define RARRAY_PTR(ary) (RARRAY(ary)->ptr)
|
12
|
+
#endif
|
13
|
+
#ifndef RARRAY_LEN
|
14
|
+
# define RARRAY_LEN(ary) (RARRAY(ary)->len)
|
15
|
+
#endif
|
16
|
+
|
17
|
+
#ifndef HAVE_NA_SHAPE_T
|
18
|
+
typedef int na_shape_t;
|
19
|
+
#endif
|
20
|
+
|
21
|
+
enum bc_type {
|
22
|
+
BC_SIMPLE=10,
|
23
|
+
BC_CYCLIC=11,
|
24
|
+
BC_TRIM=12
|
25
|
+
};
|
26
|
+
|
27
|
+
#define ID3(i,j,k) ((i) + (j)*n0 + (k)*n0*n1)
|
28
|
+
#define ID3T(i,j,k) ((i) + (j)*n0 + (k)*n0*(n1-wlen+1))
|
29
|
+
#define ID3o(i,j,k) ((i) + (j)*n0 + (k)*n0*n1o)
|
30
|
+
#define ID3z(i,j,k) ((i) + (j)*n0 + (k)*n0*nz)
|
31
|
+
#define ID3c(i,j,k) ((i) + (j)*n0 + (k)*n0*nc)
|
32
|
+
#define ID2(i,j) ((i) + (j)*n0)
|
33
|
+
|
34
|
+
static int
|
35
|
+
convol_result_length(na_shape_t n1, na_shape_t wlen, int ibc)
|
36
|
+
{
|
37
|
+
int n1o;
|
38
|
+
switch (ibc) {
|
39
|
+
case BC_SIMPLE:
|
40
|
+
case BC_CYCLIC:
|
41
|
+
n1o = n1;
|
42
|
+
break;
|
43
|
+
case BC_TRIM:
|
44
|
+
n1o = n1-wlen+1;
|
45
|
+
break;
|
46
|
+
}
|
47
|
+
return n1o;
|
48
|
+
}
|
49
|
+
|
50
|
+
static void
|
51
|
+
running_mean_nomiss(zi,n0,n1,n2, w,wlen, ibc, zo)
|
52
|
+
// IN
|
53
|
+
double *zi;
|
54
|
+
na_shape_t n0;
|
55
|
+
na_shape_t n1;
|
56
|
+
na_shape_t n2;
|
57
|
+
double *w;
|
58
|
+
na_shape_t wlen;
|
59
|
+
int ibc;
|
60
|
+
// OUT
|
61
|
+
double *zo; // must have been set to 0 everywhere
|
62
|
+
{
|
63
|
+
na_shape_t i,j,k,m, jj;
|
64
|
+
na_shape_t wl2s, wl2;
|
65
|
+
double wsum;
|
66
|
+
double *wc; // scaled w (sum wc == 1)
|
67
|
+
double *wcsum1,*wcsum2; // for BC_SIMPLE; for shorter summation at edges
|
68
|
+
double wcm; // modified wcm for shorter summation
|
69
|
+
|
70
|
+
wl2s = (wlen - 1)/2; // e.g. 7->3, 6->2
|
71
|
+
wl2 = wlen/2; // e.g. 7->3, 6->3; wl2s + wl2 == wlen - 1
|
72
|
+
|
73
|
+
// < scale w to make its sum == 1 >
|
74
|
+
|
75
|
+
for (m=0,wsum=0.0; m<wlen; m++) {
|
76
|
+
wsum += w[m];
|
77
|
+
}
|
78
|
+
if (wsum != 1.0) {
|
79
|
+
wc = ALLOCA_N(double, wlen);
|
80
|
+
for (m=0; m<wlen; m++) {
|
81
|
+
wc[m] = w[m] / wsum;
|
82
|
+
}
|
83
|
+
} else {
|
84
|
+
wc = w;
|
85
|
+
}
|
86
|
+
|
87
|
+
// < weighted running mean >
|
88
|
+
|
89
|
+
switch (ibc) {
|
90
|
+
case BC_SIMPLE:
|
91
|
+
wcsum1 = ALLOCA_N(double, wl2s);
|
92
|
+
wcsum1[0] = 1.0 - wc[0]; // sum of wc[1...wlen]
|
93
|
+
for (m=1; m<wl2s; m++) {
|
94
|
+
wcsum1[m] = wcsum1[m-1] - wc[m]; // sum of wc[m+1...wlen]
|
95
|
+
}
|
96
|
+
wcsum2 = ALLOCA_N(double, wl2);
|
97
|
+
wcsum2[0] = 1.0 - wc[wlen-1]; // sum of wc[0...wlen-1]
|
98
|
+
for (m=wlen-2; m>wlen-1-wl2; m--) {
|
99
|
+
wcsum2[wlen-1-m] = wcsum2[wlen-2-m] - wc[m]; // sum of wc[0...m]
|
100
|
+
} // 1..wl2-1 with m
|
101
|
+
|
102
|
+
for (k=0; k<n2; k++) {
|
103
|
+
// where j is close to the "left" end
|
104
|
+
for (j=0; j<wl2s; j++) {
|
105
|
+
for (m=-j+wl2s; m<wlen; m++) {
|
106
|
+
wcm = wc[m] / wcsum1[wl2s-1-j];
|
107
|
+
for (i=0; i<n0; i++) {
|
108
|
+
zo[ID3(i,j,k)] += wcm*zi[ID3(i,j-wl2s+m,k)];
|
109
|
+
} //^^^^^^^^ from 0
|
110
|
+
}
|
111
|
+
}
|
112
|
+
// where grids are enough on both sides
|
113
|
+
for (j=wl2s; j<n1-wl2; j++) {
|
114
|
+
for (m=0; m<wlen; m++) {
|
115
|
+
for (i=0; i<n0; i++) {
|
116
|
+
zo[ID3(i,j,k)] += wc[m]*zi[ID3(i,j-wl2s+m,k)];
|
117
|
+
}
|
118
|
+
}
|
119
|
+
}
|
120
|
+
// where j is close to the "right" end
|
121
|
+
for (j=n1-wl2; j<n1; j++) {
|
122
|
+
for (m=0; m<n1-j+wl2s; m++) {
|
123
|
+
wcm = wc[m] / wcsum2[j-n1+wl2]; // wcsum2: 0...wl2
|
124
|
+
for (i=0; i<n0; i++) {
|
125
|
+
zo[ID3(i,j,k)] += wcm*zi[ID3(i,j-wl2s+m,k)];
|
126
|
+
} //^^^^^^^^ upto n1-1
|
127
|
+
}
|
128
|
+
}
|
129
|
+
}
|
130
|
+
break;
|
131
|
+
case BC_CYCLIC:
|
132
|
+
for (k=0; k<n2; k++) {
|
133
|
+
for (j=0; j<n1; j++) {
|
134
|
+
for (m=0; m<wlen; m++) {
|
135
|
+
jj = j-wl2s+m;
|
136
|
+
if ( jj < 0 ) {
|
137
|
+
jj += n1;
|
138
|
+
} else {
|
139
|
+
jj %= n1;
|
140
|
+
}
|
141
|
+
for (i=0; i<n0; i++) {
|
142
|
+
zo[ID3(i,j,k)] += wc[m]*zi[ID3(i,jj,k)];
|
143
|
+
}
|
144
|
+
}
|
145
|
+
}
|
146
|
+
}
|
147
|
+
break;
|
148
|
+
case BC_TRIM:
|
149
|
+
// trim where extra grids are not enough
|
150
|
+
for (k=0; k<n2; k++) {
|
151
|
+
for (j=0; j<n1-wlen+1; j++) {
|
152
|
+
for (m=0; m<wlen; m++) {
|
153
|
+
for (i=0; i<n0; i++) {
|
154
|
+
zo[ID3T(i,j,k)] += wc[m]*zi[ID3(i,j+m,k)];
|
155
|
+
}
|
156
|
+
}
|
157
|
+
}
|
158
|
+
}
|
159
|
+
break;
|
160
|
+
default:
|
161
|
+
rb_raise(rb_eArgError,"Undefined boundary condision (%d)", ibc);
|
162
|
+
break;
|
163
|
+
}
|
164
|
+
}
|
165
|
+
|
166
|
+
|
167
|
+
static void
|
168
|
+
running_mean_miss(zi,n0,n1,n2, w,wlen, ibc, zmiss,nminvalid, zo)
|
169
|
+
// IN
|
170
|
+
double *zi;
|
171
|
+
na_shape_t n0;
|
172
|
+
na_shape_t n1;
|
173
|
+
na_shape_t n2;
|
174
|
+
double *w;
|
175
|
+
na_shape_t wlen;
|
176
|
+
int ibc;
|
177
|
+
double zmiss;
|
178
|
+
int nminvalid;
|
179
|
+
// OUT
|
180
|
+
double *zo; // must have been set to 0 everywhere
|
181
|
+
{
|
182
|
+
na_shape_t i,j,k,m, jj;
|
183
|
+
na_shape_t wl2s, wl2;
|
184
|
+
double wsum;
|
185
|
+
int nm;
|
186
|
+
|
187
|
+
wl2s = (wlen - 1)/2; // e.g. 7->3, 6->2
|
188
|
+
wl2 = wlen/2; // e.g. 7->3, 6->3; wl2s + wl2 == wlen - 1
|
189
|
+
|
190
|
+
// < weighted running mean >
|
191
|
+
|
192
|
+
switch (ibc) {
|
193
|
+
case BC_SIMPLE:
|
194
|
+
for (k=0; k<n2; k++) {
|
195
|
+
// where j is close to the "left" end
|
196
|
+
for (j=0; j<wl2s; j++) {
|
197
|
+
for (i=0; i<n0; i++) {
|
198
|
+
wsum = 0.0;
|
199
|
+
nm = 0;
|
200
|
+
for (m=-j+wl2s; m<wlen; m++) {
|
201
|
+
if ( zi[ID3(i,j-wl2s+m,k)] != zmiss ) {
|
202
|
+
zo[ID3(i,j,k)] += w[m]*zi[ID3(i,j-wl2s+m,k)];
|
203
|
+
//^^^^^^^^ from 0
|
204
|
+
wsum += w[m];
|
205
|
+
nm++;
|
206
|
+
}
|
207
|
+
}
|
208
|
+
if (nm >= nminvalid) {
|
209
|
+
zo[ID3(i,j,k)] /= wsum;
|
210
|
+
} else {
|
211
|
+
zo[ID3(i,j,k)] = zmiss;
|
212
|
+
}
|
213
|
+
}
|
214
|
+
}
|
215
|
+
// where grids are enough on both sides
|
216
|
+
for (j=wl2s; j<n1-wl2; j++) {
|
217
|
+
for (i=0; i<n0; i++) {
|
218
|
+
wsum = 0.0;
|
219
|
+
nm = 0;
|
220
|
+
for (m=0; m<wlen; m++) {
|
221
|
+
if ( zi[ID3(i,j-wl2s+m,k)] != zmiss ) {
|
222
|
+
zo[ID3(i,j,k)] += w[m]*zi[ID3(i,j-wl2s+m,k)];
|
223
|
+
wsum += w[m];
|
224
|
+
nm++;
|
225
|
+
}
|
226
|
+
}
|
227
|
+
if (nm >= nminvalid) {
|
228
|
+
zo[ID3(i,j,k)] /= wsum;
|
229
|
+
} else {
|
230
|
+
zo[ID3(i,j,k)] = zmiss;
|
231
|
+
}
|
232
|
+
}
|
233
|
+
}
|
234
|
+
// where j is close to the "right" end
|
235
|
+
for (j=n1-wl2; j<n1; j++) {
|
236
|
+
for (i=0; i<n0; i++) {
|
237
|
+
wsum = 0.0;
|
238
|
+
nm = 0;
|
239
|
+
for (m=0; m<n1-j+wl2s; m++) {
|
240
|
+
if ( zi[ID3(i,j-wl2s+m,k)] != zmiss ) {
|
241
|
+
zo[ID3(i,j,k)] += w[m]*zi[ID3(i,j-wl2s+m,k)];
|
242
|
+
//^^^^^^^^ upto n1-1
|
243
|
+
wsum += w[m];
|
244
|
+
nm++;
|
245
|
+
}
|
246
|
+
}
|
247
|
+
if (nm >= nminvalid) {
|
248
|
+
zo[ID3(i,j,k)] /= wsum;
|
249
|
+
} else {
|
250
|
+
zo[ID3(i,j,k)] = zmiss;
|
251
|
+
}
|
252
|
+
}
|
253
|
+
}
|
254
|
+
}
|
255
|
+
break;
|
256
|
+
case BC_CYCLIC:
|
257
|
+
for (k=0; k<n2; k++) {
|
258
|
+
for (j=0; j<n1; j++) {
|
259
|
+
for (i=0; i<n0; i++) {
|
260
|
+
wsum = 0.0;
|
261
|
+
nm = 0;
|
262
|
+
for (m=0; m<wlen; m++) {
|
263
|
+
jj = j-wl2s+m;
|
264
|
+
if ( jj < 0 ) {
|
265
|
+
jj += n1;
|
266
|
+
} else {
|
267
|
+
jj %= n1;
|
268
|
+
}
|
269
|
+
if ( zi[ID3(i,jj,k)] != zmiss ) {
|
270
|
+
zo[ID3(i,j,k)] += w[m]*zi[ID3(i,jj,k)];
|
271
|
+
wsum += w[m];
|
272
|
+
nm++;
|
273
|
+
}
|
274
|
+
}
|
275
|
+
if (nm >= nminvalid) {
|
276
|
+
zo[ID3(i,j,k)] /= wsum;
|
277
|
+
} else {
|
278
|
+
zo[ID3(i,j,k)] = zmiss;
|
279
|
+
}
|
280
|
+
}
|
281
|
+
}
|
282
|
+
}
|
283
|
+
break;
|
284
|
+
case BC_TRIM:
|
285
|
+
// trim where extra grids are not enough
|
286
|
+
for (k=0; k<n2; k++) {
|
287
|
+
for (j=0; j<n1-wlen+1; j++) {
|
288
|
+
for (i=0; i<n0; i++) {
|
289
|
+
wsum = 0.0;
|
290
|
+
nm = 0;
|
291
|
+
for (m=0; m<wlen; m++) {
|
292
|
+
if ( zi[ID3(i,j+m,k)] != zmiss ) {
|
293
|
+
zo[ID3T(i,j,k)] += w[m]*zi[ID3(i,j+m,k)];
|
294
|
+
wsum += w[m];
|
295
|
+
nm++;
|
296
|
+
}
|
297
|
+
}
|
298
|
+
if (nm >= nminvalid) {
|
299
|
+
zo[ID3T(i,j,k)] /= wsum;
|
300
|
+
} else {
|
301
|
+
zo[ID3T(i,j,k)] = zmiss;
|
302
|
+
}
|
303
|
+
}
|
304
|
+
}
|
305
|
+
}
|
306
|
+
break;
|
307
|
+
default:
|
308
|
+
rb_raise(rb_eArgError,"Undefined boundary condision (%d)", ibc);
|
309
|
+
break;
|
310
|
+
}
|
311
|
+
}
|
312
|
+
|
313
|
+
// 注:convolution も引数は同じなのでドライバーは兼ねられる
|
314
|
+
// (入り口はわけないとならない)が今のところやってない.
|
315
|
+
//
|
316
|
+
static VALUE
|
317
|
+
running_mean(int argc, VALUE *argv, VALUE self)
|
318
|
+
{
|
319
|
+
VALUE vi; // mandatory 1st arg; input NArray
|
320
|
+
VALUE dim; // mandatory 2nd arg; Integer
|
321
|
+
VALUE wgt; // mandatory 3rd arg; weight 1D NArray
|
322
|
+
VALUE bc; // mandatory 4th arg; boundary condition (Integer class const)
|
323
|
+
VALUE missv=Qnil; // optional 5th arg; if present(Float) vi may have missing
|
324
|
+
int nminvalid=1; // optional 6th arg; miminum count of non-missing vales
|
325
|
+
int with_miss;
|
326
|
+
struct NARRAY *na;
|
327
|
+
na_shape_t *shi, wlen;
|
328
|
+
na_shape_t n0, n1, n2;
|
329
|
+
double *zi, *w, zmiss;
|
330
|
+
int d, i, rank, ibc;
|
331
|
+
VALUE vo;
|
332
|
+
na_shape_t *sho, n1o;
|
333
|
+
double *zo;
|
334
|
+
|
335
|
+
// < process arguments >
|
336
|
+
|
337
|
+
if ( argc<4 || argc>6 ) { rb_raise(rb_eArgError,"Need 4 to 6 arguments"); }
|
338
|
+
vi = argv[0];
|
339
|
+
dim = argv[1];
|
340
|
+
wgt = argv[2];
|
341
|
+
bc = argv[3];
|
342
|
+
with_miss = (argc > 4) && (!NIL_P(argv[4]));
|
343
|
+
if ( with_miss ) { missv = argv[4]; }
|
344
|
+
if ( argc == 6) {
|
345
|
+
nminvalid = NUM2INT( argv[5] );
|
346
|
+
}
|
347
|
+
|
348
|
+
// 1st arg
|
349
|
+
if (!IsNArray(vi)) { rb_raise(rb_eArgError,"1st arg must be a NArray"); }
|
350
|
+
vi = na_cast_object(vi, NA_DFLOAT);
|
351
|
+
rank = NA_RANK(vi);
|
352
|
+
zi = NA_PTR_TYPE(vi, double *);
|
353
|
+
GetNArray(vi, na);
|
354
|
+
shi = na->shape;
|
355
|
+
|
356
|
+
// 2nd arg
|
357
|
+
d = NUM2INT( dim );
|
358
|
+
|
359
|
+
// 3rd arg
|
360
|
+
if (!IsNArray(wgt)) {rb_raise(rb_eArgError,"3rd arg must be a 1D NArray");}
|
361
|
+
if (NA_RANK(wgt)!=1) {rb_raise(rb_eArgError,"3rd arg must be a 1D NArray");}
|
362
|
+
wgt = na_cast_object(wgt, NA_DFLOAT);
|
363
|
+
wlen = NA_TOTAL(wgt);
|
364
|
+
w = NA_PTR_TYPE(wgt, double *);
|
365
|
+
|
366
|
+
// 4th arg
|
367
|
+
ibc = NUM2INT( bc );
|
368
|
+
|
369
|
+
// 5th arg
|
370
|
+
if ( with_miss ) { zmiss = NUM2DBL(missv); }
|
371
|
+
|
372
|
+
// 6th arg
|
373
|
+
if (nminvalid > wlen) {rb_raise(rb_eArgError,"nminvalid > filtering length");}
|
374
|
+
|
375
|
+
// < shape as 3D >
|
376
|
+
|
377
|
+
n1 = shi[d]; // length of the dim to filter
|
378
|
+
if (wlen >= n1) {rb_raise(rb_eArgError,"filter len >= len of the dim");}
|
379
|
+
|
380
|
+
n0 = n2 = 1;
|
381
|
+
for (i=0; i<d; i++) {
|
382
|
+
n0 *= shi[i]; // total lengths of dims before d
|
383
|
+
}
|
384
|
+
for (i=d+1; i<rank; i++) {
|
385
|
+
n2 *= shi[i]; // total lengths of dims after d
|
386
|
+
}
|
387
|
+
|
388
|
+
// < initialize the NArray to ruturn >
|
389
|
+
|
390
|
+
n1o = convol_result_length(n1, wlen, ibc);
|
391
|
+
|
392
|
+
sho = ALLOCA_N(int, rank);
|
393
|
+
for(i=0; i<rank; i++){
|
394
|
+
sho[i] = ( i!=d ? shi[i] : n1o );
|
395
|
+
}
|
396
|
+
|
397
|
+
vo = na_make_object(NA_DFLOAT, rank, sho, cNArray);
|
398
|
+
GetNArray(vo, na);
|
399
|
+
na_clear_data(na);
|
400
|
+
zo = NA_PTR_TYPE(vo, double *);
|
401
|
+
|
402
|
+
// < do the job >
|
403
|
+
if ( with_miss ) {
|
404
|
+
running_mean_miss(zi,n0,n1,n2, w,wlen, ibc, zmiss, nminvalid, zo);
|
405
|
+
} else {
|
406
|
+
running_mean_nomiss(zi,n0,n1,n2, w,wlen, ibc, zo);
|
407
|
+
}
|
408
|
+
|
409
|
+
return vo;
|
410
|
+
}
|
411
|
+
|
412
|
+
static void
|
413
|
+
bin_mean_nomiss(zi,n0,n1,n2, len, zo)
|
414
|
+
// IN
|
415
|
+
double *zi;
|
416
|
+
na_shape_t n0;
|
417
|
+
na_shape_t n1;
|
418
|
+
na_shape_t n2;
|
419
|
+
na_shape_t len;
|
420
|
+
// OUT
|
421
|
+
double *zo; // must have been set to 0 everywhere
|
422
|
+
{
|
423
|
+
na_shape_t n1o;
|
424
|
+
na_shape_t i,j,k,m;
|
425
|
+
double fact;
|
426
|
+
|
427
|
+
n1o = n1 / len;
|
428
|
+
fact = 1.0 / len;
|
429
|
+
|
430
|
+
for (k=0; k<n2; k++) {
|
431
|
+
for (j=0; j<n1o; j++) {
|
432
|
+
for (m=0; m<len; m++) {
|
433
|
+
for (i=0; i<n0; i++) {
|
434
|
+
zo[ID3o(i,j,k)] += fact*zi[ID3(i,j*len+m,k)];
|
435
|
+
}
|
436
|
+
}
|
437
|
+
}
|
438
|
+
}
|
439
|
+
}
|
440
|
+
|
441
|
+
static void
|
442
|
+
bin_sum_nomiss(zi,n0,n1,n2, len, zo)
|
443
|
+
// IN
|
444
|
+
double *zi;
|
445
|
+
na_shape_t n0;
|
446
|
+
na_shape_t n1;
|
447
|
+
na_shape_t n2;
|
448
|
+
na_shape_t len;
|
449
|
+
// OUT
|
450
|
+
double *zo; // must have been set to 0 everywhere
|
451
|
+
{
|
452
|
+
na_shape_t n1o;
|
453
|
+
na_shape_t i,j,k,m;
|
454
|
+
|
455
|
+
n1o = n1 / len;
|
456
|
+
|
457
|
+
for (k=0; k<n2; k++) {
|
458
|
+
for (j=0; j<n1o; j++) {
|
459
|
+
for (m=0; m<len; m++) {
|
460
|
+
for (i=0; i<n0; i++) {
|
461
|
+
zo[ID3o(i,j,k)] += zi[ID3(i,j*len+m,k)];
|
462
|
+
}
|
463
|
+
}
|
464
|
+
}
|
465
|
+
}
|
466
|
+
}
|
467
|
+
|
468
|
+
static void
|
469
|
+
bin_mean_miss(zi,n0,n1,n2, len, zmiss,nminvalid, zo)
|
470
|
+
// IN
|
471
|
+
double *zi;
|
472
|
+
na_shape_t n0;
|
473
|
+
na_shape_t n1;
|
474
|
+
na_shape_t n2;
|
475
|
+
na_shape_t len;
|
476
|
+
double zmiss;
|
477
|
+
int nminvalid;
|
478
|
+
// OUT
|
479
|
+
double *zo; // must have been set to 0 everywhere
|
480
|
+
{
|
481
|
+
na_shape_t n1o;
|
482
|
+
na_shape_t i,j,k,m;
|
483
|
+
na_shape_t cnt;
|
484
|
+
|
485
|
+
n1o = n1 / len;
|
486
|
+
|
487
|
+
for (k=0; k<n2; k++) {
|
488
|
+
for (j=0; j<n1o; j++) {
|
489
|
+
for (i=0; i<n0; i++) {
|
490
|
+
cnt = 0;
|
491
|
+
for (m=0; m<len; m++) {
|
492
|
+
if ( zi[ID3(i,j*len+m,k)] != zmiss ) {
|
493
|
+
zo[ID3o(i,j,k)] += zi[ID3(i,j*len+m,k)];
|
494
|
+
cnt++;
|
495
|
+
}
|
496
|
+
}
|
497
|
+
if (cnt >= nminvalid) {
|
498
|
+
zo[ID3o(i,j,k)] /= cnt;
|
499
|
+
} else {
|
500
|
+
zo[ID3o(i,j,k)] = zmiss;
|
501
|
+
}
|
502
|
+
}
|
503
|
+
}
|
504
|
+
}
|
505
|
+
}
|
506
|
+
|
507
|
+
static void
|
508
|
+
bin_sum_miss(zi,n0,n1,n2, len, zmiss,nminvalid, zo)
|
509
|
+
// IN
|
510
|
+
double *zi;
|
511
|
+
na_shape_t n0;
|
512
|
+
na_shape_t n1;
|
513
|
+
na_shape_t n2;
|
514
|
+
na_shape_t len;
|
515
|
+
double zmiss;
|
516
|
+
int nminvalid;
|
517
|
+
// OUT
|
518
|
+
double *zo; // must have been set to 0 everywhere
|
519
|
+
{
|
520
|
+
na_shape_t n1o;
|
521
|
+
na_shape_t i,j,k,m;
|
522
|
+
na_shape_t cnt;
|
523
|
+
|
524
|
+
n1o = n1 / len;
|
525
|
+
|
526
|
+
for (k=0; k<n2; k++) {
|
527
|
+
for (j=0; j<n1o; j++) {
|
528
|
+
for (i=0; i<n0; i++) {
|
529
|
+
cnt = 0;
|
530
|
+
for (m=0; m<len; m++) {
|
531
|
+
if ( zi[ID3(i,j*len+m,k)] != zmiss ) {
|
532
|
+
zo[ID3o(i,j,k)] += zi[ID3(i,j*len+m,k)];
|
533
|
+
cnt++;
|
534
|
+
}
|
535
|
+
}
|
536
|
+
if ( !(cnt >= nminvalid) ) {
|
537
|
+
zo[ID3o(i,j,k)] = zmiss;
|
538
|
+
}
|
539
|
+
}
|
540
|
+
}
|
541
|
+
}
|
542
|
+
}
|
543
|
+
|
544
|
+
// bin_mean or bin_sum depeiding on the last arg
|
545
|
+
static VALUE
|
546
|
+
bin_mean_sum(int argc, VALUE *argv, VALUE self, int mean)
|
547
|
+
{
|
548
|
+
VALUE vi; // 1st arg; input NArray
|
549
|
+
VALUE dim; // 2nd arg
|
550
|
+
na_shape_t len; // 3rd arg
|
551
|
+
VALUE missv=Qnil; // optional 4th arg; if present(Float) vi may have missing
|
552
|
+
int nminvalid=1; // optional 5th arg
|
553
|
+
|
554
|
+
int with_miss;
|
555
|
+
struct NARRAY *na;
|
556
|
+
double *zi, zmiss;
|
557
|
+
na_shape_t *shi;
|
558
|
+
na_shape_t n0, n1, n2;
|
559
|
+
int d, i, rank;
|
560
|
+
VALUE vo;
|
561
|
+
na_shape_t *sho, n1o;
|
562
|
+
double *zo;
|
563
|
+
|
564
|
+
// < process arguments >
|
565
|
+
|
566
|
+
if ( argc<3 || argc>5 ) { rb_raise(rb_eArgError,"Need 2 or 3 arguments"); }
|
567
|
+
vi = argv[0];
|
568
|
+
|
569
|
+
dim = argv[1];
|
570
|
+
d = NUM2INT( dim );
|
571
|
+
|
572
|
+
len = NUM2INT( argv[2] );
|
573
|
+
if (len<1) {rb_raise(rb_eArgError,"len must be >= 1");}
|
574
|
+
|
575
|
+
with_miss = (argc > 3) && (!NIL_P(argv[3]));
|
576
|
+
if ( with_miss ) {
|
577
|
+
missv = argv[3];
|
578
|
+
zmiss = NUM2DBL(missv);
|
579
|
+
}
|
580
|
+
|
581
|
+
if (argc==5) {
|
582
|
+
nminvalid = NUM2INT( argv[4] );
|
583
|
+
if (nminvalid > len) {rb_raise(rb_eArgError,"nminvalid > bin length");}
|
584
|
+
}
|
585
|
+
|
586
|
+
|
587
|
+
// < NArray elements >
|
588
|
+
|
589
|
+
vi = na_cast_object(vi, NA_DFLOAT);
|
590
|
+
rank = NA_RANK(vi);
|
591
|
+
zi = NA_PTR_TYPE(vi, double *);
|
592
|
+
GetNArray(vi, na);
|
593
|
+
shi = na->shape;
|
594
|
+
|
595
|
+
// < shape as 3D >
|
596
|
+
|
597
|
+
n1 = shi[d]; // length of the dim
|
598
|
+
if (len >= n1) {rb_raise(rb_eArgError,"filter len >= len of the dim");}
|
599
|
+
|
600
|
+
n0 = n2 = 1;
|
601
|
+
for (i=0; i<d; i++) {
|
602
|
+
n0 *= shi[i]; // total lengths of dims before d
|
603
|
+
}
|
604
|
+
for (i=d+1; i<rank; i++) {
|
605
|
+
n2 *= shi[i]; // total lengths of dims after d
|
606
|
+
}
|
607
|
+
|
608
|
+
// < initialize the NArray to ruturn >
|
609
|
+
|
610
|
+
n1o = n1 / len; // <- BC_TRIM (currently this is the only available bc)
|
611
|
+
|
612
|
+
sho = ALLOCA_N(int, rank);
|
613
|
+
for(i=0; i<rank; i++){
|
614
|
+
sho[i] = ( i!=d ? shi[i] : n1o );
|
615
|
+
}
|
616
|
+
|
617
|
+
vo = na_make_object(NA_DFLOAT, rank, sho, cNArray);
|
618
|
+
GetNArray(vo, na);
|
619
|
+
na_clear_data(na);
|
620
|
+
zo = NA_PTR_TYPE(vo, double *);
|
621
|
+
|
622
|
+
// < do the job >
|
623
|
+
if ( mean ) {
|
624
|
+
if ( with_miss ) {
|
625
|
+
bin_mean_miss(zi,n0,n1,n2, len, zmiss,nminvalid, zo);
|
626
|
+
} else {
|
627
|
+
bin_mean_nomiss(zi,n0,n1,n2, len, zo);
|
628
|
+
}
|
629
|
+
} else {
|
630
|
+
if ( with_miss ) {
|
631
|
+
bin_sum_miss(zi,n0,n1,n2, len, zmiss,nminvalid, zo);
|
632
|
+
} else {
|
633
|
+
bin_sum_nomiss(zi,n0,n1,n2, len, zo);
|
634
|
+
}
|
635
|
+
}
|
636
|
+
|
637
|
+
return vo;
|
638
|
+
}
|
639
|
+
|
640
|
+
static VALUE
|
641
|
+
bin_mean(int argc, VALUE *argv, VALUE self)
|
642
|
+
{
|
643
|
+
bin_mean_sum(argc, argv, self, 1);
|
644
|
+
}
|
645
|
+
|
646
|
+
static VALUE
|
647
|
+
bin_sum(int argc, VALUE *argv, VALUE self)
|
648
|
+
{
|
649
|
+
bin_mean_sum(argc, argv, self, 0);
|
650
|
+
}
|
651
|
+
|
652
|
+
|
653
|
+
/*
|
654
|
+
cum_sum_dfloat_bang : cumulative summation along a dimension zdim (FLOAT)
|
655
|
+
(bang method: overwrite the input by the result)
|
656
|
+
*/
|
657
|
+
static VALUE
|
658
|
+
cum_sum_dfloat_bang(obj, f, zdim)
|
659
|
+
VALUE obj;
|
660
|
+
VALUE f;
|
661
|
+
VALUE zdim;
|
662
|
+
{
|
663
|
+
int rank, zd, d;
|
664
|
+
struct NARRAY *na;
|
665
|
+
na_shape_t *shape;
|
666
|
+
double *v;
|
667
|
+
na_shape_t n0, nz, n2;
|
668
|
+
na_shape_t j, k, l;
|
669
|
+
|
670
|
+
if ( NA_TYPE(f) != NA_DFLOAT ){
|
671
|
+
rb_raise(rb_eArgError, "expects a DFLOAT NArray");
|
672
|
+
}
|
673
|
+
|
674
|
+
rank = NA_RANK(f);
|
675
|
+
GetNArray(f, na);
|
676
|
+
shape = na->shape;
|
677
|
+
v = (double *)NA_PTR(na, 0);
|
678
|
+
|
679
|
+
zd = NUM2INT(zdim);
|
680
|
+
if (zd < 0) zd += rank; // negative: count from the last dim
|
681
|
+
|
682
|
+
if (zd < 0 || zd >= rank){
|
683
|
+
rb_raise(rb_eArgError,
|
684
|
+
"Invalid dimension (%d) for a rank %d NArray", NUM2INT(zdim), rank);
|
685
|
+
}
|
686
|
+
|
687
|
+
for (d=0, n0=1 ; d<zd ; d++){
|
688
|
+
n0 *= shape[d];
|
689
|
+
}
|
690
|
+
nz = shape[zd];
|
691
|
+
for (d=zd+1, n2=1 ; d<rank ; d++){
|
692
|
+
n2 *= shape[d];
|
693
|
+
}
|
694
|
+
|
695
|
+
for (l=0; l<n2; l++){
|
696
|
+
for (k=1; k<nz; k++){
|
697
|
+
for (j=0; j<n0; j++){
|
698
|
+
v[ID3z(j,k,l)] += v[ID3z(j,k-1,l)];
|
699
|
+
}
|
700
|
+
}
|
701
|
+
}
|
702
|
+
|
703
|
+
return Qnil;
|
704
|
+
}
|
705
|
+
|
706
|
+
/*
|
707
|
+
cum_sum : cumulative summation along a dimension zdim (FLOAT)
|
708
|
+
|
709
|
+
This method may be good to extend NArray.
|
710
|
+
At this moment (2014-11-30), though, it is made available to Ruby
|
711
|
+
only as a private method of VArray.
|
712
|
+
*/
|
713
|
+
static VALUE
|
714
|
+
cum_sum(obj, f, zdim)
|
715
|
+
VALUE obj;
|
716
|
+
VALUE f;
|
717
|
+
VALUE zdim;
|
718
|
+
{
|
719
|
+
VALUE sum;
|
720
|
+
|
721
|
+
sum = na_clone(f);
|
722
|
+
switch( NA_TYPE(f) ) {
|
723
|
+
case NA_DFLOAT:
|
724
|
+
cum_sum_dfloat_bang(obj, sum, zdim);
|
725
|
+
break;
|
726
|
+
default:
|
727
|
+
rb_raise(rb_eArgError, "Sorry, this type of NArray is yet to be supported");
|
728
|
+
break;
|
729
|
+
}
|
730
|
+
return sum;
|
731
|
+
}
|
732
|
+
|
733
|
+
|
734
|
+
/*
|
735
|
+
cell_integ_irreg: trapezoidal numerical integration over coordinate cells, supporting irregular grid
|
736
|
+
|
737
|
+
== Description
|
738
|
+
|
739
|
+
Suppose a multi-dimensional NArray f[:,k,:], where colon represents
|
740
|
+
any number of dimensions, and k is the "z" dimension along which
|
741
|
+
integration is made. We write its real space representation as
|
742
|
+
f(z; x), where x symbolically represents all of the independent
|
743
|
+
variables other than z, and for simplicity, we further write it as
|
744
|
+
f(z).
|
745
|
+
|
746
|
+
z is sampled at z_k, k=0,1,...,nzbound-1. This method allows z_k to be
|
747
|
+
defined for each z column, so it requires a multi-D NArray argument
|
748
|
+
z[:,k,:] (having the same shape as f). Optionally, nzbound can also
|
749
|
+
vary as nzbound[:,:]. If, instead, nil is given to nzbound, the entire
|
750
|
+
z grid is used; nzbound is set to f.shape(zdim).
|
751
|
+
|
752
|
+
We define the integration of f as
|
753
|
+
|
754
|
+
{ \int_za^zb f(z) dz, when za<=zb,
|
755
|
+
I(za,zb) = {
|
756
|
+
{ -\int_za^zb f(z) dz, otherwise.
|
757
|
+
|
758
|
+
In other words, our integration is always made from the smaller end
|
759
|
+
to the greater end.
|
760
|
+
|
761
|
+
In the normal use case (when w is given nil), we define the cell
|
762
|
+
integration as,
|
763
|
+
|
764
|
+
I(-\infty, zc_0), I(zc_0, zc_1), I(zc_1, zc_2),...,
|
765
|
+
|
766
|
+
The cell boundaries zc_m (m=0,1,..) are specified by the 1D NArray
|
767
|
+
argument "ccell"; ccell must be aligned in the increasing order.
|
768
|
+
|
769
|
+
This method allows coordinate transformation by specifying another
|
770
|
+
coordinate variable w[:,k,:] (having the same shape as f). In this
|
771
|
+
case, the ccell argument specifies a coordinate with respect to w:
|
772
|
+
wc_m (m=0,1,...; wc_m must be in the increasing order).
|
773
|
+
The integration is still taken with respect to z, so the cell
|
774
|
+
integration is expressed as
|
775
|
+
|
776
|
+
I(-\infty, z(wc_0)), I(z(wc_0), z(wc_1)), I(z(wc_1), z(wc_2)),...,
|
777
|
+
|
778
|
+
The grid values z[:,k,:] and w[:,k,:] do not have to be monotonic;
|
779
|
+
the numerical integration properly treats the contribution from
|
780
|
+
multiple ranges along k. Mathematically, the coordinate-transferred
|
781
|
+
integration over the w bin (-\infty, wc] is expressed as
|
782
|
+
|
783
|
+
\int_-\infty^+\infty H(wc-w(z)) f(z) dz,
|
784
|
+
|
785
|
+
where H is the Heaviside function. The normal use case (without w)
|
786
|
+
is simply when w is z itself, which is exploited in implementation.
|
787
|
+
|
788
|
+
*/
|
789
|
+
static VALUE
|
790
|
+
cell_integ_irreg(obj, f, z, zdim, nzbound, ccell, w)
|
791
|
+
VALUE obj;
|
792
|
+
VALUE f; // [NArray] multi-D data to be integrated
|
793
|
+
VALUE z; // [NArray] multi-D coordinate values of f's grid; integration
|
794
|
+
// is always made along z (whether or not w is given)
|
795
|
+
VALUE zdim; // [Integer] dimension of f along which to integrate
|
796
|
+
VALUE nzbound; // [nil, or NArray(integer) with rank 1 smaller than f's]
|
797
|
+
// Length of the actual z dim for each column (data must
|
798
|
+
// be packed from the beginning of z dim; 0...nzbound[j,l]).
|
799
|
+
// If nil, the entire column is assumed valid;
|
800
|
+
VALUE ccell; // [NArray] 1D grid to sample the result. It is the z
|
801
|
+
// coordinate if w is nil; if w is given, it's a w grid.
|
802
|
+
VALUE w; // [nil or NArray] alternative grid point values to express
|
803
|
+
// the result as a function of w rather than z (special case)
|
804
|
+
// (e.g. z: pressure/g; w: potential temperature)
|
805
|
+
{
|
806
|
+
struct NARRAY *na;
|
807
|
+
int rank, zd, d;
|
808
|
+
na_shape_t *shape;
|
809
|
+
na_shape_t n0, nz, n2, nzw;
|
810
|
+
na_shape_t *oshape, nc;
|
811
|
+
VALUE F; // the result: \int f dz
|
812
|
+
double *fv, *zv, *wc, *wv, *Fv;
|
813
|
+
int32_t *nzbd;
|
814
|
+
na_shape_t j, k, l, m; // k: index of z (orig); m: index of ccell
|
815
|
+
double fa, fb, dz, wa, wb, wac, wbc, a, b, fi;
|
816
|
+
|
817
|
+
// cast to ensure pointer types
|
818
|
+
|
819
|
+
if(!IsNArray(f)) rb_raise(rb_eArgError, "f is not a NArray");
|
820
|
+
if(!IsNArray(z)) rb_raise(rb_eArgError, "z is not a NArray");
|
821
|
+
if(!IsNArray(ccell)) rb_raise(rb_eArgError, "ccell is not a NArray");
|
822
|
+
if(w!=Qnil && !IsNArray(w)) rb_raise(rb_eArgError, "w is must be nil or a NArray");
|
823
|
+
|
824
|
+
f = na_cast_object(f, NA_DFLOAT);
|
825
|
+
z = na_cast_object(z, NA_DFLOAT);
|
826
|
+
if(nzbound != Qnil){ nzbound = na_cast_object(nzbound, NA_LINT); }
|
827
|
+
ccell = na_cast_object(ccell, NA_DFLOAT);
|
828
|
+
if(w != Qnil){ w = na_cast_object(w, NA_DFLOAT); }
|
829
|
+
|
830
|
+
// read & check the shapes
|
831
|
+
|
832
|
+
rank = NA_RANK(f);
|
833
|
+
if ( NA_RANK(z) != rank ){
|
834
|
+
rb_raise(rb_eArgError, "f and z must have the same shape");
|
835
|
+
}
|
836
|
+
if ( nzbound != Qnil && NA_RANK(nzbound) != rank-1 ){
|
837
|
+
rb_raise(rb_eArgError, "rank of nzbound must be 1 smaller than f's");
|
838
|
+
}
|
839
|
+
|
840
|
+
zd = NUM2INT(zdim);
|
841
|
+
if (zd < 0) zd += rank; // negative: count from the last dim
|
842
|
+
|
843
|
+
if (zd < 0 || zd >= rank){
|
844
|
+
rb_raise(rb_eArgError,
|
845
|
+
"Invalid dimension (%d) since f.rank==%d", NUM2INT(zdim), rank);
|
846
|
+
}
|
847
|
+
|
848
|
+
GetNArray(f, na);
|
849
|
+
shape = na->shape;
|
850
|
+
for (d=0, n0=1 ; d<zd ; d++){
|
851
|
+
n0 *= shape[d];
|
852
|
+
}
|
853
|
+
nz = shape[zd];
|
854
|
+
for (d=zd+1, n2=1 ; d<rank ; d++){
|
855
|
+
n2 *= shape[d];
|
856
|
+
}
|
857
|
+
|
858
|
+
if (NA_TOTAL(z) != n0*nz*n2){
|
859
|
+
rb_raise(rb_eArgError, "lengths of f and z do not agree");
|
860
|
+
}
|
861
|
+
if (nzbound != Qnil && NA_TOTAL(nzbound) != n0*n2){
|
862
|
+
rb_raise(rb_eArgError, "shapes of f and nzbound are incompatible");
|
863
|
+
}
|
864
|
+
|
865
|
+
// prepare the output array; assign pointers
|
866
|
+
|
867
|
+
if ( NA_RANK(ccell) != 1 ){rb_raise(rb_eArgError, "ccell is not 1D");}
|
868
|
+
nc = NA_TOTAL(ccell);
|
869
|
+
oshape = ALLOCA_N(na_shape_t, rank);
|
870
|
+
for (d=0; d<rank ; d++){
|
871
|
+
if (d != zd){
|
872
|
+
oshape[d] = shape[d];
|
873
|
+
} else {
|
874
|
+
oshape[d] = nc;
|
875
|
+
}
|
876
|
+
}
|
877
|
+
F = na_make_object(NA_DFLOAT, rank, oshape, cNArray);
|
878
|
+
GetNArray(F, na);
|
879
|
+
na_clear_data(na);
|
880
|
+
Fv = (double *)NA_PTR(na, 0);
|
881
|
+
|
882
|
+
GetNArray(f, na);
|
883
|
+
fv = (double *)NA_PTR(na, 0);
|
884
|
+
|
885
|
+
GetNArray(z, na);
|
886
|
+
zv = (double *)NA_PTR(na, 0);
|
887
|
+
|
888
|
+
if(nzbound != Qnil){
|
889
|
+
GetNArray(nzbound, na);
|
890
|
+
nzbd = (int32_t *)NA_PTR(na, 0);
|
891
|
+
}
|
892
|
+
|
893
|
+
GetNArray(ccell, na);
|
894
|
+
wc = (double *)NA_PTR(na, 0);
|
895
|
+
if (wc[0] > wc[nc-1]){
|
896
|
+
rb_raise(rb_eArgError, "ccell must be alined in the increasing order");
|
897
|
+
}
|
898
|
+
|
899
|
+
if(w != Qnil){
|
900
|
+
GetNArray(w, na);
|
901
|
+
wv = (double *)NA_PTR(na, 0);
|
902
|
+
} else {
|
903
|
+
wv = zv;
|
904
|
+
}
|
905
|
+
|
906
|
+
// main loop
|
907
|
+
for (l=0; l<n2; l++){
|
908
|
+
for (j=0; j<n0; j++){
|
909
|
+
if (nzbound == Qnil) {
|
910
|
+
nzw = nz;
|
911
|
+
} else {
|
912
|
+
nzw = nzbd[j+n0*l];
|
913
|
+
if(nzw>nz) nzw=nz;
|
914
|
+
}
|
915
|
+
m=0; // m: index of the new cooridnate
|
916
|
+
for (k=0; k<nzw-1; k++){
|
917
|
+
// set the trapezoid
|
918
|
+
if (wv[ID3z(j,k,l)] < wv[ID3z(j,k+1,l)]) {
|
919
|
+
wa = wv[ID3z(j,k,l)]; // "left" (lower) end along w
|
920
|
+
wb = wv[ID3z(j,k+1,l)]; // "right" (upper) end along w
|
921
|
+
fa = fv[ID3z(j,k,l)]; // at the left end
|
922
|
+
fb = fv[ID3z(j,k+1,l)]; // at the right end
|
923
|
+
} else {
|
924
|
+
wa = wv[ID3z(j,k+1,l)]; // "left" (lower) end along w
|
925
|
+
wb = wv[ID3z(j,k,l)]; // "right" (upper) end along w
|
926
|
+
fa = fv[ID3z(j,k+1,l)]; // at the left end
|
927
|
+
fb = fv[ID3z(j,k,l)]; // at the right end
|
928
|
+
}
|
929
|
+
dz = fabs(zv[ID3z(j,k+1,l)]-zv[ID3z(j,k,l)]);
|
930
|
+
|
931
|
+
// find the right next grid point to wa (left end)
|
932
|
+
if (wa < wc[m]){
|
933
|
+
while( m>0 && wa < wc[m-1] ){ m--; }
|
934
|
+
} else {
|
935
|
+
while( wa >= wc[m] && m<nc ){ m++; }
|
936
|
+
// m can be nc, meaning the entire trapezoid is outside
|
937
|
+
}
|
938
|
+
|
939
|
+
// integration
|
940
|
+
if (m<nc){
|
941
|
+
wac = wa; // left end of the current bin
|
942
|
+
while(1){
|
943
|
+
//wbc = (wb<=wc[m]) ? wb : wc[m]; // current right end
|
944
|
+
wbc = fmin(wb, wc[m]);
|
945
|
+
|
946
|
+
// do the integration
|
947
|
+
if (wb != wa){
|
948
|
+
a = (wac-wa)/(wb-wa); // normalized (0-1) left end
|
949
|
+
b = (wbc-wa)/(wb-wa); // normalized (0-1) right end
|
950
|
+
fi = (fa + (a+b)/2*(fb-fa)) * (b-a)*dz;
|
951
|
+
} else {
|
952
|
+
fi = 0.0;
|
953
|
+
}
|
954
|
+
// ^ f value at (a+b)/2 ^ width
|
955
|
+
Fv[ID3c(j,m,l)] += fi;
|
956
|
+
if ( wb <= wc[m] || m == nc-1 ) break;
|
957
|
+
wac = wc[m];
|
958
|
+
m++;
|
959
|
+
}
|
960
|
+
} else {
|
961
|
+
// no need integrate
|
962
|
+
m = nc - 1; // put m inside the range before next k
|
963
|
+
}
|
964
|
+
}
|
965
|
+
}
|
966
|
+
}
|
967
|
+
|
968
|
+
// finish
|
969
|
+
return F;
|
970
|
+
}
|
971
|
+
|
972
|
+
/*
|
973
|
+
cum_integ_irreg : similar to cell_integ_irreg but it sums up along the
|
974
|
+
axis. -- This method acutually uses cell_integ_irreg and make sumation.
|
975
|
+
*/
|
976
|
+
static VALUE
|
977
|
+
cum_integ_irreg(obj, f, z, zdim, nzbound, ccell, w)
|
978
|
+
VALUE obj;
|
979
|
+
VALUE f;
|
980
|
+
VALUE z;
|
981
|
+
VALUE zdim;
|
982
|
+
VALUE nzbound;
|
983
|
+
VALUE ccell;
|
984
|
+
VALUE w;
|
985
|
+
{
|
986
|
+
VALUE F;
|
987
|
+
|
988
|
+
F = cell_integ_irreg(obj, f, z, zdim, nzbound, ccell, w);
|
989
|
+
cum_sum_dfloat_bang(obj, F, zdim);
|
990
|
+
return F;
|
991
|
+
}
|
992
|
+
|
993
|
+
/*
|
994
|
+
cap_by_boundary : Cap (insert) a NArray with boundary values
|
995
|
+
|
996
|
+
Restriction; data alignment is restricted so that the beginning of
|
997
|
+
the out data is always valid (within the domain). To ensure it, it
|
998
|
+
should be either zcrd is increasing and upper==true or zcrd is
|
999
|
+
decreasing and upper==false.
|
1000
|
+
|
1001
|
+
RETURN VALUES
|
1002
|
+
|
1003
|
+
* fe: f capped by the boundary values. The dimension zdim is
|
1004
|
+
extended by 1; i.e., f[:,nz,:] --> fe[:,nz+1,:], where ":" respresent
|
1005
|
+
arbitrary number of dimensions. The elements of fe are equal to
|
1006
|
+
those of f where inside the domain (simple copies), and they are equal
|
1007
|
+
to the elements of fs at the bondary (simple copies if fs is given;
|
1008
|
+
if not, guessed by interpolation or naive extension).
|
1009
|
+
* ze: grid points of fe along zdim. It is a mixture of zcrd and zs;
|
1010
|
+
it is zcrd inside the domain (where f is copied), and it is zs
|
1011
|
+
at the boundary (where fs is copied).
|
1012
|
+
Same shape as fe.
|
1013
|
+
* nze: The number of valid data along zdim of fe. Shaped as ze[:,:],
|
1014
|
+
according to the notation above. For example, when fe is 4D and
|
1015
|
+
zdim==2, fe[i,j,k,l] is valid for k = 0,1,...,nze[i,j,l]-1,
|
1016
|
+
where the boundary is at nze[i,j,l]-1. Thus, nze is always
|
1017
|
+
smaller than or equal to the length of zdim of fe (which is nz+1)
|
1018
|
+
|
1019
|
+
*/
|
1020
|
+
static VALUE
|
1021
|
+
cap_by_boundary(obj, f, zdim, zcrd, upper, zb, fb)
|
1022
|
+
VALUE obj;
|
1023
|
+
VALUE f; // [NArray] multi-D data
|
1024
|
+
VALUE zdim; // [Integer] dimension of zcrd in f
|
1025
|
+
VALUE zcrd; // [NArray] 1D coordinate values of the zdim dimension of f
|
1026
|
+
VALUE upper; // true/false to cap the upper/lower side (with z)
|
1027
|
+
VALUE zb; // [NArray] the "surface" z; zb.rank must be f.rank-1
|
1028
|
+
VALUE fb; // [nil or NArray] the f value at surface (zb.shape==fb.shape)
|
1029
|
+
{
|
1030
|
+
VALUE fe; // [NArray] return value, extended f by fb
|
1031
|
+
VALUE ze; // [NArray] return value, grid points of fe along zdim
|
1032
|
+
VALUE nze; // [NArray] return value, valid data lengths along zdim in fe
|
1033
|
+
VALUE result; // [Array] [fe, ze, nze] (return the two in an Array)
|
1034
|
+
struct NARRAY *na;
|
1035
|
+
int rank, zd, d;
|
1036
|
+
na_shape_t n0, nz, n2, nc;
|
1037
|
+
double *fv, *zcv, *zbv, *fbv, *fev, *zev;
|
1038
|
+
int32_t *nzev;
|
1039
|
+
int zcincr, capupper, sgn;
|
1040
|
+
na_shape_t j, k, l;
|
1041
|
+
na_shape_t *shape, *oshape, *oshape2;
|
1042
|
+
|
1043
|
+
// cast to ensure pointer types
|
1044
|
+
|
1045
|
+
if(!IsNArray(f)) rb_raise(rb_eArgError, "f is not a NArray");
|
1046
|
+
if(!IsNArray(zcrd)) rb_raise(rb_eArgError, "zcrd is not a NArray");
|
1047
|
+
if(!IsNArray(zb)) rb_raise(rb_eArgError, "zb is not a NArray");
|
1048
|
+
if(fb!=Qnil && !IsNArray(fb)) rb_raise(rb_eArgError, "fb must be nil or a NArray");
|
1049
|
+
|
1050
|
+
f = na_cast_object(f, NA_DFLOAT);
|
1051
|
+
zcrd = na_cast_object(zcrd, NA_DFLOAT);
|
1052
|
+
zb = na_cast_object(zb, NA_DFLOAT);
|
1053
|
+
if(fb != Qnil){ fb = na_cast_object(fb, NA_DFLOAT); }
|
1054
|
+
|
1055
|
+
// read & check
|
1056
|
+
|
1057
|
+
rank = NA_RANK(f);
|
1058
|
+
if (NA_RANK(zb)!=rank-1){rb_raise(rb_eArgError, "zb.rank must f.rank-1");}
|
1059
|
+
|
1060
|
+
zd = NUM2INT(zdim);
|
1061
|
+
if (zd < 0) zd += rank; // negative: count from the last dim
|
1062
|
+
if (zd < 0 || zd >= rank){
|
1063
|
+
rb_raise(rb_eArgError,
|
1064
|
+
"Invalid dimension (%d) since f.rank==%d", NUM2INT(zdim), rank);
|
1065
|
+
}
|
1066
|
+
|
1067
|
+
GetNArray(f, na);
|
1068
|
+
shape = na->shape;
|
1069
|
+
for (d=0, n0=1 ; d<zd ; d++){
|
1070
|
+
n0 *= shape[d];
|
1071
|
+
}
|
1072
|
+
nz = shape[zd];
|
1073
|
+
for (d=zd+1, n2=1 ; d<rank ; d++){
|
1074
|
+
n2 *= shape[d];
|
1075
|
+
}
|
1076
|
+
fv = (double *)NA_PTR(na, 0);
|
1077
|
+
|
1078
|
+
if (NA_TOTAL(zcrd) != nz){
|
1079
|
+
rb_raise(rb_eArgError,"zcrd.length (%d) != nz (%d)", NA_TOTAL(zcrd),nz);
|
1080
|
+
}
|
1081
|
+
zcv = NA_PTR_TYPE(zcrd, double *);
|
1082
|
+
|
1083
|
+
if (NA_TOTAL(zb) != n0*n2){
|
1084
|
+
rb_raise(rb_eArgError,"shapes of f and zb are incompatible");
|
1085
|
+
}
|
1086
|
+
zbv = NA_PTR_TYPE(zb, double *);
|
1087
|
+
|
1088
|
+
if(fb != Qnil){
|
1089
|
+
if (NA_TOTAL(fb) != n0*n2){
|
1090
|
+
rb_raise(rb_eArgError,"shapes of f and fb are incompatible");
|
1091
|
+
}
|
1092
|
+
fbv = NA_PTR_TYPE(fb, double *);
|
1093
|
+
}
|
1094
|
+
|
1095
|
+
// find the direction
|
1096
|
+
|
1097
|
+
zcincr = zcv[0] < zcv[nz-1]; // zcrd is in the increasing order
|
1098
|
+
capupper = upper != Qnil && upper != Qfalse; // whether upper is "true"
|
1099
|
+
sgn = capupper ? 1 : -1;
|
1100
|
+
if ( (zcincr && !capupper) || (!zcincr && capupper) ){
|
1101
|
+
rb_raise(rb_eArgError,"Unexpected data alignment: To ensure that the zdim dimension of the output NArray (fe, ze) starts from the valid data (i.e., its beginning is inside the domain), it should be either that zcrd is increasing and upper==true or that zcrd is decreasing and upper==false");
|
1102
|
+
}
|
1103
|
+
|
1104
|
+
// prepare the output array
|
1105
|
+
|
1106
|
+
nc = nz+1;
|
1107
|
+
oshape = ALLOCA_N(na_shape_t, rank);
|
1108
|
+
for (d=0; d<rank ; d++){
|
1109
|
+
if (d != zd){
|
1110
|
+
oshape[d] = shape[d];
|
1111
|
+
} else {
|
1112
|
+
oshape[d] = nc;
|
1113
|
+
}
|
1114
|
+
}
|
1115
|
+
fe = na_make_object(NA_DFLOAT, rank, oshape, cNArray);
|
1116
|
+
fev = NA_PTR_TYPE(fe, double *);
|
1117
|
+
ze = na_make_object(NA_DFLOAT, rank, oshape, cNArray);
|
1118
|
+
zev = NA_PTR_TYPE(ze, double *);
|
1119
|
+
|
1120
|
+
oshape2 = ALLOCA_N(na_shape_t, rank-1);
|
1121
|
+
for (d=0; d<rank ; d++){
|
1122
|
+
if (d < zd){
|
1123
|
+
oshape2[d] = shape[d];
|
1124
|
+
} else if (d > zd) {
|
1125
|
+
oshape2[d-1] = shape[d];
|
1126
|
+
}
|
1127
|
+
}
|
1128
|
+
|
1129
|
+
nze = na_make_object(NA_LINT, rank-1, oshape2, cNArray);
|
1130
|
+
nzev = NA_PTR_TYPE(nze, int32_t *);
|
1131
|
+
|
1132
|
+
// initialize the output data
|
1133
|
+
|
1134
|
+
for (l=0; l<n2; l++){
|
1135
|
+
for (k=0; k<nz; k++){
|
1136
|
+
for (j=0; j<n0; j++){
|
1137
|
+
fev[ID3c(j,k,l)] = fv[ID3z(j,k,l)]; // copy
|
1138
|
+
zev[ID3c(j,k,l)] = zcv[k]; // copy
|
1139
|
+
}
|
1140
|
+
}
|
1141
|
+
for (j=0; j<n0; j++){
|
1142
|
+
fev[ID3c(j,nc-1,l)] = 0e0; // clear
|
1143
|
+
zev[ID3c(j,nc-1,l)] = 0e0; // clear
|
1144
|
+
}
|
1145
|
+
}
|
1146
|
+
|
1147
|
+
// main loop
|
1148
|
+
if(fb != Qnil){
|
1149
|
+
for (l=0; l<n2; l++){
|
1150
|
+
for (j=0; j<n0; j++){
|
1151
|
+
for (k=0; k<nz; k++){
|
1152
|
+
if ( (zcv[k] - zbv[ID2(j,l)])*sgn > 0 ){
|
1153
|
+
fev[ID3c(j,k,l)] = fbv[ID2(j,l)];
|
1154
|
+
zev[ID3c(j,k,l)] = zbv[ID2(j,l)];
|
1155
|
+
nzev[ID2(j,l)] = k+1;
|
1156
|
+
break;
|
1157
|
+
}
|
1158
|
+
}
|
1159
|
+
if (k==nz) {
|
1160
|
+
// didn't break
|
1161
|
+
fev[ID3c(j,k,l)] = fbv[ID2(j,l)];
|
1162
|
+
zev[ID3c(j,k,l)] = zbv[ID2(j,l)];
|
1163
|
+
nzev[ID2(j,l)] = k+1;
|
1164
|
+
}
|
1165
|
+
}
|
1166
|
+
}
|
1167
|
+
} else {
|
1168
|
+
for (l=0; l<n2; l++){
|
1169
|
+
for (j=0; j<n0; j++){
|
1170
|
+
for (k=0; k<nz; k++){
|
1171
|
+
if ( (zcv[k] - zbv[ID2(j,l)])*sgn > 0 ){
|
1172
|
+
//fev[ID3c(j,k,l)] = fv[ID3z(j,k-1,l)];//naive extension
|
1173
|
+
fev[ID3c(j,k,l)] =
|
1174
|
+
( fv[ID3z(j,k-1,l)]*(zcv[k]-zbv[ID2(j,l)])
|
1175
|
+
+ fv[ID3z(j,k,l)]*(zbv[ID2(j,l)]-zcv[k-1]) ) /
|
1176
|
+
(zcv[k] - zcv[k-1]);
|
1177
|
+
zev[ID3c(j,k,l)] = zbv[ID2(j,l)];
|
1178
|
+
nzev[ID2(j,l)] = k+1;
|
1179
|
+
break;
|
1180
|
+
}
|
1181
|
+
}
|
1182
|
+
if (k==nz) {
|
1183
|
+
// didn't break
|
1184
|
+
fev[ID3c(j,k,l)] = fv[ID3z(j,k-1,l)]; // naive extension
|
1185
|
+
zev[ID3c(j,k,l)] = zbv[ID2(j,l)];
|
1186
|
+
nzev[ID2(j,l)] = k+1;
|
1187
|
+
}
|
1188
|
+
}
|
1189
|
+
}
|
1190
|
+
}
|
1191
|
+
|
1192
|
+
// output
|
1193
|
+
result = rb_ary_new3(3, fe, ze, nze);
|
1194
|
+
return result;
|
1195
|
+
}
|
1196
|
+
|
1197
|
+
void
|
1198
|
+
init_gphys_dim_op()
|
1199
|
+
{
|
1200
|
+
static VALUE mNumRu;
|
1201
|
+
static VALUE cGPhys;
|
1202
|
+
static VALUE cVArray;
|
1203
|
+
|
1204
|
+
// rb_require("narray"); // it does not work ??
|
1205
|
+
mNumRu = rb_define_module("NumRu");
|
1206
|
+
|
1207
|
+
cGPhys = rb_define_class_under(mNumRu, "GPhys", rb_cObject);
|
1208
|
+
rb_define_private_method(cGPhys, "c_running_mean", running_mean, -1);
|
1209
|
+
|
1210
|
+
cVArray = rb_define_class_under(mNumRu, "VArray", rb_cObject);
|
1211
|
+
rb_define_private_method(cVArray, "c_bin_mean", bin_mean, -1);
|
1212
|
+
rb_define_private_method(cVArray, "c_bin_sum", bin_sum, -1);
|
1213
|
+
|
1214
|
+
rb_define_private_method(cVArray, "c_cum_sum", cum_sum, 2);
|
1215
|
+
rb_define_singleton_method(cGPhys, "c_cell_integ_irreg",
|
1216
|
+
cell_integ_irreg, 6);
|
1217
|
+
rb_define_singleton_method(cGPhys, "c_cum_integ_irreg", cum_integ_irreg, 6);
|
1218
|
+
|
1219
|
+
rb_define_singleton_method(cGPhys, "c_cap_by_boundary", cap_by_boundary, 6);
|
1220
|
+
}
|