gphys 1.5.0 → 1.5.1

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 (94) hide show
  1. checksums.yaml +7 -0
  2. data/ChangeLog +7414 -0
  3. data/LICENSE.txt +1 -1
  4. data/Rakefile +0 -2
  5. data/doc/derivative/math-doc/document/images.log +385 -0
  6. data/doc/ep_flux/math-doc/document/images.log +1375 -0
  7. data/doc/ganalysis/doc/NumRu.html +203 -0
  8. data/doc/ganalysis/doc/NumRu/GAnalysis.html +931 -0
  9. data/doc/ganalysis/doc/NumRu/GAnalysis/BetaPlane.html +574 -0
  10. data/doc/ganalysis/doc/NumRu/GAnalysis/Fitting.html +576 -0
  11. data/doc/ganalysis/doc/NumRu/GAnalysis/LogP.html +425 -0
  12. data/doc/ganalysis/doc/NumRu/GAnalysis/Met.html +2021 -0
  13. data/doc/ganalysis/doc/NumRu/GAnalysis/MetZ.html +524 -0
  14. data/doc/ganalysis/doc/NumRu/GAnalysis/Planet.html +1047 -0
  15. data/doc/ganalysis/doc/NumRu/GAnalysis/QG.html +794 -0
  16. data/doc/ganalysis/doc/NumRu/GAnalysis/QG/Uninitialized.html +215 -0
  17. data/doc/ganalysis/doc/NumRu/GAnalysis/QG_common.html +603 -0
  18. data/doc/ganalysis/doc/NumRu/GAnalysis/QG_sphere.html +760 -0
  19. data/doc/ganalysis/doc/NumRu/GAnalysis/QG_sphere_common.html +251 -0
  20. data/doc/ganalysis/doc/NumRu/GAnalysis/QG_sphere_div.html +424 -0
  21. data/doc/ganalysis/doc/NumRu/GAnalysis/SigmaCoord.html +321 -0
  22. data/doc/ganalysis/doc/NumRu/GGraph.html +334 -0
  23. data/doc/ganalysis/doc/NumRu/GPhys.html +579 -0
  24. data/doc/ganalysis/doc/Object.html +210 -0
  25. data/doc/ganalysis/doc/__/__/lib/numru/ganalysis/beta_plane_rb.html +60 -0
  26. data/doc/ganalysis/doc/__/__/lib/numru/ganalysis/covariance_rb.html +56 -0
  27. data/doc/ganalysis/doc/__/__/lib/numru/ganalysis/eof_rb.html +64 -0
  28. data/doc/ganalysis/doc/__/__/lib/numru/ganalysis/fitting_rb.html +54 -0
  29. data/doc/ganalysis/doc/__/__/lib/numru/ganalysis/histogram_rb.html +58 -0
  30. data/doc/ganalysis/doc/__/__/lib/numru/ganalysis/log_p_rb.html +60 -0
  31. data/doc/ganalysis/doc/__/__/lib/numru/ganalysis/met_rb.html +60 -0
  32. data/doc/ganalysis/doc/__/__/lib/numru/ganalysis/met_z_rb.html +58 -0
  33. data/doc/ganalysis/doc/__/__/lib/numru/ganalysis/planet_rb.html +58 -0
  34. data/doc/ganalysis/doc/__/__/lib/numru/ganalysis/qg_rb.html +64 -0
  35. data/doc/ganalysis/doc/__/__/lib/numru/ganalysis/sigma_coord_rb.html +56 -0
  36. data/doc/ganalysis/doc/__/__/lib/numru/ganalysis_rb.html +98 -0
  37. data/doc/ganalysis/doc/created.rid +13 -0
  38. data/doc/ganalysis/doc/images/brick.png +0 -0
  39. data/doc/ganalysis/doc/images/brick_link.png +0 -0
  40. data/doc/ganalysis/doc/images/bug.png +0 -0
  41. data/doc/ganalysis/doc/images/bullet_black.png +0 -0
  42. data/doc/ganalysis/doc/images/bullet_toggle_minus.png +0 -0
  43. data/doc/ganalysis/doc/images/bullet_toggle_plus.png +0 -0
  44. data/doc/ganalysis/doc/images/date.png +0 -0
  45. data/doc/ganalysis/doc/images/find.png +0 -0
  46. data/doc/ganalysis/doc/images/loadingAnimation.gif +0 -0
  47. data/doc/ganalysis/doc/images/macFFBgHack.png +0 -0
  48. data/doc/ganalysis/doc/images/package.png +0 -0
  49. data/doc/ganalysis/doc/images/page_green.png +0 -0
  50. data/doc/ganalysis/doc/images/page_white_text.png +0 -0
  51. data/doc/ganalysis/doc/images/page_white_width.png +0 -0
  52. data/doc/ganalysis/doc/images/plugin.png +0 -0
  53. data/doc/ganalysis/doc/images/ruby.png +0 -0
  54. data/doc/ganalysis/doc/images/tag_green.png +0 -0
  55. data/doc/ganalysis/doc/images/wrench.png +0 -0
  56. data/doc/ganalysis/doc/images/wrench_orange.png +0 -0
  57. data/doc/ganalysis/doc/images/zoom.png +0 -0
  58. data/doc/ganalysis/doc/index.html +383 -0
  59. data/doc/ganalysis/doc/js/darkfish.js +118 -0
  60. data/doc/ganalysis/doc/js/jquery.js +32 -0
  61. data/doc/ganalysis/doc/js/quicksearch.js +114 -0
  62. data/doc/ganalysis/doc/js/thickbox-compressed.js +10 -0
  63. data/doc/ganalysis/doc/rdoc.css +763 -0
  64. data/ext/numru/gphys/ext_init.c +1 -0
  65. data/ext/numru/gphys/quad_mesh_sample.c +478 -0
  66. data/gphys.gemspec +2 -2
  67. data/lib/numru/dclext.rb +394 -14
  68. data/lib/numru/derivative.rb +6 -0
  69. data/lib/numru/ganalysis/qg.rb +6 -4
  70. data/lib/numru/ggraph.rb +41 -8
  71. data/lib/numru/gphys/gphys.rb +62 -14
  72. data/lib/numru/gphys/gphys_io.rb +4 -4
  73. data/lib/numru/gphys/version.rb +2 -2
  74. metadata +84 -79
  75. data/.gitignore +0 -14
  76. data/TODO_ep_flux +0 -6
  77. data/gphys-bigmem.gemspec +0 -44
  78. data/install.rb +0 -130
  79. data/sample/cira86_to_nc.rb +0 -122
  80. data/sample/druby_cli1.rb +0 -23
  81. data/sample/druby_cli2.rb +0 -28
  82. data/sample/druby_serv1.rb +0 -30
  83. data/sample/druby_serv2.rb +0 -51
  84. data/sample/ep_flux/demo_NCEP_1.rb +0 -48
  85. data/sample/ep_flux/demo_NCEP_2.rb +0 -57
  86. data/sample/ep_flux/demo_NCEP_3.rb +0 -81
  87. data/sample/ggraph_latlon_labelling_dr002690.rb +0 -159
  88. data/sample/ggraph_mapfit-axes_dr002687.rb +0 -131
  89. data/sample/map_projection.rb +0 -121
  90. data/sample/ncep_theta_coord.rb +0 -79
  91. data/test_old/eof_slp.rb +0 -28
  92. data/test_old/mltbit.dat +0 -0
  93. data/test_old/test_ep_flux.rb +0 -533
  94. data/test_old/test_multibitIO.rb +0 -19
