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.
Files changed (405) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +8 -17
  3. data/.rspec +2 -0
  4. data/.travis.yml +3 -0
  5. data/ChangeLog +5762 -753
  6. data/LICENSE.txt +30 -18
  7. data/Rakefile +1 -0
  8. data/bin/console +14 -0
  9. data/bin/gpcat +43 -2
  10. data/bin/gpcut +16 -0
  11. data/bin/gpvect +167 -15
  12. data/bin/gpview +254 -51
  13. data/bin/setup +7 -0
  14. data/dim_op.c +1220 -0
  15. data/doc/attribute.html +19 -0
  16. data/doc/attributenetcdf.html +15 -0
  17. data/doc/axis.html +387 -0
  18. data/doc/coordmapping.html +111 -0
  19. data/doc/coordtransform.html +36 -0
  20. data/doc/dclext.html +821 -0
  21. data/doc/derivative/gphys-derivative.html +100 -0
  22. data/doc/derivative/index.html +21 -0
  23. data/doc/derivative/index.rd +14 -0
  24. data/doc/derivative/math-doc/document.pdf +0 -0
  25. data/doc/derivative/math-doc/document.tex +158 -0
  26. data/doc/derivative/math-doc/document/document.css +30 -0
  27. data/doc/derivative/math-doc/document/document.html +57 -0
  28. data/doc/derivative/math-doc/document/images.aux +1 -0
  29. data/doc/derivative/math-doc/document/images.log +385 -0
  30. data/doc/derivative/math-doc/document/images.pl +186 -0
  31. data/doc/derivative/math-doc/document/images.tex +364 -0
  32. data/doc/derivative/math-doc/document/img1.png +0 -0
  33. data/doc/derivative/math-doc/document/img10.png +0 -0
  34. data/doc/derivative/math-doc/document/img11.png +0 -0
  35. data/doc/derivative/math-doc/document/img12.png +0 -0
  36. data/doc/derivative/math-doc/document/img13.png +0 -0
  37. data/doc/derivative/math-doc/document/img14.png +0 -0
  38. data/doc/derivative/math-doc/document/img15.png +0 -0
  39. data/doc/derivative/math-doc/document/img16.png +0 -0
  40. data/doc/derivative/math-doc/document/img17.png +0 -0
  41. data/doc/derivative/math-doc/document/img18.png +0 -0
  42. data/doc/derivative/math-doc/document/img19.png +0 -0
  43. data/doc/derivative/math-doc/document/img2.png +0 -0
  44. data/doc/derivative/math-doc/document/img20.png +0 -0
  45. data/doc/derivative/math-doc/document/img21.png +0 -0
  46. data/doc/derivative/math-doc/document/img22.png +0 -0
  47. data/doc/derivative/math-doc/document/img23.png +0 -0
  48. data/doc/derivative/math-doc/document/img24.png +0 -0
  49. data/doc/derivative/math-doc/document/img25.png +0 -0
  50. data/doc/derivative/math-doc/document/img26.png +0 -0
  51. data/doc/derivative/math-doc/document/img27.png +0 -0
  52. data/doc/derivative/math-doc/document/img28.png +0 -0
  53. data/doc/derivative/math-doc/document/img29.png +0 -0
  54. data/doc/derivative/math-doc/document/img3.png +0 -0
  55. data/doc/derivative/math-doc/document/img30.png +0 -0
  56. data/doc/derivative/math-doc/document/img4.png +0 -0
  57. data/doc/derivative/math-doc/document/img5.png +0 -0
  58. data/doc/derivative/math-doc/document/img6.png +0 -0
  59. data/doc/derivative/math-doc/document/img7.png +0 -0
  60. data/doc/derivative/math-doc/document/img8.png +0 -0
  61. data/doc/derivative/math-doc/document/img9.png +0 -0
  62. data/doc/derivative/math-doc/document/index.html +57 -0
  63. data/doc/derivative/math-doc/document/labels.pl +13 -0
  64. data/doc/derivative/math-doc/document/next.png +0 -0
  65. data/doc/derivative/math-doc/document/next_g.png +0 -0
  66. data/doc/derivative/math-doc/document/node1.html +238 -0
  67. data/doc/derivative/math-doc/document/node2.html +75 -0
  68. data/doc/derivative/math-doc/document/prev.png +0 -0
  69. data/doc/derivative/math-doc/document/prev_g.png +0 -0
  70. data/doc/derivative/math-doc/document/up.png +0 -0
  71. data/doc/derivative/math-doc/document/up_g.png +0 -0
  72. data/doc/derivative/numru-derivative.html +158 -0
  73. data/doc/ep_flux/ep_flux.html +469 -0
  74. data/doc/ep_flux/ggraph_on_merdional_section.html +71 -0
  75. data/doc/ep_flux/index.html +31 -0
  76. data/doc/ep_flux/index.rd +24 -0
  77. data/doc/ep_flux/math-doc/document.pdf +0 -0
  78. data/doc/ep_flux/math-doc/document.tex +2018 -0
  79. data/doc/ep_flux/math-doc/document/WARNINGS +1 -0
  80. data/doc/ep_flux/math-doc/document/contents.png +0 -0
  81. data/doc/ep_flux/math-doc/document/crossref.png +0 -0
  82. data/doc/ep_flux/math-doc/document/document.css +30 -0
  83. data/doc/ep_flux/math-doc/document/document.html +101 -0
  84. data/doc/ep_flux/math-doc/document/images.aux +1 -0
  85. data/doc/ep_flux/math-doc/document/images.log +1375 -0
  86. data/doc/ep_flux/math-doc/document/images.pl +1328 -0
  87. data/doc/ep_flux/math-doc/document/images.tex +1471 -0
  88. data/doc/ep_flux/math-doc/document/img1.png +0 -0
  89. data/doc/ep_flux/math-doc/document/img10.png +0 -0
  90. data/doc/ep_flux/math-doc/document/img100.png +0 -0
  91. data/doc/ep_flux/math-doc/document/img101.png +0 -0
  92. data/doc/ep_flux/math-doc/document/img102.png +0 -0
  93. data/doc/ep_flux/math-doc/document/img103.png +0 -0
  94. data/doc/ep_flux/math-doc/document/img104.png +0 -0
  95. data/doc/ep_flux/math-doc/document/img105.png +0 -0
  96. data/doc/ep_flux/math-doc/document/img106.png +0 -0
  97. data/doc/ep_flux/math-doc/document/img107.png +0 -0
  98. data/doc/ep_flux/math-doc/document/img108.png +0 -0
  99. data/doc/ep_flux/math-doc/document/img109.png +0 -0
  100. data/doc/ep_flux/math-doc/document/img11.png +0 -0
  101. data/doc/ep_flux/math-doc/document/img110.png +0 -0
  102. data/doc/ep_flux/math-doc/document/img111.png +0 -0
  103. data/doc/ep_flux/math-doc/document/img112.png +0 -0
  104. data/doc/ep_flux/math-doc/document/img113.png +0 -0
  105. data/doc/ep_flux/math-doc/document/img114.png +0 -0
  106. data/doc/ep_flux/math-doc/document/img115.png +0 -0
  107. data/doc/ep_flux/math-doc/document/img116.png +0 -0
  108. data/doc/ep_flux/math-doc/document/img117.png +0 -0
  109. data/doc/ep_flux/math-doc/document/img118.png +0 -0
  110. data/doc/ep_flux/math-doc/document/img119.png +0 -0
  111. data/doc/ep_flux/math-doc/document/img12.png +0 -0
  112. data/doc/ep_flux/math-doc/document/img120.png +0 -0
  113. data/doc/ep_flux/math-doc/document/img121.png +0 -0
  114. data/doc/ep_flux/math-doc/document/img122.png +0 -0
  115. data/doc/ep_flux/math-doc/document/img123.png +0 -0
  116. data/doc/ep_flux/math-doc/document/img124.png +0 -0
  117. data/doc/ep_flux/math-doc/document/img125.png +0 -0
  118. data/doc/ep_flux/math-doc/document/img126.png +0 -0
  119. data/doc/ep_flux/math-doc/document/img127.png +0 -0
  120. data/doc/ep_flux/math-doc/document/img128.png +0 -0
  121. data/doc/ep_flux/math-doc/document/img129.png +0 -0
  122. data/doc/ep_flux/math-doc/document/img13.png +0 -0
  123. data/doc/ep_flux/math-doc/document/img130.png +0 -0
  124. data/doc/ep_flux/math-doc/document/img131.png +0 -0
  125. data/doc/ep_flux/math-doc/document/img132.png +0 -0
  126. data/doc/ep_flux/math-doc/document/img133.png +0 -0
  127. data/doc/ep_flux/math-doc/document/img134.png +0 -0
  128. data/doc/ep_flux/math-doc/document/img135.png +0 -0
  129. data/doc/ep_flux/math-doc/document/img136.png +0 -0
  130. data/doc/ep_flux/math-doc/document/img137.png +0 -0
  131. data/doc/ep_flux/math-doc/document/img138.png +0 -0
  132. data/doc/ep_flux/math-doc/document/img139.png +0 -0
  133. data/doc/ep_flux/math-doc/document/img14.png +0 -0
  134. data/doc/ep_flux/math-doc/document/img140.png +0 -0
  135. data/doc/ep_flux/math-doc/document/img141.png +0 -0
  136. data/doc/ep_flux/math-doc/document/img142.png +0 -0
  137. data/doc/ep_flux/math-doc/document/img143.png +0 -0
  138. data/doc/ep_flux/math-doc/document/img144.png +0 -0
  139. data/doc/ep_flux/math-doc/document/img145.png +0 -0
  140. data/doc/ep_flux/math-doc/document/img146.png +0 -0
  141. data/doc/ep_flux/math-doc/document/img147.png +0 -0
  142. data/doc/ep_flux/math-doc/document/img148.png +0 -0
  143. data/doc/ep_flux/math-doc/document/img149.png +0 -0
  144. data/doc/ep_flux/math-doc/document/img15.png +0 -0
  145. data/doc/ep_flux/math-doc/document/img150.png +0 -0
  146. data/doc/ep_flux/math-doc/document/img151.png +0 -0
  147. data/doc/ep_flux/math-doc/document/img152.png +0 -0
  148. data/doc/ep_flux/math-doc/document/img153.png +0 -0
  149. data/doc/ep_flux/math-doc/document/img154.png +0 -0
  150. data/doc/ep_flux/math-doc/document/img155.png +0 -0
  151. data/doc/ep_flux/math-doc/document/img156.png +0 -0
  152. data/doc/ep_flux/math-doc/document/img157.png +0 -0
  153. data/doc/ep_flux/math-doc/document/img158.png +0 -0
  154. data/doc/ep_flux/math-doc/document/img159.png +0 -0
  155. data/doc/ep_flux/math-doc/document/img16.png +0 -0
  156. data/doc/ep_flux/math-doc/document/img160.png +0 -0
  157. data/doc/ep_flux/math-doc/document/img161.png +0 -0
  158. data/doc/ep_flux/math-doc/document/img162.png +0 -0
  159. data/doc/ep_flux/math-doc/document/img163.png +0 -0
  160. data/doc/ep_flux/math-doc/document/img164.png +0 -0
  161. data/doc/ep_flux/math-doc/document/img165.png +0 -0
  162. data/doc/ep_flux/math-doc/document/img166.png +0 -0
  163. data/doc/ep_flux/math-doc/document/img167.png +0 -0
  164. data/doc/ep_flux/math-doc/document/img168.png +0 -0
  165. data/doc/ep_flux/math-doc/document/img169.png +0 -0
  166. data/doc/ep_flux/math-doc/document/img17.png +0 -0
  167. data/doc/ep_flux/math-doc/document/img170.png +0 -0
  168. data/doc/ep_flux/math-doc/document/img171.png +0 -0
  169. data/doc/ep_flux/math-doc/document/img172.png +0 -0
  170. data/doc/ep_flux/math-doc/document/img173.png +0 -0
  171. data/doc/ep_flux/math-doc/document/img174.png +0 -0
  172. data/doc/ep_flux/math-doc/document/img175.png +0 -0
  173. data/doc/ep_flux/math-doc/document/img176.png +0 -0
  174. data/doc/ep_flux/math-doc/document/img177.png +0 -0
  175. data/doc/ep_flux/math-doc/document/img178.png +0 -0
  176. data/doc/ep_flux/math-doc/document/img179.png +0 -0
  177. data/doc/ep_flux/math-doc/document/img18.png +0 -0
  178. data/doc/ep_flux/math-doc/document/img180.png +0 -0
  179. data/doc/ep_flux/math-doc/document/img181.png +0 -0
  180. data/doc/ep_flux/math-doc/document/img182.png +0 -0
  181. data/doc/ep_flux/math-doc/document/img183.png +0 -0
  182. data/doc/ep_flux/math-doc/document/img184.png +0 -0
  183. data/doc/ep_flux/math-doc/document/img185.png +0 -0
  184. data/doc/ep_flux/math-doc/document/img186.png +0 -0
  185. data/doc/ep_flux/math-doc/document/img187.png +0 -0
  186. data/doc/ep_flux/math-doc/document/img188.png +0 -0
  187. data/doc/ep_flux/math-doc/document/img189.png +0 -0
  188. data/doc/ep_flux/math-doc/document/img19.png +0 -0
  189. data/doc/ep_flux/math-doc/document/img190.png +0 -0
  190. data/doc/ep_flux/math-doc/document/img191.png +0 -0
  191. data/doc/ep_flux/math-doc/document/img192.png +0 -0
  192. data/doc/ep_flux/math-doc/document/img193.png +0 -0
  193. data/doc/ep_flux/math-doc/document/img194.png +0 -0
  194. data/doc/ep_flux/math-doc/document/img195.png +0 -0
  195. data/doc/ep_flux/math-doc/document/img196.png +0 -0
  196. data/doc/ep_flux/math-doc/document/img197.png +0 -0
  197. data/doc/ep_flux/math-doc/document/img198.png +0 -0
  198. data/doc/ep_flux/math-doc/document/img199.png +0 -0
  199. data/doc/ep_flux/math-doc/document/img2.png +0 -0
  200. data/doc/ep_flux/math-doc/document/img20.png +0 -0
  201. data/doc/ep_flux/math-doc/document/img200.png +0 -0
  202. data/doc/ep_flux/math-doc/document/img21.png +0 -0
  203. data/doc/ep_flux/math-doc/document/img22.png +0 -0
  204. data/doc/ep_flux/math-doc/document/img23.png +0 -0
  205. data/doc/ep_flux/math-doc/document/img24.png +0 -0
  206. data/doc/ep_flux/math-doc/document/img25.png +0 -0
  207. data/doc/ep_flux/math-doc/document/img26.png +0 -0
  208. data/doc/ep_flux/math-doc/document/img27.png +0 -0
  209. data/doc/ep_flux/math-doc/document/img28.png +0 -0
  210. data/doc/ep_flux/math-doc/document/img29.png +0 -0
  211. data/doc/ep_flux/math-doc/document/img3.png +0 -0
  212. data/doc/ep_flux/math-doc/document/img30.png +0 -0
  213. data/doc/ep_flux/math-doc/document/img31.png +0 -0
  214. data/doc/ep_flux/math-doc/document/img32.png +0 -0
  215. data/doc/ep_flux/math-doc/document/img33.png +0 -0
  216. data/doc/ep_flux/math-doc/document/img34.png +0 -0
  217. data/doc/ep_flux/math-doc/document/img35.png +0 -0
  218. data/doc/ep_flux/math-doc/document/img36.png +0 -0
  219. data/doc/ep_flux/math-doc/document/img37.png +0 -0
  220. data/doc/ep_flux/math-doc/document/img38.png +0 -0
  221. data/doc/ep_flux/math-doc/document/img39.png +0 -0
  222. data/doc/ep_flux/math-doc/document/img4.png +0 -0
  223. data/doc/ep_flux/math-doc/document/img40.png +0 -0
  224. data/doc/ep_flux/math-doc/document/img41.png +0 -0
  225. data/doc/ep_flux/math-doc/document/img42.png +0 -0
  226. data/doc/ep_flux/math-doc/document/img43.png +0 -0
  227. data/doc/ep_flux/math-doc/document/img44.png +0 -0
  228. data/doc/ep_flux/math-doc/document/img45.png +0 -0
  229. data/doc/ep_flux/math-doc/document/img46.png +0 -0
  230. data/doc/ep_flux/math-doc/document/img47.png +0 -0
  231. data/doc/ep_flux/math-doc/document/img48.png +0 -0
  232. data/doc/ep_flux/math-doc/document/img49.png +0 -0
  233. data/doc/ep_flux/math-doc/document/img5.png +0 -0
  234. data/doc/ep_flux/math-doc/document/img50.png +0 -0
  235. data/doc/ep_flux/math-doc/document/img51.png +0 -0
  236. data/doc/ep_flux/math-doc/document/img52.png +0 -0
  237. data/doc/ep_flux/math-doc/document/img53.png +0 -0
  238. data/doc/ep_flux/math-doc/document/img54.png +0 -0
  239. data/doc/ep_flux/math-doc/document/img55.png +0 -0
  240. data/doc/ep_flux/math-doc/document/img56.png +0 -0
  241. data/doc/ep_flux/math-doc/document/img57.png +0 -0
  242. data/doc/ep_flux/math-doc/document/img58.png +0 -0
  243. data/doc/ep_flux/math-doc/document/img59.png +0 -0
  244. data/doc/ep_flux/math-doc/document/img6.png +0 -0
  245. data/doc/ep_flux/math-doc/document/img60.png +0 -0
  246. data/doc/ep_flux/math-doc/document/img61.png +0 -0
  247. data/doc/ep_flux/math-doc/document/img62.png +0 -0
  248. data/doc/ep_flux/math-doc/document/img63.png +0 -0
  249. data/doc/ep_flux/math-doc/document/img64.png +0 -0
  250. data/doc/ep_flux/math-doc/document/img65.png +0 -0
  251. data/doc/ep_flux/math-doc/document/img66.png +0 -0
  252. data/doc/ep_flux/math-doc/document/img67.png +0 -0
  253. data/doc/ep_flux/math-doc/document/img68.png +0 -0
  254. data/doc/ep_flux/math-doc/document/img69.png +0 -0
  255. data/doc/ep_flux/math-doc/document/img7.png +0 -0
  256. data/doc/ep_flux/math-doc/document/img70.png +0 -0
  257. data/doc/ep_flux/math-doc/document/img71.png +0 -0
  258. data/doc/ep_flux/math-doc/document/img72.png +0 -0
  259. data/doc/ep_flux/math-doc/document/img73.png +0 -0
  260. data/doc/ep_flux/math-doc/document/img74.png +0 -0
  261. data/doc/ep_flux/math-doc/document/img75.png +0 -0
  262. data/doc/ep_flux/math-doc/document/img76.png +0 -0
  263. data/doc/ep_flux/math-doc/document/img77.png +0 -0
  264. data/doc/ep_flux/math-doc/document/img78.png +0 -0
  265. data/doc/ep_flux/math-doc/document/img79.png +0 -0
  266. data/doc/ep_flux/math-doc/document/img8.png +0 -0
  267. data/doc/ep_flux/math-doc/document/img80.png +0 -0
  268. data/doc/ep_flux/math-doc/document/img81.png +0 -0
  269. data/doc/ep_flux/math-doc/document/img82.png +0 -0
  270. data/doc/ep_flux/math-doc/document/img83.png +0 -0
  271. data/doc/ep_flux/math-doc/document/img84.png +0 -0
  272. data/doc/ep_flux/math-doc/document/img85.png +0 -0
  273. data/doc/ep_flux/math-doc/document/img86.png +0 -0
  274. data/doc/ep_flux/math-doc/document/img87.png +0 -0
  275. data/doc/ep_flux/math-doc/document/img88.png +0 -0
  276. data/doc/ep_flux/math-doc/document/img89.png +0 -0
  277. data/doc/ep_flux/math-doc/document/img9.png +0 -0
  278. data/doc/ep_flux/math-doc/document/img90.png +0 -0
  279. data/doc/ep_flux/math-doc/document/img91.png +0 -0
  280. data/doc/ep_flux/math-doc/document/img92.png +0 -0
  281. data/doc/ep_flux/math-doc/document/img93.png +0 -0
  282. data/doc/ep_flux/math-doc/document/img94.png +0 -0
  283. data/doc/ep_flux/math-doc/document/img95.png +0 -0
  284. data/doc/ep_flux/math-doc/document/img96.png +0 -0
  285. data/doc/ep_flux/math-doc/document/img97.png +0 -0
  286. data/doc/ep_flux/math-doc/document/img98.png +0 -0
  287. data/doc/ep_flux/math-doc/document/img99.png +0 -0
  288. data/doc/ep_flux/math-doc/document/index.html +101 -0
  289. data/doc/ep_flux/math-doc/document/internals.pl +258 -0
  290. data/doc/ep_flux/math-doc/document/labels.pl +265 -0
  291. data/doc/ep_flux/math-doc/document/next.png +0 -0
  292. data/doc/ep_flux/math-doc/document/next_g.png +0 -0
  293. data/doc/ep_flux/math-doc/document/node1.html +104 -0
  294. data/doc/ep_flux/math-doc/document/node10.html +164 -0
  295. data/doc/ep_flux/math-doc/document/node11.html +86 -0
  296. data/doc/ep_flux/math-doc/document/node12.html +166 -0
  297. data/doc/ep_flux/math-doc/document/node13.html +897 -0
  298. data/doc/ep_flux/math-doc/document/node14.html +1065 -0
  299. data/doc/ep_flux/math-doc/document/node15.html +72 -0
  300. data/doc/ep_flux/math-doc/document/node16.html +81 -0
  301. data/doc/ep_flux/math-doc/document/node2.html +82 -0
  302. data/doc/ep_flux/math-doc/document/node3.html +91 -0
  303. data/doc/ep_flux/math-doc/document/node4.html +149 -0
  304. data/doc/ep_flux/math-doc/document/node5.html +330 -0
  305. data/doc/ep_flux/math-doc/document/node6.html +99 -0
  306. data/doc/ep_flux/math-doc/document/node7.html +98 -0
  307. data/doc/ep_flux/math-doc/document/node8.html +83 -0
  308. data/doc/ep_flux/math-doc/document/node9.html +140 -0
  309. data/doc/ep_flux/math-doc/document/prev.png +0 -0
  310. data/doc/ep_flux/math-doc/document/prev_g.png +0 -0
  311. data/doc/ep_flux/math-doc/document/up.png +0 -0
  312. data/doc/ep_flux/math-doc/document/up_g.png +0 -0
  313. data/doc/gdir.html +412 -0
  314. data/doc/gdir_client.html +16 -0
  315. data/doc/gdir_connect_ftp-like.html +61 -0
  316. data/doc/gdir_server.html +45 -0
  317. data/doc/ggraph.html +1119 -0
  318. data/doc/gpcat.html +45 -0
  319. data/doc/gpcut.html +47 -0
  320. data/doc/gphys.html +624 -0
  321. data/doc/gphys_fft.html +324 -0
  322. data/doc/gphys_grads_io.html +69 -0
  323. data/doc/gphys_grib_io.html +82 -0
  324. data/doc/gphys_io.html +183 -0
  325. data/doc/gphys_io_common.html +18 -0
  326. data/doc/gphys_netcdf_io.html +283 -0
  327. data/doc/gplist.html +24 -0
  328. data/doc/gpmath.html +52 -0
  329. data/doc/gpmaxmin.html +32 -0
  330. data/doc/gpprint.html +35 -0
  331. data/doc/gpview.html +349 -0
  332. data/doc/grads2nc_with_gphys.html +21 -0
  333. data/doc/grads_gridded.html +307 -0
  334. data/doc/grib.html +149 -0
  335. data/doc/grid.html +224 -0
  336. data/doc/index.html +145 -0
  337. data/doc/index.rd +138 -0
  338. data/doc/netcdf_convention.html +136 -0
  339. data/doc/unumeric.html +176 -0
  340. data/doc/update +69 -0
  341. data/doc/update_rdoc +8 -0
  342. data/doc/varray.html +299 -0
  343. data/doc/varraycomposite.html +67 -0
  344. data/ext_init.c +1 -0
  345. data/extconf.rb +16 -6
  346. data/gphys.gemspec +33 -26
  347. data/interpo.c +1 -1
  348. data/lib/numru/dclext.rb +718 -546
  349. data/lib/numru/derivative.rb +2 -0
  350. data/lib/numru/ganalysis.rb +38 -0
  351. data/lib/numru/ganalysis/beta_plane.rb +103 -0
  352. data/lib/numru/ganalysis/eof.rb +3 -2
  353. data/lib/numru/ganalysis/fitting.rb +559 -0
  354. data/lib/numru/ganalysis/histogram.rb +36 -19
  355. data/lib/numru/ganalysis/log_p.rb +130 -0
  356. data/lib/numru/ganalysis/met.rb +396 -2
  357. data/lib/numru/ganalysis/met_z.rb +300 -0
  358. data/lib/numru/ganalysis/planet.rb +17 -7
  359. data/lib/numru/ganalysis/qg.rb +685 -0
  360. data/lib/numru/ganalysis/sigma_coord.rb +90 -0
  361. data/lib/numru/gdir.rb +2 -1
  362. data/lib/numru/ggraph.rb +204 -60
  363. data/lib/numru/ggraph_on_merdional_section.rb +1 -1
  364. data/lib/numru/gphys.rb +6 -0
  365. data/lib/numru/gphys/assoccoords.rb +18 -3
  366. data/lib/numru/gphys/axis.rb +209 -8
  367. data/lib/numru/gphys/derivative.rb +11 -0
  368. data/lib/numru/gphys/gphys.rb +539 -48
  369. data/lib/numru/gphys/gphys_dim_op.rb +331 -0
  370. data/lib/numru/gphys/gphys_fft.rb +48 -2
  371. data/lib/numru/gphys/gphys_io.rb +241 -13
  372. data/lib/numru/gphys/gphys_netcdf_io.rb +77 -39
  373. data/lib/numru/gphys/gphys_nusdas_io.rb +3 -0
  374. data/lib/numru/gphys/grib.rb +133 -54
  375. data/lib/numru/gphys/grib_params.rb +26 -3
  376. data/lib/numru/gphys/grid.rb +75 -34
  377. data/lib/numru/gphys/interpolate.rb +24 -10
  378. data/lib/numru/gphys/mdstorage.rb +160 -0
  379. data/lib/numru/gphys/netcdf_convention.rb +4 -2
  380. data/lib/numru/gphys/subsetmapping.rb +0 -1
  381. data/lib/numru/gphys/unumeric.rb +50 -5
  382. data/lib/numru/gphys/varray.rb +15 -30
  383. data/lib/numru/gphys/varraycomposite.rb +107 -24
  384. data/lib/numru/gphys/varraynetcdf.rb +9 -3
  385. data/lib/numru/gphys/version.rb +5 -0
  386. data/sample/druby_cli1.rb +2 -0
  387. data/sample/druby_cli2.rb +0 -6
  388. data/sample/druby_serv2.rb +0 -13
  389. data/spec/gphys_spec.rb +11 -0
  390. data/spec/spec_helper.rb +2 -0
  391. data/test/test_assoccoords.rb +102 -0
  392. data/test/test_axis.rb +61 -0
  393. data/test/test_fitting.rb +116 -0
  394. data/test/test_gphys.rb +20 -0
  395. data/test/test_met_z.rb +96 -0
  396. data/test/test_sigma_coord.rb +50 -0
  397. data/{test → test_old}/eof_slp.rb +0 -0
  398. data/{test → test_old}/mltbit.dat +0 -0
  399. data/{test → test_old}/test_ep_flux.rb +0 -0
  400. data/{test → test_old}/test_multibitIO.rb +0 -0
  401. metadata +530 -191
  402. data/README.md +0 -29
  403. data/lib/gphys.rb +0 -2
  404. data/lib/numru/dclext_datetime_ax.rb +0 -220
  405. data/lib/version.rb +0 -3
@@ -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>))
@@ -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
@@ -27,8 +27,9 @@ module NumRu
27
27
 
28
28
  module_function
29
29
 
30
- # = Calculate EOF vectors and contribution rate
31
- # call-seq:
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