gphys 1.2.2.1 → 1.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|