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/lib/numru/derivative.rb
CHANGED
@@ -17,6 +17,8 @@ require "narray"
|
|
17
17
|
* First derivative (2nd Order difference use three point.)
|
18
18
|
* ((<cderiv>))
|
19
19
|
* First derivative (center difference use two point.)
|
20
|
+
* ((<deriv2d>))
|
21
|
+
* 2nd derivative
|
20
22
|
* ((<b_expand_linear_ext>))
|
21
23
|
* return array extended boundaries with linear extention.
|
22
24
|
* ((<cdiff>))
|
data/lib/numru/ganalysis.rb
CHANGED
@@ -1,7 +1,45 @@
|
|
1
|
+
# Library for data analysis with GPhys
|
2
|
+
#
|
3
|
+
# To use NumRu::GAnalysis, require it in your code as
|
4
|
+
#
|
5
|
+
# require "numru/ganalysis"
|
6
|
+
#
|
7
|
+
# Or you can require specific library(ies) such as
|
8
|
+
#
|
9
|
+
# require "numru/ganalysis/planet"
|
10
|
+
# require "numru/ganalysis/covariance"
|
11
|
+
#
|
12
|
+
# Available files in this way are currently
|
13
|
+
# "numru/ganalysis/covariance",
|
14
|
+
# "numru/ganalysis/eof",
|
15
|
+
# "numru/ganalysis/histogram",
|
16
|
+
# "numru/ganalysis/planet",
|
17
|
+
# "numru/ganalysis/met",
|
18
|
+
# "numru/ganalysis/sigma_coord",
|
19
|
+
# and "numru/ganalysis/met_z".
|
20
|
+
#
|
21
|
+
# Note that the first three (covariance, eof, histogram) define
|
22
|
+
# methods directly underneath NumRu::GAnalysis, while others introduce
|
23
|
+
# sub-modules (e.g., NumRu::GAnalysis::Planet).
|
24
|
+
#
|
25
|
+
# ==== !! For developers: Please introduce sub-modules if you create a new library.
|
26
|
+
#
|
27
|
+
# == License
|
28
|
+
# http://www.gfd-dennou.org/library/ruby/products/gphys/LICENSE.txt
|
29
|
+
|
30
|
+
|
31
|
+
|
1
32
|
require "numru/gphys"
|
2
33
|
|
34
|
+
module NumRu
|
35
|
+
module GAnalysis
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
3
39
|
require "numru/ganalysis/covariance"
|
4
40
|
require "numru/ganalysis/eof"
|
5
41
|
require "numru/ganalysis/histogram"
|
6
42
|
require "numru/ganalysis/planet"
|
7
43
|
require "numru/ganalysis/met"
|
44
|
+
require "numru/ganalysis/sigma_coord"
|
45
|
+
require "numru/ganalysis/met_z"
|
@@ -0,0 +1,103 @@
|
|
1
|
+
# = NumRu::GAnalysis::BetaPlane : A class to represent a bata plane
|
2
|
+
#
|
3
|
+
# Planetary parameters are taken from the Planet module
|
4
|
+
|
5
|
+
require "numru/gphys"
|
6
|
+
require 'numru/ganalysis/planet'
|
7
|
+
|
8
|
+
module NumRu
|
9
|
+
module GAnalysis
|
10
|
+
class BetaPlane
|
11
|
+
def initialize(lat0_or_latary)
|
12
|
+
if lat0_or_latary.respond_to?(:mean)
|
13
|
+
@lat0 = lat0_or_latary.mean.to_f
|
14
|
+
else
|
15
|
+
@lat0 = lat0_or_latary
|
16
|
+
end
|
17
|
+
@phi0 = lat0 * Math::PI / 180.0
|
18
|
+
@f0 = 2 * Planet.omega * Math::sin(phi0)
|
19
|
+
@beta = 2 * Planet.omega * Math::cos(phi0) / Planet::radius
|
20
|
+
@a = Planet::radius
|
21
|
+
end
|
22
|
+
|
23
|
+
attr_reader :lat0, :phi0, :f0, :beta, :a
|
24
|
+
|
25
|
+
# Derive the x and y from the lon and lat coordinates
|
26
|
+
#
|
27
|
+
# ARGUMENTS
|
28
|
+
# * gphys (GPhys) : a GPhys object (having a lon&lat as coordinates)
|
29
|
+
#
|
30
|
+
# RETURN VALUE
|
31
|
+
# * [x, y] (GPhys objects)
|
32
|
+
def get_x_y(gphys)
|
33
|
+
lam, phi, = Planet::get_lambda_phi(gphys)
|
34
|
+
x = lam * (@a * Math::cos(@phi0))
|
35
|
+
x.units = @a.units
|
36
|
+
y = ( phi - @phi0 ) * @a
|
37
|
+
y.units = @a.units
|
38
|
+
[x, y]
|
39
|
+
end
|
40
|
+
|
41
|
+
# Horizontal gradient
|
42
|
+
#
|
43
|
+
# ARGUMENTS
|
44
|
+
# * gphys (GPhys) : a GPhys object (having a lon&lat as coordinates)
|
45
|
+
# * x [GPhys or nil] : the x coordinate, which can be obtained by
|
46
|
+
# the get_x_y method. If nil, internally calculated by get_x_y method.
|
47
|
+
# * y [GPhys or nil] : the y coordinate, which can be obtained by
|
48
|
+
# the get_x_y method. If nil, internally calculated by get_x_y method.
|
49
|
+
#
|
50
|
+
# RETURN VALUE
|
51
|
+
# * [grad_x, grad_y] (GPhys objects)
|
52
|
+
def grad_h(gphys, x=nil, y=nil)
|
53
|
+
lond, latd = Planet::find_lon_lat_dims(gphys)
|
54
|
+
x, y = get_x_y(gphys) if !x || !y
|
55
|
+
bc = GPhys::Derivative::CYCLIC_OR_LINEAR
|
56
|
+
[ gphys.cderiv(lond,bc,x), gphys.threepoint_O2nd_deriv(latd,bc,y) ]
|
57
|
+
end
|
58
|
+
|
59
|
+
def div_h(u, v, x=nil, y=nil)
|
60
|
+
lond, latd = Planet::find_lon_lat_dims(u)
|
61
|
+
x, y = get_x_y(u) if !x || !y
|
62
|
+
bc = GPhys::Derivative::CYCLIC_OR_LINEAR
|
63
|
+
gx = u.cderiv(lond,bc,x)
|
64
|
+
gy = v.threepoint_O2nd_deriv(latd,bc,y)
|
65
|
+
div = gx + gy
|
66
|
+
div.name = "div"
|
67
|
+
div.long_name = "div(#{u.long_name},#{v.long_name})"
|
68
|
+
div
|
69
|
+
end
|
70
|
+
|
71
|
+
# Gradient in the x direction
|
72
|
+
#
|
73
|
+
# ARGUMENTS
|
74
|
+
# * gphys (GPhys) : a GPhys object (having a longitude as a coordinate)
|
75
|
+
# * x [GPhys or nil] : the x coordinate, which can be obtained by
|
76
|
+
# the get_x_y method. If nil, internally calculated by get_x_y method.
|
77
|
+
#
|
78
|
+
# RETURN VALUE
|
79
|
+
# * grad_x (GPhys objects)
|
80
|
+
def grad_x(gphys, x=nil)
|
81
|
+
lond, latd = Planet::find_lon_lat_dims
|
82
|
+
x, = get_x_y(gphys) if !x
|
83
|
+
gphys.cderiv(lond,x)
|
84
|
+
end
|
85
|
+
|
86
|
+
# Gradient in the y direction
|
87
|
+
#
|
88
|
+
# ARGUMENTS
|
89
|
+
# * gphys (GPhys) : a GPhys object (having a latitude as a coordinate)
|
90
|
+
# * y [GPhys or nil] : the y coordinate, which can be obtained by
|
91
|
+
# the get_x_y method. If nil, internally calculated by get_x_y method.
|
92
|
+
#
|
93
|
+
# RETURN VALUE
|
94
|
+
# * grad_y (GPhys objects)
|
95
|
+
def grad_y(gphys, y=nil)
|
96
|
+
lond, latd = Planet::find_lon_lat_dims
|
97
|
+
x, y = get_x_y(gphys) if !y
|
98
|
+
gphys.threepoint_O2nd_deriv(latd,y)
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
data/lib/numru/ganalysis/eof.rb
CHANGED
@@ -27,8 +27,9 @@ module NumRu
|
|
27
27
|
|
28
28
|
module_function
|
29
29
|
|
30
|
-
#
|
31
|
-
#
|
30
|
+
# Calculate EOF vectors and contribution rate
|
31
|
+
#
|
32
|
+
# == call-seq
|
32
33
|
# NumRu::GAnalysis.eof(gphys, dim0[, dim1, ..., dimN[, opts]]) => [eof, rate]
|
33
34
|
#
|
34
35
|
# == Arguments
|
@@ -0,0 +1,559 @@
|
|
1
|
+
require "numru/gphys"
|
2
|
+
|
3
|
+
module NumRu
|
4
|
+
module GAnalysis
|
5
|
+
|
6
|
+
# Library for function fitting
|
7
|
+
#
|
8
|
+
module Fitting
|
9
|
+
|
10
|
+
# Predifined functions for convenience
|
11
|
+
|
12
|
+
# predefined Proc for fitting: Polynomial x (function of the 1st dim)
|
13
|
+
X = proc {|*args|
|
14
|
+
raise(ArgumentError,"# of arge must be >= 1") if args.length==0
|
15
|
+
x = args[0]
|
16
|
+
self.ensure_1D_NArray(x, 0)
|
17
|
+
rank = args.length
|
18
|
+
f = x.dup
|
19
|
+
(rank-1).times{f.newdim!(-1)} # f.rank becomes the number of arguments
|
20
|
+
f
|
21
|
+
}
|
22
|
+
|
23
|
+
# predefined Proc for fitting: Polynomial x**2 (function of the 1st dim)
|
24
|
+
XX = proc {|*args|
|
25
|
+
raise(ArgumentError,"# of arge must be >= 1") if args.length==0
|
26
|
+
x = args[0]
|
27
|
+
self.ensure_1D_NArray(x, 0)
|
28
|
+
rank = args.length
|
29
|
+
f = x*x
|
30
|
+
(rank-1).times{f.newdim!(-1)} # f.rank becomes the number of arguments
|
31
|
+
f
|
32
|
+
}
|
33
|
+
|
34
|
+
# predefined Proc for fitting: Polynomial y (function of the 2nd dim)
|
35
|
+
Y = proc {|*args|
|
36
|
+
raise(ArgumentError,"# of arge must be >= 2") if args.length < 2
|
37
|
+
y = args[1]
|
38
|
+
self.ensure_1D_NArray(y, 1)
|
39
|
+
rank = args.length
|
40
|
+
f = y.dup
|
41
|
+
f.newdim!(0)
|
42
|
+
(rank-2).times{f.newdim!(-1)} # f.rank becomes the number of arguments
|
43
|
+
f
|
44
|
+
}
|
45
|
+
|
46
|
+
# predefined Proc for fitting: Polynomial y**2 (function of the 2nd dim)
|
47
|
+
YY = proc {|*args|
|
48
|
+
raise(ArgumentError,"# of arge must be >= 2") if args.length < 2
|
49
|
+
y = args[1]
|
50
|
+
self.ensure_1D_NArray(y, 1)
|
51
|
+
rank = args.length
|
52
|
+
f = y*y
|
53
|
+
f.newdim!(0)
|
54
|
+
(rank-2).times{f.newdim!(-1)} # f.rank becomes the number of arguments
|
55
|
+
f
|
56
|
+
}
|
57
|
+
|
58
|
+
# predefined Proc for fitting: Polynomial x*y (function of the 1st&2nd dims)
|
59
|
+
XY = proc {|*args|
|
60
|
+
raise(ArgumentError,"# of arge must be >= 2") if args.length < 2
|
61
|
+
x = args[0]
|
62
|
+
y = args[1]
|
63
|
+
self.ensure_1D_NArray(x, 0)
|
64
|
+
self.ensure_1D_NArray(y, 1)
|
65
|
+
rank = args.length
|
66
|
+
f = x.newdim(-1) * y.newdim(0)
|
67
|
+
(rank-2).times{f.newdim!(-1)} # f.rank becomes the number of arguments
|
68
|
+
f
|
69
|
+
}
|
70
|
+
|
71
|
+
@@unity = proc {|*args|
|
72
|
+
rank = args.length
|
73
|
+
f = NArray.sfloat(1).fill!(1.0) # will be coersed to float when needed
|
74
|
+
(rank-1).times{f.newdim!(-1)}
|
75
|
+
f
|
76
|
+
}
|
77
|
+
|
78
|
+
|
79
|
+
module_function
|
80
|
+
|
81
|
+
# Least square fit of a linear combination of any functions (basic NArray version).
|
82
|
+
#
|
83
|
+
# === ARGUMENTS
|
84
|
+
# * +data+ [NArray or NArrayMiss] multi-D data to fit
|
85
|
+
# * +grid_locs+ [Array of 1D NArrays] Grid points of independent variables
|
86
|
+
# (so grid_locs.length == the # of independent variables).
|
87
|
+
# * +functions+ [Array of Procs] Proc objects to represent the functions,
|
88
|
+
# which accept the elements of +grid_locs+ as the arguments (so the
|
89
|
+
# number of arguments fed is equal to the length of +grid_locs+).
|
90
|
+
# * +ensemble_dims+ (optional) [nil (defualt) or Array of Integers]
|
91
|
+
# When <tt>grid_locs.length < data.rank</tt>,
|
92
|
+
# this argument can be used to specify the dimensions that are
|
93
|
+
# not included in grid_locs and are used for ensemble averaging
|
94
|
+
# * +indep_dims+ (optional) [nil (defualt) or Array of Integers]
|
95
|
+
# When <tt>grid_locs.length < data.rank</tt>,
|
96
|
+
# this argument can be used to specify the dimensions that are
|
97
|
+
# not included in +grid_locs+ and are treated as independent, so
|
98
|
+
# the fitting is made for each of their component.
|
99
|
+
#
|
100
|
+
# Note that the sum of the lengths of +grid_locs+, +ensemble_dims+ and
|
101
|
+
# +indep_dims+ must be equal to the rank (# of dims) of +data+.
|
102
|
+
#
|
103
|
+
# === RETURN VALUES
|
104
|
+
# [ c, bf, diff ]
|
105
|
+
# where
|
106
|
+
# * +c+ is a NArray containing the coefficients of the functions
|
107
|
+
# and the constant offset; its length is one greater than the
|
108
|
+
# number of +functions+ because of the offset.
|
109
|
+
# It is 1D unless the +indep_dims+ argument is used
|
110
|
+
# (see the examples below).
|
111
|
+
# * +bf+ is a NArray having the best fit grid point values.
|
112
|
+
# Its rank is equal to data.rank, but the lengths along
|
113
|
+
# +ensemble_dims+ are simply 1.
|
114
|
+
# * rms of the difference between the data and best fit
|
115
|
+
#
|
116
|
+
# === EXAMPLES
|
117
|
+
# * Simple 1D case
|
118
|
+
#
|
119
|
+
# Line fitting:
|
120
|
+
#
|
121
|
+
# nx = 5
|
122
|
+
# x = NArray.float(nx).indgen! - nx/2
|
123
|
+
# data = x + x*x*0.1
|
124
|
+
# c, bf = GAnalysis::Fitting.least_square_fit(data, [x],
|
125
|
+
# [GAnalysis::Fitting::X])
|
126
|
+
# p "data:", data, "c:", c, "bf:", bf
|
127
|
+
#
|
128
|
+
# Here, +GAnalysis::Fitting::X+ is a predefined Proc to represent
|
129
|
+
# the first order polynomial x. The data values given as above follow
|
130
|
+
# f(x) = x + x**2/10. Then the result printed by the last line is
|
131
|
+
# "data:"
|
132
|
+
# NArray.float(5):
|
133
|
+
# [ -1.6, -0.9, 0.0, 1.1, 2.4 ]
|
134
|
+
# "c:"
|
135
|
+
# NArray.float(2):
|
136
|
+
# [ 1.0, 0.2 ]
|
137
|
+
# "bf:"
|
138
|
+
# NArray.float(5):
|
139
|
+
# [ -1.8, -0.8, 0.2, 1.2, 2.2 ]
|
140
|
+
# The +c+ values indicate that the fitting result is f(x) = 1.0*x + 0.2,
|
141
|
+
# and the +bf+ values are its grid point values.
|
142
|
+
#
|
143
|
+
# Parabolic fitting:
|
144
|
+
#
|
145
|
+
# You can also fit the data by 2nd order polynomial as
|
146
|
+
# c, bf = GAnalysis::Fitting.least_square_fit(data, [x],
|
147
|
+
# [GAnalysis::Fitting::XX,GAnalysis::Fitting::X])
|
148
|
+
# Then the result will be
|
149
|
+
# p c #--> [0.1, 1.0, 0.0]
|
150
|
+
# which indicates the original 2nd order polynomial 0.1 x**2 + x,
|
151
|
+
# so it follows <tt>data == bf</tt> (except for round-off error if any).
|
152
|
+
#
|
153
|
+
# * 1D fitting of multi-D data (ensemble case)
|
154
|
+
#
|
155
|
+
# Suppose you have a 2D NArray (or NArrayMiss) data, in which
|
156
|
+
# the 1st dim represents x and the 2nd dim represents something
|
157
|
+
# else (such as time sequence, or just a simple ensemble).
|
158
|
+
# If you want to use the entire data to get a single fit,
|
159
|
+
# use the +ensemble_dims+ argument to specify the non-x dimension(s).
|
160
|
+
# You can fit the data, for example, by
|
161
|
+
# p*sin(x) + q*cos(x) + r as follows:
|
162
|
+
#
|
163
|
+
# sin = proc{|x| NMath.sin(x)}
|
164
|
+
# cos = proc{|x| NMath.cos(x)}
|
165
|
+
# c, bf = GAnalysis::Fitting.least_square_fit(data, [x],
|
166
|
+
# [sin, cos], [1])
|
167
|
+
# Here, the last parameter [1] is given as the arguemnt
|
168
|
+
# +ensemble_dims+ to express that the dimension 1
|
169
|
+
# (2nd dimension) of +data+ is the ensemble dimension, so the x
|
170
|
+
# coordinate is the remaining dimension 0 (1st dimension). The
|
171
|
+
# coefficients of the functions are returned by
|
172
|
+
# the 1st return value as a NArray, so
|
173
|
+
# p = c[0]
|
174
|
+
# q = c[1]
|
175
|
+
# r = c[2]
|
176
|
+
#
|
177
|
+
# * 1D fitting of multi-D data (individual fitting)
|
178
|
+
#
|
179
|
+
# Suppose you have the same data as above, but
|
180
|
+
# you want to fit it for each of the 2nd dim elements. You can
|
181
|
+
# do it as follows:
|
182
|
+
#
|
183
|
+
# c, bf = GAnalysis::Fitting.least_square_fit(data, [x],
|
184
|
+
# [sin, cos], nil, [1])
|
185
|
+
#
|
186
|
+
# Here, +nil+ is given as the 4th argument (+ensemble_dims+)
|
187
|
+
# and [1] is given as the fifth (+indep_dims+).
|
188
|
+
# In this case, the return value +c+ is 2-dimensional; the
|
189
|
+
# first being the coefficients as above and the second representing
|
190
|
+
# the non-x (i.e., the second) dim of +data+.
|
191
|
+
#
|
192
|
+
# * 2D fitting
|
193
|
+
#
|
194
|
+
# It can be done like
|
195
|
+
#
|
196
|
+
# cosx = proc {|x,y| NMath.cos(x).newdim!(-1)}
|
197
|
+
# sinx = proc {|x,y| NMath.sin(x).newdim!(-1)}
|
198
|
+
# cosy = proc {|x,y| NMath.cos(y).newdim!(0)}
|
199
|
+
# siny = proc {|x,y| NMath.sin(y).newdim!(0)}
|
200
|
+
# c, bf = GAnalysis::Fitting.least_square_fit(data4D, [x,y],
|
201
|
+
# [cosx, sinx, cosy, siny], [2,3])
|
202
|
+
# where +data4D+ is a 4D NArray, whose first and second dimensions
|
203
|
+
# (dimensions 0 and 1) represent x and y axis, respectively, and the
|
204
|
+
# 1D NArrays +x+ and +y+ are the grid points.
|
205
|
+
# Note that the functions (+cosx+ etc) accept 2 arguments (x and y),
|
206
|
+
# and they use NArray's +newdim+ method to return 2D NArray
|
207
|
+
# (newdim!(-1) inserts a 1-element dim to the end, and
|
208
|
+
# newdim(0) inserts a 1-element dim to the beginning).
|
209
|
+
#
|
210
|
+
# TYPICAL ERRORS
|
211
|
+
# * Error is raised (from the LU decomposition), if the problem
|
212
|
+
# cannot be solved. That happens if you specify a same function twice
|
213
|
+
# (redundantly) in the +functions+ argument, as a matter of course.
|
214
|
+
# * Error is raised if the number of data is insuffcient for the
|
215
|
+
# number of functions (also unsolvable).
|
216
|
+
#
|
217
|
+
def least_square_fit(data, grid_locs, functions, ensemble_dims=nil,
|
218
|
+
indep_dims=nil)
|
219
|
+
|
220
|
+
#< argument check >
|
221
|
+
|
222
|
+
grid_locs.each_with_index{|x,i| self.ensure_1D_NArray(x, i)}
|
223
|
+
functions.each{|f| raise("Found non-Proc arg") if !f.is_a?(Proc)}
|
224
|
+
|
225
|
+
functions = functions + [@@unity] # constanf offset
|
226
|
+
|
227
|
+
ng = grid_locs.length
|
228
|
+
rank = data.rank
|
229
|
+
ensemble_dims = [ ensemble_dims ] if ensemble_dims.is_a?(Integer)
|
230
|
+
indep_dims = [ indep_dims ] if indep_dims.is_a?(Integer)
|
231
|
+
|
232
|
+
ensemble_dims = Array.new if ensemble_dims.nil? # --> always an Array
|
233
|
+
n_indep = ( indep_dims ? indep_dims.length : 0 )
|
234
|
+
|
235
|
+
if ng < rank
|
236
|
+
ensemble_dims = ensemble_dims.collect{|d|
|
237
|
+
if d<-rank || d>=rank
|
238
|
+
raise "Invalid ensemble_dims value (#{d}) for rank #{rank} NArray"
|
239
|
+
end
|
240
|
+
d += rank if d<0
|
241
|
+
d
|
242
|
+
}
|
243
|
+
ensemble_dims.sort!
|
244
|
+
if indep_dims
|
245
|
+
indep_dims = indep_dims.collect{|d|
|
246
|
+
if d<-rank || d>=rank
|
247
|
+
raise "Invalid indep_dims value (#{d}) for rank #{rank} NArray"
|
248
|
+
end
|
249
|
+
d += rank if d<0
|
250
|
+
d
|
251
|
+
}
|
252
|
+
indep_dims.sort!
|
253
|
+
end
|
254
|
+
elsif ng > rank
|
255
|
+
raise "# of grid_locs (#{ng}) > data.rank (#{rank})"
|
256
|
+
end
|
257
|
+
|
258
|
+
if data.rank != ng + ensemble_dims.length + n_indep
|
259
|
+
raise ArgumentError,
|
260
|
+
"lengths of grid_locs, ensemble_dims and indep_dims != data.rank"
|
261
|
+
end
|
262
|
+
|
263
|
+
otherdims = ensemble_dims
|
264
|
+
if indep_dims
|
265
|
+
otherdims += indep_dims
|
266
|
+
otherdims.sort!.uniq!
|
267
|
+
if otherdims.length != ensemble_dims.length + n_indep
|
268
|
+
raise ArgumentError, "Overlap in ensemble_dims and indep_dims"
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
#< pre-process data >
|
273
|
+
|
274
|
+
d0 = data.mean
|
275
|
+
data = data - d0 # constant offset for numerical stability
|
276
|
+
|
277
|
+
if data.is_a?(NArrayMiss)
|
278
|
+
mask = data.get_mask
|
279
|
+
elsif data.is_a?(NArray)
|
280
|
+
mask = nil # NArray.byte(*data.shape).fill!(1)
|
281
|
+
else
|
282
|
+
raise "Data type (#{data.class}) is not NArray or NArrayMiss"
|
283
|
+
end
|
284
|
+
|
285
|
+
#< derive the matrix >
|
286
|
+
|
287
|
+
fv = functions.collect{|f|
|
288
|
+
f = f[*grid_locs]
|
289
|
+
otherdims.each{|d| f.newdim!(d)}
|
290
|
+
f
|
291
|
+
}
|
292
|
+
|
293
|
+
ms = fv.length # matrix size
|
294
|
+
|
295
|
+
if ( (len=data.length) < ms )
|
296
|
+
raise "Insufficient data length (#{len}) for the # of funcs+1 (#{ms})"
|
297
|
+
end
|
298
|
+
|
299
|
+
mat = NMatrix.float(ms,ms) # wil be symmetric
|
300
|
+
|
301
|
+
for i in 0...ms
|
302
|
+
for j in 0..i
|
303
|
+
if mask
|
304
|
+
fvij = NArrayMiss.to_nam( fv[i] * fv[j] * mask, mask )
|
305
|
+
mat[i,j] = (fvij).mean
|
306
|
+
else
|
307
|
+
mat[i,j] = (fv[i] * fv[j]).mean
|
308
|
+
end
|
309
|
+
end
|
310
|
+
end
|
311
|
+
|
312
|
+
for i in 0...ms
|
313
|
+
for j in i+1...ms
|
314
|
+
mat[i,j] = mat[j,i] # symmetric
|
315
|
+
end
|
316
|
+
end
|
317
|
+
#p "*** mat ***",mat
|
318
|
+
lu = mat.lu
|
319
|
+
|
320
|
+
#< derive the vector, solve, and best fit >
|
321
|
+
|
322
|
+
unless indep_dims # fitting only once
|
323
|
+
# derive the vector
|
324
|
+
b = NVector.float(ms)
|
325
|
+
for i in 0...ms
|
326
|
+
b[i] = (data * fv[i]).mean
|
327
|
+
end
|
328
|
+
|
329
|
+
# solve
|
330
|
+
c = lu.solve(b)
|
331
|
+
c[-1] += d0 # add the mean subtracted
|
332
|
+
|
333
|
+
# convert c from NVector to NArray (just for cleanliness)
|
334
|
+
na = NArray.float(ms)
|
335
|
+
na[true] = c[true]
|
336
|
+
c = na
|
337
|
+
|
338
|
+
# best fit
|
339
|
+
bf = c[-1] # the constant offset
|
340
|
+
for i in 0...ms-1
|
341
|
+
bf += c[i]*fv[i]
|
342
|
+
end
|
343
|
+
|
344
|
+
else # fitting multiple times
|
345
|
+
|
346
|
+
# derive vectors
|
347
|
+
idshp = indep_dims.collect{|d| data.shape[d]}
|
348
|
+
bs = NArray.float(ms,*idshp)
|
349
|
+
meandims = (0...rank).collect{|d| d} - indep_dims
|
350
|
+
for i in 0...ms
|
351
|
+
bsi = (data * fv[i]).mean(*meandims)
|
352
|
+
if bsi.is_a?(NArrayMiss)
|
353
|
+
if bsi.count_invalid > 0
|
354
|
+
raise("Found invalid data everywhere along indep_dims. Trim data in advance and try again.")
|
355
|
+
end
|
356
|
+
bsi = bsi.to_na
|
357
|
+
end
|
358
|
+
bs[i,false] = bsi
|
359
|
+
end
|
360
|
+
idlen = 1
|
361
|
+
idshp.each{|l| idlen *= l}
|
362
|
+
|
363
|
+
# solve
|
364
|
+
bs = bs.reshape(ms, idlen)
|
365
|
+
c = NArray.float(ms,idlen)
|
366
|
+
b = NVector.float(ms)
|
367
|
+
for id in 0...idlen
|
368
|
+
b[true] = bs[true,id]
|
369
|
+
c[true,id] = lu.solve(b)
|
370
|
+
end
|
371
|
+
c[-1,true] += d0
|
372
|
+
c = c.reshape(ms, *idshp)
|
373
|
+
|
374
|
+
# best fit
|
375
|
+
idshp_full = Array.new
|
376
|
+
for d in 0...rank
|
377
|
+
if indep_dims.include?(d)
|
378
|
+
idshp_full[d] = data.shape[d]
|
379
|
+
else
|
380
|
+
idshp_full[d] = 1
|
381
|
+
end
|
382
|
+
end
|
383
|
+
cs = c.reshape(ms, *idshp_full)
|
384
|
+
bf = cs[-1,false]
|
385
|
+
for i in 0...ms-1
|
386
|
+
bf += cs[i,false]*fv[i]
|
387
|
+
end
|
388
|
+
|
389
|
+
end
|
390
|
+
|
391
|
+
diff = Math.sqrt( ( (data + d0 - bf)**2 ).mean )
|
392
|
+
|
393
|
+
#< return >
|
394
|
+
|
395
|
+
[ c, bf, diff ]
|
396
|
+
end
|
397
|
+
|
398
|
+
################################################
|
399
|
+
# For internal usage
|
400
|
+
|
401
|
+
private
|
402
|
+
|
403
|
+
def self.ensure_1D_NArray(na, ith)
|
404
|
+
raise("proc argument #{ith}: not a NArray") if !na.is_a?(NArray)
|
405
|
+
raise("proc argument #{ith}: not 1 dimensional") if na.rank != 1
|
406
|
+
nil
|
407
|
+
end
|
408
|
+
|
409
|
+
end
|
410
|
+
|
411
|
+
end
|
412
|
+
|
413
|
+
# GPhys extension with GAnalysis::Fitting
|
414
|
+
class GPhys
|
415
|
+
# Least square fit of a linear combination of any functions (GPhys version).
|
416
|
+
#
|
417
|
+
# This method calls GAnalysis::Fitting.least_square_fit in
|
418
|
+
# the GAnalysis::Fitting module.
|
419
|
+
# See its document for the details, usage, and predifined functions.
|
420
|
+
#
|
421
|
+
# === ARGUMENTS
|
422
|
+
#
|
423
|
+
# The arguments are the same as the third to fifth arguemnts of
|
424
|
+
# GAnalysis::Fitting.least_square_fit except that +ensemble_dims+
|
425
|
+
# and +indep_dims+ accept dimension specification by names (in Strings).
|
426
|
+
#
|
427
|
+
# * +functions+ [Array of Procs] Proc objects to represent the functions,
|
428
|
+
# which accept the elements of +grid_locs+ as the arguments (so the
|
429
|
+
# number of arguments fed is equal to the length of +grid_locs+).
|
430
|
+
# (Some predifined functions are available in GAnalysis::Fitting).
|
431
|
+
# * +ensemble_dims+ (optional) [nil (defualt) or Array of Integers or Strings]
|
432
|
+
# When <tt>grid_locs.length < data.rank</tt>,
|
433
|
+
# this argument can be used to specify the dimensions that are
|
434
|
+
# not included in grid_locs and are used for ensemble averaging
|
435
|
+
# * +indep_dims+ (optional) [nil (defualt) or Array of Integers or Strings]
|
436
|
+
# When <tt>grid_locs.length < data.rank</tt>,
|
437
|
+
# this argument can be used to specify the dimensions that are
|
438
|
+
# not included in +grid_locs+ and are treated as independent, so
|
439
|
+
# the fitting is made for each of their component.
|
440
|
+
#
|
441
|
+
# === RETURN VALUES
|
442
|
+
# [ c, bf, diff ]
|
443
|
+
# where
|
444
|
+
# * +c+ is a NArray containing the coefficients of the functions
|
445
|
+
# and the constant offset; its length is one greater than the
|
446
|
+
# number of +functions+ because of the offset.
|
447
|
+
# It is 1D unless the +indep_dims+ argument is used
|
448
|
+
# (see the examples below).
|
449
|
+
# * +bf+ is a GPhys having the best fit grid point values.
|
450
|
+
# Its rank is equal to data.rank unless ensemble_dims
|
451
|
+
# are given; ensemble_dims are deleted unlike the return
|
452
|
+
# value of GAnalysis::Fitting.least_square_fit.
|
453
|
+
# * rms of the difference between the data and best fit
|
454
|
+
#
|
455
|
+
# === USAGE
|
456
|
+
# See GAnalysis::Fitting.least_square_fit.
|
457
|
+
|
458
|
+
|
459
|
+
|
460
|
+
def least_square_fit(functions, ensemble_dims=nil, indep_dims=nil)
|
461
|
+
|
462
|
+
#< preparation >
|
463
|
+
|
464
|
+
no_fitting_dims = Array.new
|
465
|
+
if ensemble_dims
|
466
|
+
ensemble_dims = ensemble_dims.collect{|d| @grid.dim_index(d)}
|
467
|
+
no_fitting_dims += ensemble_dims
|
468
|
+
end
|
469
|
+
if indep_dims
|
470
|
+
indep_dims = indep_dims.collect{|d| @grid.dim_index(d)}
|
471
|
+
no_fitting_dims += indep_dims
|
472
|
+
end
|
473
|
+
fitting_dims = (0...rank).collect{|i| i} - no_fitting_dims
|
474
|
+
grid_locs = fitting_dims.collect{|d| coord(d).val}
|
475
|
+
data = self.val
|
476
|
+
|
477
|
+
#< fitting >
|
478
|
+
c, bf, diff = GAnalysis::Fitting.least_square_fit(data, grid_locs,
|
479
|
+
functions, ensemble_dims, indep_dims)
|
480
|
+
|
481
|
+
#< make a GPhys of the best fit >
|
482
|
+
|
483
|
+
if !ensemble_dims
|
484
|
+
grid = self.grid
|
485
|
+
else
|
486
|
+
axes = Array.new
|
487
|
+
(0...rank).each{|d|
|
488
|
+
axes.push(self.axis(d)) unless ensemble_dims.include?(d)
|
489
|
+
}
|
490
|
+
grid = Grid.new(*axes)
|
491
|
+
shape = bf.shape
|
492
|
+
ensemble_dims.sort.reverse_each{|d| shape.delete_at(d)}
|
493
|
+
bf = bf.reshape(*shape)
|
494
|
+
end
|
495
|
+
|
496
|
+
va = VArray.new(bf, self.data, self.name)
|
497
|
+
bf = GPhys.new(grid, va)
|
498
|
+
|
499
|
+
[c, bf, diff]
|
500
|
+
end
|
501
|
+
end
|
502
|
+
|
503
|
+
end
|
504
|
+
|
505
|
+
|
506
|
+
######################################################
|
507
|
+
if $0 == __FILE__
|
508
|
+
|
509
|
+
include NumRu
|
510
|
+
nx = 7
|
511
|
+
ny = 5
|
512
|
+
x = NArray.float(nx).indgen!
|
513
|
+
y = NArray.float(ny).indgen! - 1
|
514
|
+
#p GAnalysis::Fitting::X[x]
|
515
|
+
#p GAnalysis::Fitting::X[x,nil,nil]
|
516
|
+
#p GAnalysis::Fitting::X[x,y]
|
517
|
+
#p GAnalysis::Fitting::XX[x,y]
|
518
|
+
#p GAnalysis::Fitting::Y[x,y]
|
519
|
+
#p GAnalysis::Fitting::YY[x,y]
|
520
|
+
#p GAnalysis::Fitting::XY[x,y,nil]
|
521
|
+
#exit
|
522
|
+
|
523
|
+
xx = x.newdim(-1)
|
524
|
+
yy = y.newdim(0)
|
525
|
+
data = xx + 2*yy + 100
|
526
|
+
data += data.random * 0.1
|
527
|
+
p "***data**", data
|
528
|
+
|
529
|
+
f_x = GAnalysis::Fitting::X
|
530
|
+
f_y = GAnalysis::Fitting::Y
|
531
|
+
|
532
|
+
p GAnalysis::Fitting.least_square_fit(data, [x,y], [f_x, f_y])
|
533
|
+
|
534
|
+
data2 = NArray.float(nx,2,ny)
|
535
|
+
data2[true,0,true] = data - 1
|
536
|
+
data2[true,1,true] = data + 1
|
537
|
+
p GAnalysis::Fitting.least_square_fit(data2, [x,y], [f_x, f_y], [1])
|
538
|
+
|
539
|
+
nx = 5
|
540
|
+
x = NArray.float(nx).indgen! - nx/2
|
541
|
+
data = x + x*x*0.1
|
542
|
+
c, bf, diff = GAnalysis::Fitting.least_square_fit(data, [x],
|
543
|
+
[GAnalysis::Fitting::X])
|
544
|
+
p "data:", data, "c:", c, "bf:", bf
|
545
|
+
exit
|
546
|
+
|
547
|
+
c, bf, diff = GAnalysis::Fitting.least_square_fit(data, [x],
|
548
|
+
[GAnalysis::Fitting::X,GAnalysis::Fitting::XX])
|
549
|
+
p c
|
550
|
+
|
551
|
+
xx = x.newdim(-1)
|
552
|
+
data = xx + 2*yy + 100
|
553
|
+
cosx = proc {|x,y| NMath.cos(x).newdim!(-1)}
|
554
|
+
sinx = proc {|x,y| NMath.sin(x).newdim!(-1)}
|
555
|
+
cosy = proc {|x,y| NMath.cos(y).newdim!(0)}
|
556
|
+
siny = proc {|x,y| NMath.sin(y).newdim!(0)}
|
557
|
+
p GAnalysis::Fitting.least_square_fit(data, [x,y], [cosx, sinx, cosy, siny])
|
558
|
+
|
559
|
+
end
|