@@ -5,4 +5,5 @@ Init_gphys_ext()
5
5
  init_gphys_interpo();
6
6
  init_gphys_multibitIO();
7
7
  init_gphys_dim_op();
8
+ init_gphys_quad_mesh_sample();
8
9
  }
@@ -0,0 +1,478 @@
1
+ /**
2
+ * Sample an arbitrary quadrilateral mesh with an equally spaced regular grid.
3
+ */
4
+
5
+ #include<stdio.h>
6
+ #include <math.h>
7
+ #include "ruby.h"
8
+ #include "narray.h"
9
+
10
+ #ifndef NARRAY_BIGMEM
11
+ typedef int na_shape_t;
12
+ #endif
13
+
14
+ static double Eps = 1e-10;
15
+
16
+ // sort three pairs of x&y by x
17
+ void sort3pairs(double ax, double bx, double cx, // in
18
+ double ay, double by, double cy, // in
19
+ double *x3, double *y3) // out (len=3, alreadt allocated)
20
+ {
21
+ if ( ax <= bx && ax <= cx ) {
22
+ x3[0]=ax; y3[0]=ay;
23
+ if ( bx <= cx ) {
24
+ x3[1]=bx; y3[1]=by; x3[2]=cx; y3[2]=cy;
25
+ } else {
26
+ x3[1]=cx; y3[1]=cy; x3[2]=bx; y3[2]=by;
27
+ }
28
+ } else if ( bx <= cx ) {
29
+ x3[0]=bx; y3[0]=by;
30
+ if ( ax <= cx ) {
31
+ x3[1]=ax; y3[1]=ay; x3[2]=cx; y3[2]=cy;
32
+ } else {
33
+ x3[1]=cx; y3[1]=cy; x3[2]=ax; y3[2]=ay;
34
+ }
35
+ } else {
36
+ x3[0]=cx; y3[0]=cy;
37
+ if ( bx <= ax ) {
38
+ x3[1]=bx; y3[1]=by; x3[2]=ax; y3[2]=ay;
39
+ } else {
40
+ x3[1]=ax; y3[1]=ay; x3[2]=bx; y3[2]=by;
41
+ }
42
+ }
43
+ }
44
+
45
+ static int idxceil(double x, int limit)
46
+ {
47
+ int idx;
48
+ idx = ceil(x-Eps);
49
+ idx = ( idx >= limit ? idx : limit );
50
+ return idx;
51
+ }
52
+
53
+ static int idxfloor(double x, int limit)
54
+ {
55
+ int idx;
56
+ idx = floor(x+Eps);
57
+ idx = ( idx <= limit ? idx : limit );
58
+ return idx;
59
+ }
60
+
61
+ static double ycrossing(double x0, double x1, double y0, double y1, double x)
62
+ {
63
+ double yc = -999; // negative value considering the positive array indexing
64
+ if (x1!=x0) yc = y0 + (y1-y0)/(x1-x0)*(x-x0);
65
+ return yc;
66
+ }
67
+
68
+ // solve quadratic equation to return a solution which is likely between 0 and 1
69
+ // (if both solutions are between 0 and 1, arbitrary one of them is returned).
70
+ static double solv_quad_0to1(double a, double b, double c){
71
+ double x;
72
+ if ( a == 0 ) {
73
+ if (b == 0){
74
+ return 0.5; // no solution. return a moderate val
75
+ } else {
76
+ return -c/b;
77
+ }
78
+ }
79
+ if ( b*b - 4*a*c < 0) {
80
+ return 0.5; // no solution. return a moderate val
81
+ } else if ( b*b < Eps*fabs(4*a*c) ){ // b ~ 0
82
+ if ( c/a < 0) {
83
+ return 0.5; // likely due to a round-off error
84
+ } else {
85
+ return sqrt(c/a); // must be positive to be between 0 and 1
86
+ }
87
+ } else if ( fabs(4*a*c) < Eps*b*b ) {
88
+ // a ~ 0 or c ~ 0 : determinant is vulnerable to round-off error
89
+ // Taylor expansion -> solutions are -c/b or -b/a+c/b (usu big)
90
+ x = -b/a+c/b;
91
+ if ( x >= -Eps && x <= 1+Eps ) { // rare case
92
+ return x;
93
+ } else {
94
+ return -c/b;
95
+ }
96
+ } else {
97
+ x = ( -b + sqrt(b*b - 4*a*c) ) / (2*a) ;
98
+ if ( x >= -Eps && x <= 1+Eps ) {
99
+ return x;
100
+ } else {
101
+ x = ( -b - sqrt(b*b - 4*a*c) ) / (2*a) ;
102
+ return x;
103
+ }
104
+ }
105
+ }
106
+
107
+ /*
108
+ * Initialize a quadrilateral mesh sampling with an equally-spaced regular grid
109
+ *
110
+ * Prepare for the call of quad_mesh_sample.
111
+ * Using a transformed bilinear interpolation.
112
+ *
113
+ * (IN)
114
+ * * x, y: one-dimensionalized 2D array of ns(minor) * nr (major).
115
+ * Coordinate values of the field value to sample
116
+ * * nx, dx0, d_x: describes the regular grid of x: d0, d0+d_x,..,d0+(nx-1)*d_x.
117
+ * * ny, dy0, d_y: describes the regular grid of y: d0, d0+d_y,..,d0+(ny-1)*d_y.
118
+ * * handle_miss: if true (non zero), data missing in x and y are handled:
119
+ * not to sample if any one vertex of a surrounding quadrilateral is missing.
120
+ * (OUT)
121
+ * * si, ri: specifies the surrounding quadrilateral for the regular grid points
122
+ * * p, q: bilinear interpolation parameter, obtained from quadratic equations
123
+ * to support arbitrary quadrilaterals.
124
+ */
125
+
126
+ static void quad_mesh_sample_init(int ns, int nr, double *x, double *y, // (in)
127
+ int nx, double x0, double d_x, // (in)
128
+ int ny, double y0, double d_y, // (in)
129
+ int handle_miss, double misval, // (in)
130
+ int *si, int *ri, double *p, double *q) // (out)
131
+ {
132
+ int i, is, ir, ix, iy, j;
133
+ int iy0, iy1;
134
+ int imis=-1; // negative value as an invalid (missing) index
135
+ double ax, bx, cx, dx; // c d quadrilateral points
136
+ double ay, by, cy, dy; // a b normalized by x0, d_x, y0, d_y
137
+ double x3[3], y3[3]; // normalized triangle points sorted by x
138
+ double a0, a1, a2, a3, b0, b1 ,b2, b3, a, b, c, xi, yi;
139
+
140
+ //< array initialization >
141
+
142
+ for ( i=0 ; i<nx*ny ; i++ ){
143
+ si[i] = ri[i] = imis;
144
+ p[i] = q[i] = 0.0; // just to avoid non-initialization
145
+ }
146
+
147
+ //< find where each of x-y grid point is in the original mesh >
148
+
149
+ for ( ir=0 ; ir<nr-1 ; ir++ ){
150
+ for ( is=0 ; is<ns-1 ; is++ ){
151
+ if (handle_miss && ( x[is+ns*ir]==misval || x[is+1+ns*ir]==misval ||
152
+ x[is+ns*(ir+1)]==misval || x[is+1+ns*(ir+1)]==misval ||
153
+ y[is+ns*ir]==misval || y[is+1+ns*ir]==misval ||
154
+ y[is+ns*(ir+1)]==misval || y[is+1+ns*(ir+1)]==misval ) ) {
155
+ continue;
156
+ }
157
+
158
+ ax = (x[is + ns*ir] - x0)/d_x;
159
+ bx = (x[is+1 + ns*ir] - x0)/d_x;
160
+ cx = (x[is + ns*(ir+1)] - x0)/d_x;
161
+ dx = (x[is+1 + ns*(ir+1)] - x0)/d_x;
162
+ ay = (y[is + ns*ir] - y0)/d_y;
163
+ by = (y[is+1 + ns*ir] - y0)/d_y;
164
+ cy = (y[is + ns*(ir+1)] - y0)/d_y;
165
+ dy = (y[is+1 + ns*(ir+1)] - y0)/d_y;
166
+
167
+ for(j=0; j<2; j++) {
168
+ if (j==0) {
169
+ sort3pairs(ax, bx, cx, ay, by, cy, x3, y3); // first time
170
+ } else {
171
+ sort3pairs(dx, bx, cx, dy, by, cy, x3, y3); // second time
172
+ }
173
+ for(ix=idxceil(x3[0],0); ix<=idxfloor(x3[2],nx-1); ix++){
174
+ xi = (double) ix; // normalized x grid
175
+ if ( (x3[0]!=x3[1] && ix<=x3[1]) || x3[1]==x3[2] ){
176
+ // consider angle at x3[0],y3[0]
177
+ if ((x3[2]-x3[0])*(y3[1]-y3[0]) - (x3[1]-x3[0])*(y3[2]-y3[0]) < 0) {
178
+ iy0 = idxceil(ycrossing(x3[0],x3[1],y3[0],y3[1],xi), 0);
179
+ iy1 = idxfloor(ycrossing(x3[0],x3[2],y3[0],y3[2],xi), ny-1);
180
+ } else {
181
+ iy0 = idxceil(ycrossing(x3[0],x3[2],y3[0],y3[2],xi), 0);
182
+ iy1 = idxfloor(ycrossing(x3[0],x3[1],y3[0],y3[1],xi), ny-1);
183
+ }
184
+ } else {
185
+ // consider angle at x3[2],y3[2]
186
+ if ((x3[0]-x3[2])*(y3[1]-y3[2]) - (x3[1]-x3[2])*(y3[0]-y3[2]) > 0) {
187
+ iy0 = idxceil(ycrossing(x3[2],x3[1],y3[2],y3[1],xi), 0);
188
+ iy1 = idxfloor(ycrossing(x3[2],x3[0],y3[2],y3[0],xi), ny-1);
189
+ } else {
190
+ iy0 = idxceil(ycrossing(x3[2],x3[0],y3[2],y3[0],xi), 0);
191
+ iy1 = idxfloor(ycrossing(x3[2],x3[1],y3[2],y3[1],xi), ny-1);
192
+ }
193
+ }
194
+ for(iy=iy0; iy<=iy1; iy++){
195
+ si[ix + nx*iy] = is;
196
+ ri[ix + nx*iy] = ir;
197
+ }
198
+ }
199
+ }
200
+ }
201
+ }
202
+
203
+ //< interpolation point >
204
+
205
+ for (i=0; i<nx*ny; i++){
206
+ if (si[i] >= 0) { // then ri[i] >= 0
207
+ xi = (double) (i % nx); // normalized grid x val
208
+ yi = (double) (i / nx); // normalized grid y val
209
+
210
+ is = si[i];
211
+ ir = ri[i];
212
+ ax = (x[is + ns*ir] - x0)/d_x;
213
+ bx = (x[is+1 + ns*ir] - x0)/d_x;
214
+ cx = (x[is + ns*(ir+1)] - x0)/d_x;
215
+ dx = (x[is+1 + ns*(ir+1)] - x0)/d_x;
216
+ ay = (y[is + ns*ir] - y0)/d_y;
217
+ by = (y[is+1 + ns*ir] - y0)/d_y;
218
+ cy = (y[is + ns*(ir+1)] - y0)/d_y;
219
+ dy = (y[is+1 + ns*(ir+1)] - y0)/d_y;
220
+
221
+ // mapping xi = a0 + a1*p + a2*q + a3*p*q where p=0..1 & q=0..1
222
+ // yi = b0 + b1*p + b2*q + b3*p*q
223
+ a0 = ax; // x = ax when p=q=0
224
+ a1 = bx - ax; // x = bx when p=1 & q=0
225
+ a2 = cx - ax; // x = cx when p=0 & q=1
226
+ a3 = dx - bx -cx + ax; // x = dx when p=q=1
227
+ b0 = ay;
228
+ b1 = by - ay;
229
+ b2 = cy - ay;
230
+ b3 = dy - by -cy + ay;
231
+
232
+ // quadratic equation
233
+ a = a3*b2 - a2*b3;
234
+ b = -a3*yi + b3*xi +a3*b0 - a0*b3 + a1*b2 - a2*b1;
235
+ c = -a1*yi + b1*xi +a1*b0 - a0*b1;
236
+ q[i] = solv_quad_0to1(a, b, c);
237
+ if ( a1 + a3*q[i] != 0 ) {
238
+ p[i] = (xi - a2*q[i] - a0) / (a1 + a3*q[i]);
239
+ if (p[i] > 1.0) p[i]=1.0; // abnormal, likely due to round-off error
240
+ if (p[i] < 0.0) p[i]=0.0; // abnormal, likely due to round-off error
241
+ } else if ( b1 + b3*q[i] != 0 ) {
242
+ p[i] = (yi - b2*q[i] - b0) / (b1 + b3*q[i]);
243
+ if (p[i] > 1.0) p[i]=1.0; // abnormal, likely due to round-off error
244
+ if (p[i] < 0.0) p[i]=0.0; // abnormal, likely due to round-off error
245
+ } else {
246
+ p[i] = 0.5; //not uniq.
247
+ }
248
+ }
249
+ }
250
+
251
+ }
252
+
253
+ /*
254
+ * Conduct a quadrilateral mesh sampling with an equally-spaced regular grid
255
+ *
256
+ * Need to call quad_mesh_sample_init to set up.
257
+ *
258
+ * (IN)
259
+ * * z: The field value. One-dimensionalized 2D array of ns(minor) * nr (major).
260
+ * *si, ri, p, q: obtained from quad_mesh_sample_init
261
+ * (OUT)
262
+ * * zg: The interpolated field value.
263
+ * One-dimensionalized 2D array of nx (minor) * ny (major).
264
+ */
265
+
266
+ static void quad_mesh_sample(int ns, int nr, double *z, int nx, int ny, // (in)
267
+ int *si, int *ri, double *p, double *q, double misval, //(in)
268
+ double *zg) // (out)
269
+ {
270
+ int i, is, ir;
271
+ for (i=0; i<nx*ny; i++){
272
+ is = si[i];
273
+ ir = ri[i];
274
+ if (is >= 0 && ir >= 0) {
275
+ zg[i] = (1-p[i])*(1-q[i])*z[is+ns*ir]
276
+ + p[i]*(1-q[i])*z[is+1+ns*ir]
277
+ + (1-p[i])*q[i]*z[is+ns*(ir+1)]
278
+ + p[i]*q[i]*z[is+1+ns*(ir+1)];
279
+ } else {
280
+ zg[i] = misval;
281
+ }
282
+ }
283
+ }
284
+
285
+
286
+ ///////////////////////////////////////////////////////////////////////
287
+ // ruby interface
288
+ ///////////////////////////////////////////////////////////////////////
289
+ /*
290
+ * misval: nil or Numeric(Float)
291
+ */
292
+ VALUE rb_quad_mesh_sample_init(VALUE obj, VALUE x_na, VALUE y_na, // (in)
293
+ VALUE nx_i, VALUE x0_f, VALUE dx_f, // (in)
294
+ VALUE ny_i, VALUE y0_f, VALUE dy_f, // (in)
295
+ VALUE misval_f ) // (in)
296
+ {
297
+ VALUE si_na, ri_na, p_na, q_na; // (out)
298
+ int ns, nr, nx, ny, rank;
299
+ double *x, *y;
300
+ double x0, dx, y0, dy, misval;
301
+ int handle_miss;
302
+ int *si, *ri;
303
+ double *p, *q;
304
+ struct NARRAY *na;
305
+ na_shape_t sh[2];
306
+
307
+ if (!IsNArray(x_na)) rb_raise(rb_eTypeError, "1st arg (x) must be an NArray");
308
+ if (!IsNArray(y_na)) rb_raise(rb_eTypeError, "2nd arg (y) must be an NArray");
309
+
310
+ rank = NA_RANK(x_na);
311
+ if (rank != 2) rb_raise(rb_eArgError, "rank of x is not 2");
312
+ rank = NA_RANK(y_na);
313
+ if (rank != 2) rb_raise(rb_eArgError, "rank of x is not 2");
314
+
315
+ GetNArray( na_cast_object(x_na, NA_DFLOAT), na);
316
+ ns = na->shape[0];
317
+ nr = na->shape[1];
318
+ x = (double *) NA_PTR(na, 0);
319
+
320
+ GetNArray( na_cast_object(y_na, NA_DFLOAT), na);
321
+ if ( ns != na->shape[0] || nr != na->shape[1])
322
+ rb_raise(rb_eArgError, "shapes of x and y do not agree");
323
+ y = (double *) NA_PTR(na, 0);
324
+
325
+ nx = NUM2INT( nx_i );
326
+ ny = NUM2INT( ny_i );
327
+ x0 = NUM2DBL( x0_f );
328
+ dx = NUM2DBL( dx_f );
329
+ y0 = NUM2DBL( y0_f );
330
+ dy = NUM2DBL( dy_f );
331
+
332
+ handle_miss = misval_f != Qnil;
333
+ if (handle_miss) {
334
+ misval = NUM2DBL( misval_f );
335
+ } else {
336
+ misval_f = 0.0; // just to avoid non-nitialization
337
+ }
338
+
339
+ sh[0] = (na_shape_t) nx;
340
+ sh[1] = (na_shape_t) ny;
341
+ si_na = na_make_object(NA_LINT, 2, sh, cNArray);
342
+ si = NA_PTR_TYPE(si_na, int *);
343
+ ri_na = na_make_object(NA_LINT, 2, sh, cNArray);
344
+ ri = NA_PTR_TYPE(ri_na, int *);
345
+ p_na = na_make_object(NA_DFLOAT, 2, sh, cNArray);
346
+ p = NA_PTR_TYPE(p_na, double *);
347
+ q_na = na_make_object(NA_DFLOAT, 2, sh, cNArray);
348
+ q = NA_PTR_TYPE(q_na, double *);
349
+
350
+ quad_mesh_sample_init(ns, nr, x, y, nx, x0, dx, ny, y0, dy, // (in)
351
+ handle_miss, misval, // (in)
352
+ si, ri, p, q);
353
+
354
+ return rb_ary_new3(4, si_na, ri_na, p_na, q_na);
355
+ }
356
+
357
+ VALUE rb_quad_mesh_sample(VALUE obj, VALUE z_na, VALUE si_na, VALUE ri_na,
358
+ VALUE p_na, VALUE q_na, VALUE misval_f)
359
+ {
360
+ VALUE zg_na;
361
+ int ns, nr, nx, ny;
362
+ int *si, *ri;
363
+ double *p, *q, misval, *z, *zg;
364
+ struct NARRAY *na;
365
+ na_shape_t sh[2];
366
+
367
+ GetNArray( na_cast_object(z_na, NA_DFLOAT), na);
368
+ ns = na->shape[0];
369
+ nr = na->shape[1];
370
+ z = (double *) NA_PTR(na, 0);
371
+
372
+ GetNArray( na_cast_object(si_na, NA_DFLOAT), na);
373
+ nx = na->shape[0];
374
+ ny = na->shape[1];
375
+ si = NA_PTR_TYPE(si_na, int *);
376
+ ri = NA_PTR_TYPE(ri_na, int *);
377
+ p = NA_PTR_TYPE(p_na, double *);
378
+ q = NA_PTR_TYPE(q_na, double *);
379
+ misval = NUM2DBL( misval_f );
380
+
381
+ sh[0] = (na_shape_t) nx;
382
+ sh[1] = (na_shape_t) ny;
383
+ zg_na = na_make_object(NA_DFLOAT, 2, sh, cNArray);
384
+ zg = NA_PTR_TYPE(zg_na, double *);
385
+
386
+ quad_mesh_sample(ns, nr, z, nx, ny, si, ri, p, q, misval, zg);
387
+
388
+ return zg_na;
389
+ }
390
+
391
+ void
392
+ init_gphys_quad_mesh_sample()
393
+ {
394
+ static VALUE mNumRu;
395
+ static VALUE cGPhys;
396
+ mNumRu = rb_define_module("NumRu");
397
+ cGPhys = rb_define_class_under(mNumRu, "GPhys", rb_cObject);
398
+ rb_define_singleton_method(cGPhys, "quad_mesh_sample_init",
399
+ rb_quad_mesh_sample_init, 9);
400
+ rb_define_singleton_method(cGPhys, "quad_mesh_sample",
401
+ rb_quad_mesh_sample, 6);
402
+ }
403
+
404
+ /*
405
+ ///////////////////////////////////////////////////////////////////////
406
+ // gcc -Wall -DTESTMAIN -lm -g quad_mesh_sample.c
407
+ ///////////////////////////////////////////////////////////////////////
408
+ #ifdef TESTMAIN
409
+ #include <stdlib.h>
410
+
411
+ int main(int argc, char *argv[]) {
412
+ int ns=21, nr=6; // sizes of the original quadrilateral mesh
413
+ // (ns:minor, nr:major)
414
+ int nx=25, ny=25; // sizes of the regular grid to resample(nx:minor, ny:major)
415
+ double x[ns*nr], y[ns*nr]; // the mesh
416
+ double z[ns*nr], zg[nx*ny]; // orig & resampled values
417
+ double x0=-nr, dx=0.5, y0=-nr, dy=0.5;
418
+ int si[nx*ny], ri[nx*ny];
419
+ double p[nx*ny], q[nx*ny];
420
+ int is,ir,i;
421
+ double r, d, theta, misval=99.99;
422
+
423
+ // polar coordinate
424
+ d = 2.0 * M_PI / (ns - 1.0);
425
+ for ( ir=0 ; ir<nr ; ir++ ){
426
+ r = (double) ir;
427
+ for ( is=0 ; is<ns ; is++ ){
428
+ theta = d*is;
429
+ x[is + ns*ir] = r * cos(theta);
430
+ y[is + ns*ir] = r * sin(theta);
431
+ z[is + ns*ir] = 0.1 * sqrt(r) * sin(2*theta); // wavenum-2 field
432
+ }
433
+ }
434
+
435
+ // prep
436
+ quad_mesh_sample_init(ns, nr, x, y, nx, x0, dx, ny, y0, dy, // (in)
437
+ 0, 0.0, // (in)
438
+ si, ri, p, q);
439
+
440
+ printf("si\n");
441
+ printf(" "); for(i=0;i<nx;i++) printf(" %2d",i);
442
+ printf("\n %2d:",0);
443
+ for (i=0; i<nx*ny; i++){
444
+ printf("%3d",si[i]);
445
+ if ( (i+1) % nx == 0) printf("\n %2d:",(i+1)/nx);
446
+ }
447
+ printf("\nri\n %2d:",0);
448
+ for (i=0; i<nx*ny; i++){
449
+ printf("%3d",ri[i]);
450
+ if ( (i+1) % nx == 0) printf("\n %2d:",(i+1)/nx);
451
+ }
452
+ printf("\n");
453
+
454
+ printf("\nq\n %2d:",0);
455
+ for (i=0; i<nx*ny; i++){
456
+ printf("%5.2f",q[i]);
457
+ if ( (i+1) % nx == 0) printf("\n %2d:",(i+1)/nx);
458
+ }
459
+ printf("\n");
460
+ printf("\np\n %2d:",0);
461
+ for (i=0; i<nx*ny; i++){
462
+ printf("%5.2f",p[i]);
463
+ if ( (i+1) % nx == 0) printf("\n %2d:",(i+1)/nx);
464
+ }
465
+ printf("\n");
466
+
467
+ quad_mesh_sample(ns, nr, z, nx, ny, si, ri, p, q, misval, zg);
468
+
469
+ printf("\nzg\n %2d:",0);
470
+ for (i=0; i<nx*ny; i++){
471
+ printf("%5.2f",zg[i]);
472
+ if ( (i+1) % nx == 0) printf("\n %2d:",(i+1)/nx);
473
+ }
474
+
475
+ return 0;
476
+ }
477
+ #endif
478
+ */