gphys 1.2.2.1 → 1.4.3

Sign up to get free protection for your applications and to get access to all the features.
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