tioga 1.6 → 1.7

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 (41) hide show
  1. data/Tioga_README +35 -10
  2. data/split/Dvector/dvector.c +264 -22
  3. data/split/Dvector/lib/Dvector_extras.rb +30 -2
  4. data/split/Flate/extconf.rb +1 -1
  5. data/split/Function/function.c +112 -2
  6. data/split/Tioga/figures.c +76 -77
  7. data/split/Tioga/figures.h +375 -490
  8. data/split/Tioga/generic.c +254 -0
  9. data/split/Tioga/generic.h +236 -0
  10. data/split/Tioga/init.c +434 -320
  11. data/split/Tioga/lib/Creating_Paths.rb +11 -1
  12. data/split/Tioga/lib/FigMkr.rb +263 -65
  13. data/split/Tioga/lib/Legends.rb +4 -2
  14. data/split/Tioga/lib/Markers.rb +3 -2
  15. data/split/Tioga/lib/Special_Paths.rb +22 -23
  16. data/split/Tioga/lib/TeX_Text.rb +79 -1
  17. data/split/Tioga/lib/TexPreamble.rb +14 -0
  18. data/split/Tioga/lib/Utils.rb +5 -1
  19. data/split/Tioga/pdfs.h +7 -45
  20. data/split/Tioga/{axes.c → shared/axes.c} +210 -197
  21. data/split/Tioga/{makers.c → shared/makers.c} +442 -211
  22. data/split/Tioga/{pdf_font_dicts.c → shared/pdf_font_dicts.c} +0 -0
  23. data/split/Tioga/shared/pdfcolor.c +628 -0
  24. data/split/Tioga/shared/pdfcoords.c +443 -0
  25. data/split/Tioga/{pdffile.c → shared/pdffile.c} +56 -52
  26. data/split/Tioga/{pdfimage.c → shared/pdfimage.c} +103 -211
  27. data/split/Tioga/shared/pdfpath.c +766 -0
  28. data/split/Tioga/{pdftext.c → shared/pdftext.c} +121 -99
  29. data/split/Tioga/shared/texout.c +524 -0
  30. data/split/Tioga/wrappers.c +489 -0
  31. data/split/Tioga/wrappers.h +259 -0
  32. data/split/extconf.rb +4 -0
  33. data/split/mkmf2.rb +12 -1
  34. data/tests/benchmark_dvector_reads.rb +112 -0
  35. data/tests/tc_Dvector.rb +35 -3
  36. data/tests/tc_Function.rb +32 -0
  37. metadata +65 -52
  38. data/split/Tioga/pdfcolor.c +0 -486
  39. data/split/Tioga/pdfcoords.c +0 -523
  40. data/split/Tioga/pdfpath.c +0 -913
  41. data/split/Tioga/texout.c +0 -380
@@ -1,6 +1,7 @@
1
1
  /* makers.c */
2
2
  /*
3
3
  Copyright (C) 2005 Bill Paxton
4
+ Copyright (C) 2007 Taro Sato
4
5
 
5
6
  This file is part of Tioga.
6
7
 
@@ -20,101 +21,233 @@
20
21
  */
21
22
 
22
23
  #include "figures.h"
24
+ #include "generic.h"
23
25
 
24
26
 
25
27
  /* Lines */
26
28
 
27
- void c_private_make_spline_interpolated_points(FM *p, VALUE Xvec, VALUE Yvec, VALUE Xvec_data, VALUE Yvec_data,
28
- int start_clamped, double start_slope, int end_clamped, double end_slope) {
29
- int i, n_pts_data;
30
- double *As, *Bs, *Cs, *Ds;
31
- long xlen, ylen, xdlen, ydlen;
32
- double *Xs = Dvector_Data_for_Write(Xvec, &xlen);
33
- double *Ys = Dvector_Data_for_Write(Yvec, &ylen);
34
- double *X_data = Dvector_Data_for_Read(Xvec_data, &xdlen);
35
- double *Y_data = Dvector_Data_for_Read(Yvec_data, &ydlen);
36
- if (Xs == NULL || Ys == NULL || X_data == NULL || Y_data == NULL || xdlen != ydlen) {
37
- rb_raise(rb_eArgError, "Sorry: bad args for make_curves");
38
- }
39
- if (xlen == 0) return;
40
- n_pts_data = xdlen;
41
- As = Y_data;
42
- Bs = (double *)ALLOC_N(double, n_pts_data);
43
- Cs = (double *)ALLOC_N(double, n_pts_data);
44
- Ds = (double *)ALLOC_N(double, n_pts_data);
45
- c_dvector_create_spline_interpolant(n_pts_data, X_data, Y_data,
46
- start_clamped, start_slope, end_clamped, end_slope, Bs, Cs, Ds);
47
- Ys = Dvector_Data_Resize(Yvec, xlen);
48
- for (i = 0; i < xlen; i++)
49
- Ys[i] = c_dvector_spline_interpolate(Xs[i], n_pts_data, X_data, As, Bs, Cs, Ds);
50
- free(Ds); free(Cs); free(Bs);
51
- USE_P
29
+ static void create_spline_interpolant(int n_pts_data, double *Xs, double *Ys,
30
+ bool start_clamped, double start_slope, bool end_clamped, double end_slope,
31
+ double *As, double *Bs, double *Cs)
32
+ // this is copied from dvector so that makers.c won't depend on dvectors.
33
+ {
34
+ double *Hs = ALLOC_N_double(n_pts_data);
35
+ double *alphas = ALLOC_N_double(n_pts_data);
36
+ double *Ls = ALLOC_N_double(n_pts_data);
37
+ double *mu_s = ALLOC_N_double(n_pts_data);
38
+ double *Zs = ALLOC_N_double(n_pts_data);
39
+ int n = n_pts_data-1, i, j;
40
+ for (i=0; i < n; i++)
41
+ Hs[i] = Xs[i+1] - Xs[i];
42
+ if (start_clamped) alphas[0] = 3.0*(Ys[1]-Ys[0])/Hs[0] - 3.0*start_slope;
43
+ if (end_clamped) alphas[n] = 3.0*end_slope - 3.0*(Ys[n]-Ys[n-1])/Hs[n-1];
44
+ for (i=1; i < n; i++)
45
+ alphas[i] = 3.0*(Ys[i+1]*Hs[i-1]-Ys[i]*(Xs[i+1]-Xs[i-1])+Ys[i-1]*Hs[i])/(Hs[i-1]*Hs[i]);
46
+ if (start_clamped) { Ls[0] = 2.0*Hs[0]; mu_s[0] = 0.5; Zs[0] = alphas[0]/Ls[0]; }
47
+ else { Ls[0] = 1.0; mu_s[0] = 0.0; Zs[0] = 0.0; }
48
+ for (i = 1; i < n; i++) {
49
+ Ls[i] = 2.0*(Xs[i+1]-Xs[i-1]) - Hs[i-1]*mu_s[i-1];
50
+ mu_s[i] = Hs[i]/Ls[i];
51
+ Zs[i] = (alphas[i] - Hs[i-1]*Zs[i-1])/Ls[i];
52
52
  }
53
-
54
- VALUE FM_private_make_spline_interpolated_points(VALUE fmkr, VALUE Xvec, VALUE Yvec, VALUE Xvec_data, VALUE Yvec_data,
55
- VALUE start_slope, VALUE end_slope) {
56
- FM *p = Get_FM(fmkr);
57
- bool start_clamped = (start_slope != Qnil), end_clamped = (end_slope != Qnil);
58
- double start=0, end=0;
59
- if (start_clamped) {
60
- start_slope = rb_Float(start_slope);
61
- start = NUM2DBL(start_slope);
53
+ if (end_clamped) {
54
+ Ls[n] = Hs[n-1]*(2.0-mu_s[n-1]);
55
+ Bs[n] = Zs[n] = (alphas[n]-Hs[n-1]*Zs[n-1])/Ls[n];
62
56
  }
63
- if (end_clamped) {
64
- end_slope = rb_Float(end_slope);
65
- end = NUM2DBL(end_slope);
57
+ else { Ls[n] = 1.0; Zs[n] = 0.0; Bs[n] = 0.0; }
58
+ for (j = n-1; j >= 0; j--) {
59
+ Bs[j] = Zs[j] - mu_s[j]*Bs[j+1];
60
+ Cs[j] = (Ys[j+1]-Ys[j])/Hs[j] - Hs[j]*(Bs[j+1]+2.0*Bs[j])/3.0;
61
+ As[j] = (Bs[j+1]-Bs[j])/(3.0*Hs[j]);
66
62
  }
67
- c_private_make_spline_interpolated_points(p, Xvec, Yvec, Xvec_data, Yvec_data,
68
- start_clamped, start, end_clamped, end);
69
- return fmkr;
63
+ free(Zs); free(mu_s); free(Ls); free(alphas); free(Hs);
64
+ }
65
+
66
+ static double spline_interpolate(double x, int n_pts_data,
67
+ double *Xs, double *Ys, double *As, double *Bs, double *Cs)
68
+ // this is copied from dvector so that makers.c won't depend on dvectors.
69
+ {
70
+ int j;
71
+ for (j = 0; j < n_pts_data && x >= Xs[j]; j++);
72
+ if (j == n_pts_data) return Ys[j-1];
73
+ if (j == 0) return Ys[0];
74
+ j--;
75
+ double dx = x - Xs[j];
76
+ return Ys[j] + dx*(Cs[j] + dx*(Bs[j] + dx*As[j]));
77
+ }
78
+
79
+
80
+ OBJ_PTR c_private_make_spline_interpolated_points(OBJ_PTR fmkr, FM *p,
81
+ OBJ_PTR Xvec, OBJ_PTR Xvec_data, OBJ_PTR Yvec_data,
82
+ OBJ_PTR start_slope, OBJ_PTR end_slope, int *ierr) {
83
+
84
+ bool start_clamped = (start_slope != OBJ_NIL), end_clamped = (end_slope != OBJ_NIL);
85
+ long xlen;
86
+ double start=0, end=0, *Ys;
87
+ double *Xs = Vector_Data_for_Read(Xvec, &xlen, ierr);
88
+ if (*ierr != 0) RETURN_NIL;
89
+ OBJ_PTR Yvec;
90
+
91
+ if (start_clamped) start = Number_to_double(start_slope, ierr);
92
+ if (end_clamped) end = Number_to_double(end_slope, ierr);
93
+ if (*ierr != 0) RETURN_NIL;
94
+
95
+ Ys = ALLOC_N_double(xlen); // Ys are same length as Xs
96
+
97
+ int i, n_pts_data;
98
+ double *As, *Bs, *Cs, *Ds;
99
+ long xdlen, ydlen;
100
+ double *X_data = Vector_Data_for_Read(Xvec_data, &xdlen, ierr);
101
+ if (*ierr != 0) RETURN_NIL;
102
+ double *Y_data = Vector_Data_for_Read(Yvec_data, &ydlen, ierr);
103
+ if (*ierr != 0) RETURN_NIL;
104
+ if (Xs == NULL || Ys == NULL || X_data == NULL || Y_data == NULL || xdlen != ydlen) {
105
+ RAISE_ERROR("Sorry: bad args",ierr); RETURN_NIL;
106
+ }
107
+ if (xlen == 0) RETURN_NIL;
108
+ n_pts_data = xdlen;
109
+ As = Y_data;
110
+ Bs = ALLOC_N_double(n_pts_data);
111
+ Cs = ALLOC_N_double(n_pts_data);
112
+ Ds = ALLOC_N_double(n_pts_data);
113
+ create_spline_interpolant(n_pts_data, X_data, Y_data,
114
+ start_clamped, start, end_clamped, end, Bs, Cs, Ds);
115
+ for (i = 0; i < xlen; i++)
116
+ Ys[i] = spline_interpolate(Xs[i], n_pts_data, X_data, As, Bs, Cs, Ds);
117
+ free(Ds); free(Cs); free(Bs);
118
+ Yvec = Vector_New(xlen, Ys);
119
+ free(Ys);
120
+ return Yvec;
70
121
  }
71
122
 
72
- void c_make_steps(FM *p, VALUE Xvec, VALUE Yvec, VALUE Xvec_data, VALUE Yvec_data,
73
- double xfirst, double yfirst, double xlast, double ylast){
74
- double xnext, xprev, x;
75
- int n_pts_to_add;
76
- int i, j, n, old_length, new_length;
77
- long xlen, ylen, xdlen, ydlen;
78
- double *Xs = Dvector_Data_for_Write(Xvec, &xlen);
79
- double *Ys = Dvector_Data_for_Write(Yvec, &ylen);
80
- double *X_data = Dvector_Data_for_Read(Xvec_data, &xdlen);
81
- double *Y_data = Dvector_Data_for_Read(Yvec_data, &ydlen);
82
- if (Xs == NULL || Ys == NULL || X_data == NULL || Y_data == NULL
83
- || xdlen != ydlen || xlen != ylen) {
84
- rb_raise(rb_eArgError, "Sorry: bad args for make_steps");
123
+
124
+ /*
125
+ * Make points xs and ys to define a step function. x_data and y_data
126
+ * are arrays from which the step functions are generated. (xfirst,
127
+ * yfirst) and (xlast, ylast) are extra data points to fix the first
128
+ * and last steps. The x_data plus xfirst and xlast determine the
129
+ * widths of the steps. The y_data plus yfirst and ylast determine
130
+ * the height of the steps. For CENTERED justification, the steps
131
+ * occur at locations midway between the given x locations. For
132
+ * LEFT_JUSTIFIED, (x_data[i], y_data[i]) and (x_data[i], y_data[i+1])
133
+ * specifies where steps occurs. For RIGHT_JUSTIFIED, (x_data[i],
134
+ * y_data[i]) and (x_data[i], y_data[i-1]) specifies where steps
135
+ * occurs.
136
+ *
137
+ * Aug 24, 2007:
138
+ *
139
+ * TS added 'justification' to control the justification of steps.
140
+ * The use of [xy]first and [xy]last might need improvement.
141
+ */
142
+ static void
143
+ c_make_steps(FM *p,
144
+ long *xsteps_len_ptr, double **xs_ptr,
145
+ long *ysteps_len_ptr, double **ys_ptr,
146
+ OBJ_PTR xvec_data, OBJ_PTR yvec_data,
147
+ double xfirst, double yfirst, double xlast, double ylast,
148
+ int justification, int *ierr)
149
+ {
150
+ double xnext, xprev, x;
151
+ long i, j, length, xdlen, ydlen;
152
+ double *xs = NULL, *ys = NULL;
153
+ double *x_data = Vector_Data_for_Read(xvec_data, &xdlen, ierr);
154
+ if (*ierr != 0) return;
155
+ double *y_data = Vector_Data_for_Read(yvec_data, &ydlen, ierr);
156
+ if (*ierr != 0) return;
157
+ if (x_data == NULL || y_data == NULL || xdlen != ydlen) {
158
+ RAISE_ERROR("Sorry: bad args for make_steps", ierr);
159
+ return;
160
+ }
161
+
162
+ // allocate memory for arrays to be returned
163
+ length = 2 * (xdlen + 1) + ((justification != CENTERED) ? 1 : 0);
164
+
165
+ *xsteps_len_ptr = length;
166
+ xs = ALLOC_N_double(length);
167
+ *xs_ptr = xs;
168
+
169
+ *ysteps_len_ptr = length;
170
+ ys = ALLOC_N_double(length);
171
+ *ys_ptr = ys;
172
+
173
+ // fill the arrays
174
+ switch (justification) {
175
+ case CENTERED:
176
+ for (i = 0, j = 0; i <= xdlen; ++i, j += 2) {
177
+ xprev = (i == 0) ? xfirst : x_data[i - 1];
178
+ xnext = (i == xdlen) ? xlast : x_data[i];
179
+ x = 0.5 * (xprev + xnext);
180
+ xs[j] = xs[j + 1] = x;
85
181
  }
86
- n = xdlen;
87
- n_pts_to_add = 2*(n+1);
88
- old_length = xlen;
89
- new_length = old_length + n_pts_to_add;
90
- Xs = Dvector_Data_Resize(Xvec, new_length);
91
- Ys = Dvector_Data_Resize(Yvec, new_length);
92
- for (i = 0, j = 0; i <= n; i++, j += 2) {
93
- xprev = (i==0)? xfirst : X_data[i-1];
94
- xnext = (i==n)? xlast : X_data[i];
95
- x = 0.5*(xprev + xnext);
96
- Xs[j+old_length] = Xs[j+1+old_length] = x;
97
- }
98
- Ys[0] = yfirst;
99
- for (i = 0, j = 1; i < n; i++, j += 2) {
100
- Ys[j+old_length] = Ys[j+1+old_length] = Y_data[i];
101
- }
102
- Ys[n_pts_to_add-1+old_length] = ylast;
103
- USE_P
182
+ ys[0] = yfirst;
183
+ for (i = 0, j = 1; i < xdlen; ++i, j += 2) {
184
+ ys[j] = ys[j + 1] = y_data[i];
104
185
  }
105
-
106
- VALUE FM_private_make_steps(VALUE fmkr, VALUE Xvec, VALUE Yvec, VALUE Xvec_data, VALUE Yvec_data,
107
- VALUE xfirst, VALUE yfirst, VALUE xlast, VALUE ylast) {
108
- FM *p = Get_FM(fmkr);
109
- xfirst = rb_Float(xfirst);
110
- yfirst = rb_Float(yfirst);
111
- xlast = rb_Float(xlast);
112
- ylast = rb_Float(ylast);
113
- c_make_steps(p, Xvec, Yvec, Xvec_data, Yvec_data,
114
- NUM2DBL(xfirst), NUM2DBL(yfirst), NUM2DBL(xlast), NUM2DBL(ylast));
115
- return fmkr;
186
+ ys[length - 1] = ylast;
187
+ break;
188
+ case LEFT_JUSTIFIED:
189
+ xs[0] = xfirst;
190
+ for (i = 0, j = 1; i <= xdlen; ++i, j += 2) {
191
+ xs[j] = xs[j + 1] = (i == xdlen) ? xlast : x_data[i];
192
+ }
193
+ ys[0] = ys[1] = yfirst;
194
+ for (i = 0, j = 2; i < xdlen; ++i, j += 2) {
195
+ ys[j] = ys[j + 1] = y_data[i];
196
+ }
197
+ ys[length - 1] = ylast;
198
+ break;
199
+ case RIGHT_JUSTIFIED:
200
+ for (i = 0, j = 0; i <= xdlen; ++i, j += 2) {
201
+ xs[j] = xs[j + 1] = (i == 0) ? xfirst : x_data[i - 1];
202
+ }
203
+ xs[length - 1] = xlast;
204
+ ys[0] = yfirst;
205
+ for (i = 0, j = 1; i <= xdlen; ++i, j += 2) {
206
+ ys[j] = ys[j + 1] = (i == xdlen) ? ylast : y_data[i];
207
+ }
208
+ break;
209
+ default:
210
+ RAISE_ERROR_i("Sorry: unsupported justification specified (%d)",
211
+ justification, ierr);
212
+ return;
116
213
  }
117
214
 
215
+ /* TS: I don't understand the use of the macro USE_P here, which
216
+ translates to p = NULL; For now, I'll comment out. */
217
+ //USE_P
218
+ }
219
+
220
+
221
+ OBJ_PTR
222
+ c_private_make_steps(OBJ_PTR fmkr, FM *p, OBJ_PTR xvec_data, OBJ_PTR yvec_data,
223
+ double xfirst, double yfirst, double xlast, double ylast,
224
+ int justification, int *ierr)
225
+ {
226
+ OBJ_PTR xvec;
227
+ OBJ_PTR yvec;
228
+ OBJ_PTR pts_array;
229
+ long xsteps_len = 0, ysteps_len = 0;
230
+ double *xsteps_data = NULL, *ysteps_data = NULL;
231
+
232
+ c_make_steps(p, &xsteps_len, &xsteps_data, &ysteps_len, &ysteps_data,
233
+ xvec_data, yvec_data, xfirst, yfirst, xlast, ylast,
234
+ justification, ierr);
235
+ if (*ierr != 0) RETURN_NIL;
236
+
237
+ xvec = Vector_New(xsteps_len, xsteps_data);
238
+ yvec = Vector_New(ysteps_len, ysteps_data);
239
+ free(xsteps_data);
240
+ free(ysteps_data);
241
+
242
+ pts_array = Array_New(2);
243
+ Array_Store(pts_array, 0, xvec, ierr);
244
+ if (*ierr != 0) RETURN_NIL;
245
+ Array_Store(pts_array, 1, yvec, ierr);
246
+ if (*ierr != 0) RETURN_NIL;
247
+ return pts_array;
248
+ }
249
+
250
+
118
251
  /*
119
252
  CONREC: A Contouring Subroutine
120
253
  written by Paul Bourke
@@ -172,12 +305,18 @@ MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
172
305
  #define min(x,y) (x<y?x:y)
173
306
  #define max(x,y) (x>y?x:y)
174
307
 
175
- #define PUSH_POINT(x,y,j) { \
176
- Dvector_Store_Double(dest_xs, j, x); \
177
- Dvector_Store_Double(dest_ys, j, y); \
178
- j++; }
308
+ #define PUSH_POINT(x,y) { \
309
+ if (*dest_len_ptr >= *dest_sz_ptr) { \
310
+ *dest_sz_ptr += *dest_sz_ptr + 100; \
311
+ REALLOC_double(dest_xs_ptr,*dest_sz_ptr); \
312
+ REALLOC_double(dest_ys_ptr,*dest_sz_ptr); \
313
+ } \
314
+ (*dest_xs_ptr)[*dest_len_ptr] = x; \
315
+ (*dest_ys_ptr)[*dest_len_ptr] = y; \
316
+ (*dest_len_ptr)++; \
317
+ }
179
318
 
180
- int conrec(double **d,
319
+ static int conrec(double **d,
181
320
  int ilb,
182
321
  int iub,
183
322
  int jlb,
@@ -186,11 +325,14 @@ int conrec(double **d,
186
325
  double *y,
187
326
  int nc,
188
327
  double *z,
189
- VALUE dest_xs,
190
- VALUE dest_ys,
191
- VALUE gaps,
328
+ long *dest_len_ptr,
329
+ double **dest_xs_ptr,
330
+ double **dest_ys_ptr,
331
+ long *dest_sz_ptr,
332
+ OBJ_PTR gaps,
192
333
  double x_limit,
193
- double y_limit)
334
+ double y_limit,
335
+ int *ierr)
194
336
  // d ! matrix of data to contour
195
337
  // ilb,iub,jlb,jub ! index bounds of data matrix
196
338
  // x ! data matrix column coordinates
@@ -198,14 +340,14 @@ int conrec(double **d,
198
340
  // nc ! number of contour levels
199
341
  // z ! contour levels in increasing order
200
342
  {
201
- int num_pts = 0;
202
- double x_prev=0.0, y_prev=0.0;
203
- int m1,m2,m3,case_value;
204
- double dmin,dmax,x1=0.0,x2=0.0,y1=0.0,y2=0.0;
205
- register int i,j,k,m;
206
- double h[5];
207
- int sh[5];
208
- double xh[5],yh[5];
343
+ int num_pts = 0;
344
+ double x_prev=0.0, y_prev=0.0;
345
+ int m1,m2,m3,case_value;
346
+ double dmin,dmax,x1=0.0,x2=0.0,y1=0.0,y2=0.0;
347
+ register int i,j,k,m;
348
+ double h[5];
349
+ int sh[5];
350
+ double xh[5],yh[5];
209
351
  //===========================================================================
210
352
  // The indexing of im and jm should be noted as it has to start from zero
211
353
  // unlike the fortran counter part
@@ -390,10 +532,10 @@ double x_prev=0.0, y_prev=0.0;
390
532
  double dx = x1 - x_prev, dy = y1 - y_prev;
391
533
  if (dx < 0) dx = -dx; if (dy < 0) dy = -dy;
392
534
  if (num_pts == 0 || dx > x_limit || dy > y_limit) {
393
- if (num_pts > 0) rb_ary_push(gaps, INT2FIX(num_pts));
394
- PUSH_POINT(x1,y1,num_pts);
535
+ if (num_pts > 0) { Array_Push(gaps, Integer_New(num_pts), ierr); if (*ierr != 0) return 0; }
536
+ PUSH_POINT(x1,y1); num_pts++;
395
537
  }
396
- PUSH_POINT(x2,y2,num_pts);
538
+ PUSH_POINT(x2,y2); num_pts++;
397
539
  x_prev = x2; y_prev = y2;
398
540
  }
399
541
  }
@@ -426,26 +568,32 @@ double x_prev=0.0, y_prev=0.0;
426
568
  // globals to this file
427
569
  static int nx_1, ny_1, iGT, jGT, iLE, jLE;
428
570
 
429
- static void free_space_for_curve();
430
- static void get_space_for_curve();
571
+ static void free_space_for_curve(void);
572
+ static void get_space_for_curve(int *ierr);
431
573
  static void draw_the_contour(
432
- VALUE dest_xs,
433
- VALUE dest_ys,
434
- VALUE gaps);
574
+ long *dest_len_ptr,
575
+ double **dest_xs_ptr,
576
+ double **dest_ys_ptr,
577
+ long *dest_sz_ptr,
578
+ OBJ_PTR gaps,
579
+ int *ierr);
435
580
 
436
581
  static bool trace_contour(double z0,
437
582
  double *x,
438
583
  double *y,
439
- double **z,
584
+ double **z,
440
585
  double **legit,
441
- VALUE dest_xs,
442
- VALUE dest_ys,
443
- VALUE gaps);
586
+ long *dest_len_ptr,
587
+ double **dest_xs_ptr,
588
+ double **dest_ys_ptr,
589
+ long *dest_sz_ptr,
590
+ OBJ_PTR gaps,
591
+ int *iterr);
444
592
 
445
- static int FLAG(int ni, int nj, int ind);
593
+ static int FLAG(int ni, int nj, int ind, int *ierr);
446
594
  static int append_segment(double xr, double yr, double zr, double OKr,
447
595
  double xs, double ys, double zs, double OKs,
448
- double z0);
596
+ double z0, int *ierr);
449
597
 
450
598
  // Space for curve, shared by several routines
451
599
  static double *xcurve, *ycurve;
@@ -456,7 +604,7 @@ static bool curve_storage_exists = false;
456
604
 
457
605
 
458
606
  static void
459
- free_space_for_curve()
607
+ free_space_for_curve(void)
460
608
  {
461
609
  if (curve_storage_exists) {
462
610
  free(xcurve);
@@ -469,16 +617,16 @@ free_space_for_curve()
469
617
  }
470
618
 
471
619
  static void
472
- get_space_for_curve()
620
+ get_space_for_curve(int *ierr)
473
621
  {
474
622
  max_in_curve = INITIAL_CURVE_SIZE;
475
623
  if(curve_storage_exists) {
476
- rb_raise(rb_eArgError, "storage is messed up (internal error)");
477
- return; // will not execute
624
+ RAISE_ERROR("storage is messed up (internal error)", ierr);
625
+ return;
478
626
  }
479
- xcurve = ALLOC_N(double, max_in_curve);
480
- ycurve = ALLOC_N(double, max_in_curve);
481
- legitcurve = ALLOC_N(bool, max_in_curve);
627
+ xcurve = ALLOC_N_double(max_in_curve);
628
+ ycurve = ALLOC_N_double(max_in_curve);
629
+ legitcurve = ALLOC_N_bool(max_in_curve);
482
630
  curve_storage_exists = true;
483
631
  num_in_curve = 0;
484
632
  num_in_path = 0;
@@ -498,7 +646,6 @@ get_space_for_curve()
498
646
  // contour_space_later centimeters, starting with a space of
499
647
  // contour_space_first from the beginning of the trace.
500
648
  //
501
- // CONTOUR_VALUE MISSING_VALUE
502
649
  static void
503
650
  gr_contour(
504
651
  double *x,
@@ -508,21 +655,25 @@ gr_contour(
508
655
  int nx,
509
656
  int ny,
510
657
  double z0,
511
- VALUE dest_xs,
512
- VALUE dest_ys,
513
- VALUE gaps)
658
+ long *dest_len_ptr,
659
+ double **dest_xs_ptr,
660
+ double **dest_ys_ptr,
661
+ long *dest_sz_ptr,
662
+ OBJ_PTR gaps,
663
+ int *ierr)
514
664
  {
515
665
  register int i, j;
516
666
  // Test for errors
517
- if (nx <= 0) rb_raise(rb_eArgError, "nx<=0 (internal error)");
518
- if (ny <= 0) rb_raise(rb_eArgError, "ny<=0 (internal error)");
667
+ if (nx <= 0) { RAISE_ERROR("nx<=0 (internal error)", ierr); return; }
668
+ if (ny <= 0) { RAISE_ERROR("ny<=0 (internal error)", ierr); return; }
519
669
  // Save some globals
520
670
  nx_1 = nx - 1;
521
671
  ny_1 = ny - 1;
522
672
  // Clear all switches.
523
- FLAG(nx, ny, -1);
673
+ FLAG(nx, ny, -1, ierr);
524
674
  // Get space for the curve.
525
- get_space_for_curve();
675
+ get_space_for_curve(ierr);
676
+ if (*ierr != 0) return;
526
677
 
527
678
  // Search for a contour intersecting various places on the grid. Whenever
528
679
  // a contour is found to be between two grid points, call trace_contour()
@@ -553,7 +704,8 @@ gr_contour(
553
704
  jLE = j;
554
705
  iGT = i;
555
706
  jGT = j;
556
- trace_contour(z0, x, y, z, legit, dest_xs, dest_ys, gaps);
707
+ trace_contour(z0, x, y, z, legit, dest_len_ptr, dest_xs_ptr, dest_ys_ptr, dest_sz_ptr, gaps, ierr);
708
+ if (*ierr != 0) return;
557
709
  }
558
710
  // Space through legit points, that is, skipping through good
559
711
  // data looking for another island of bad data which will
@@ -576,10 +728,11 @@ gr_contour(
576
728
  jLE = j - 1;
577
729
  iGT = i;
578
730
  jGT = j;
579
- trace_contour(z0, x, y, z, legit, dest_xs, dest_ys, gaps);
731
+ trace_contour(z0, x, y, z, legit, dest_len_ptr, dest_xs_ptr, dest_ys_ptr, dest_sz_ptr, gaps, ierr);
732
+ if (*ierr != 0) return;
580
733
  }
581
734
  // space through legit points
582
- while (i > 0 && (legit == NULL || legit[i][j] != 0.0 && legit[i][ j - 1] != 0.0))
735
+ while (i > 0 && (legit == NULL || (legit[i][j] != 0.0 && legit[i][ j - 1] != 0.0)))
583
736
  i--;
584
737
  }
585
738
  }
@@ -596,10 +749,11 @@ gr_contour(
596
749
  jLE = j;
597
750
  iGT = i;
598
751
  jGT = j;
599
- trace_contour(z0, x, y, z, legit, dest_xs, dest_ys, gaps);
752
+ trace_contour(z0, x, y, z, legit, dest_len_ptr, dest_xs_ptr, dest_ys_ptr, dest_sz_ptr, gaps, ierr);
753
+ if (*ierr != 0) return;
600
754
  }
601
755
  // space through legit points
602
- while (j > 0 && (legit == NULL || legit[i][j] != 0.0 && legit[i + 1][ j] != 0.0))
756
+ while (j > 0 && (legit == NULL || (legit[i][j] != 0.0 && legit[i + 1][ j] != 0.0)))
603
757
  j--;
604
758
  }
605
759
  }
@@ -616,10 +770,11 @@ gr_contour(
616
770
  jLE = j + 1;
617
771
  iGT = i;
618
772
  jGT = j;
619
- trace_contour(z0, x, y, z, legit, dest_xs, dest_ys, gaps);
773
+ trace_contour(z0, x, y, z, legit, dest_len_ptr, dest_xs_ptr, dest_ys_ptr, dest_sz_ptr, gaps, ierr);
774
+ if (*ierr != 0) return;
620
775
  }
621
776
  // space through legit points
622
- while (i < nx_1 && (legit == NULL || legit[i][j] != 0.0 && legit[i][ j + 1] != 0.0))
777
+ while (i < nx_1 && (legit == NULL || (legit[i][j] != 0.0 && legit[i][ j + 1] != 0.0)))
623
778
  i++;
624
779
  }
625
780
  }
@@ -631,9 +786,12 @@ gr_contour(
631
786
  int flag_is_set;
632
787
  for (i = 1; i < nx; i++) {
633
788
  // trace a contour if it hits here
634
- flag_is_set = FLAG(i, j, 0);
635
- if (flag_is_set < 0)
636
- rb_raise(rb_eArgError, "ran out of storage (internal error)");
789
+ flag_is_set = FLAG(i, j, 0, ierr);
790
+ if (*ierr != 0) return;
791
+ if (flag_is_set < 0) {
792
+ RAISE_ERROR("ran out of storage (internal error)", ierr);
793
+ return;
794
+ }
637
795
  if (!flag_is_set
638
796
  && (legit == NULL || legit[i][j] != 0.0)
639
797
  && z[i][j] > z0
@@ -643,13 +801,14 @@ gr_contour(
643
801
  jLE = j;
644
802
  iGT = i;
645
803
  jGT = j;
646
- trace_contour(z0, x, y, z, legit, dest_xs, dest_ys, gaps);
804
+ trace_contour(z0, x, y, z, legit, dest_len_ptr, dest_xs_ptr, dest_ys_ptr, dest_sz_ptr, gaps, ierr);
805
+ if (*ierr != 0) return;
647
806
  }
648
807
  }
649
808
  }
650
809
  // Free up space.
651
810
  free_space_for_curve();
652
- FLAG(nx, ny, 2);
811
+ FLAG(nx, ny, 2, ierr);
653
812
  }
654
813
 
655
814
  // trace_contour() -- trace_contour a contour line with high values of z to
@@ -662,9 +821,12 @@ trace_contour(double z0,
662
821
  double *y,
663
822
  double **z,
664
823
  double **legit,
665
- VALUE dest_xs,
666
- VALUE dest_ys,
667
- VALUE gaps
824
+ long *dest_len_ptr,
825
+ double **dest_xs_ptr,
826
+ double **dest_ys_ptr,
827
+ long *dest_sz_ptr,
828
+ OBJ_PTR gaps,
829
+ int *ierr
668
830
  )
669
831
  {
670
832
  int i, ii, j, jj;
@@ -698,7 +860,8 @@ trace_contour(double z0,
698
860
 
699
861
  append_segment(x[iLE], y[jLE], z[iLE][jLE], (legit == NULL)? 1.0: legit[iLE][jLE],
700
862
  x[iGT], y[jGT], z[iGT][jGT], (legit == NULL)? 1.0: legit[iGT][jGT],
701
- z0);
863
+ z0, ierr);
864
+ if (*ierr != 0) return false;
702
865
  // Find the next point to check through a table lookup.
703
866
  locate = 3 * (jGT - jLE) + (iGT - iLE) + 4;
704
867
  i = iLE + i_test[locate];
@@ -707,27 +870,31 @@ trace_contour(double z0,
707
870
 
708
871
  // Did it hit an edge?
709
872
  if (i > nx_1 || i < 0 || j > ny_1 || j < 0) {
710
- draw_the_contour(dest_xs, dest_ys, gaps);
873
+ draw_the_contour(dest_len_ptr, dest_xs_ptr, dest_ys_ptr, dest_sz_ptr, gaps, ierr);
874
+ if (*ierr != 0) return false;
711
875
  return true; // all done
712
876
  }
713
877
 
714
878
  // Test if retracing an existing contour. See explanation
715
879
  // above, in grcntour(), just before search starts.
716
880
  if (locate == 5) {
717
- int already_set = FLAG(iGT, jGT, 1);
881
+ int already_set = FLAG(iGT, jGT, 1, ierr);
882
+ if (*ierr != 0) return false;
718
883
  if (already_set < 0) {
719
- rb_raise(rb_eArgError, "ran out of storage (internal error)");
884
+ RAISE_ERROR("ran out of storage (internal error)", ierr);
720
885
  return false;
721
886
  }
722
887
  if (already_set) {
723
- draw_the_contour(dest_xs, dest_ys, gaps);
888
+ draw_the_contour(dest_len_ptr, dest_xs_ptr, dest_ys_ptr, dest_sz_ptr, gaps, ierr);
889
+ if (*ierr != 0) return false;
724
890
  return true; // all done
725
891
  }
726
892
  }
727
893
 
728
894
  // Following new for 2.1.13
729
895
  if (legit != NULL && legit[i][j] == 0.0) {
730
- draw_the_contour(dest_xs, dest_ys, gaps);
896
+ draw_the_contour(dest_len_ptr, dest_xs_ptr, dest_ys_ptr, dest_sz_ptr, gaps, ierr);
897
+ if (*ierr != 0) return false;
731
898
  return true; // all done
732
899
  }
733
900
 
@@ -755,14 +922,16 @@ trace_contour(double z0,
755
922
  if (zcentre <= z0) {
756
923
  append_segment(x[iGT], y[jGT], z[iGT][jGT], (legit == NULL)? 1.0: legit[iGT][jGT],
757
924
  vx, vy, zcentre, legit_diag,
758
- z0);
925
+ z0, ierr);
926
+ if (*ierr != 0) return false;
759
927
  if (z[ii][jj] <= z0) {
760
928
  iLE = ii, jLE = jj;
761
929
  continue;
762
930
  }
763
931
  append_segment(x[ii], y[jj], z[ii][jj], (legit == NULL)? 1.0: legit[ii][jj],
764
932
  vx, vy, zcentre, legit_diag,
765
- z0);
933
+ z0, ierr);
934
+ if (*ierr != 0) return false;
766
935
  if (z[i][j] <= z0) {
767
936
  iGT = ii, jGT = jj;
768
937
  iLE = i, jLE = j;
@@ -770,24 +939,28 @@ trace_contour(double z0,
770
939
  }
771
940
  append_segment(x[i], y[j], z[i][j], (legit == NULL)? 1.0: legit[i][j],
772
941
  vx, vy, zcentre, legit_diag,
773
- z0);
942
+ z0, ierr);
943
+ if (*ierr != 0) return false;
774
944
  iGT = i, jGT = j;
775
945
  continue;
776
946
  }
777
947
  append_segment(vx, vy, zcentre, legit_diag,
778
948
  x[iLE], y[jLE], z[iLE][jLE], (legit == NULL)? 1.0: legit[iLE][jLE],
779
- z0);
949
+ z0, ierr);
950
+ if (*ierr != 0) return false;
780
951
  if (z[i][j] > z0) {
781
952
  iGT = i, jGT = j;
782
953
  continue;
783
954
  }
784
955
  append_segment(vx, vy, zcentre, legit_diag,
785
956
  x[i], y[j], z[i][j], (legit == NULL)? 1.0: legit[i][j],
786
- z0);
957
+ z0, ierr);
958
+ if (*ierr != 0) return false;
787
959
  if (z[ii][jj] <= z0) {
788
960
  append_segment(vx, vy, zcentre, legit_diag,
789
961
  x[ii], y[jj], z[ii][jj], (legit == NULL)? 1.0: legit[ii][jj],
790
- z0);
962
+ z0, ierr);
963
+ if (*ierr != 0) return false;
791
964
  iLE = ii;
792
965
  jLE = jj;
793
966
  continue;
@@ -804,12 +977,12 @@ static double xplot_last, yplot_last;
804
977
  static int
805
978
  append_segment(double xr, double yr, double zr, double OKr,
806
979
  double xs, double ys, double zs, double OKs,
807
- double z0)
980
+ double z0, int *ierr)
808
981
  {
809
- if (zr == zs) rb_raise(rb_eArgError, "Contouring problem: zr = zs, which is illegal");
982
+ if (zr == zs) { RAISE_ERROR("Contouring problem: zr = zs, which is illegal", ierr); return 0; }
810
983
  double frac = (zr - z0) / (zr - zs);
811
- if (frac < 0.0) rb_raise(rb_eArgError, "Contouring problem: frac < 0");
812
- if (frac > 1.0) rb_raise(rb_eArgError, "Contouring problem: frac > 1");
984
+ if (frac < 0.0) { RAISE_ERROR("Contouring problem: frac < 0", ierr); return 0; }
985
+ if (frac > 1.0) { RAISE_ERROR("Contouring problem: frac > 1", ierr); return 0; }
813
986
  double xplot = xr - frac * (xr - xs);
814
987
  double yplot = yr - frac * (yr - ys);
815
988
  // Avoid replot, which I suppose must be possible, given this code
@@ -820,17 +993,17 @@ append_segment(double xr, double yr, double zr, double OKr,
820
993
  // do this with an STL vector class
821
994
  max_in_curve *= 2;
822
995
  int i;
823
- double *tmp = ALLOC_N(double, num_in_curve);
996
+ double *tmp = ALLOC_N_double(num_in_curve);
824
997
  for (i = 0; i < num_in_curve; i++) tmp[i] = xcurve[i];
825
- free(xcurve); xcurve = ALLOC_N(double, max_in_curve);
998
+ free(xcurve); xcurve = ALLOC_N_double(max_in_curve);
826
999
  for (i = 0; i < num_in_curve; i++) xcurve[i] = tmp[i];
827
1000
  for (i = 0; i < num_in_curve; i++) tmp[i] = ycurve[i];
828
- free(ycurve); ycurve = ALLOC_N(double, max_in_curve);
1001
+ free(ycurve); ycurve = ALLOC_N_double(max_in_curve);
829
1002
  for (i = 0; i < num_in_curve; i++) ycurve[i] = tmp[i];
830
1003
  free(tmp);
831
- bool *tmpl = ALLOC_N(bool, num_in_curve);
1004
+ bool *tmpl = ALLOC_N_bool(num_in_curve);
832
1005
  for (i = 0; i < num_in_curve; i++) tmpl[i] = legitcurve[i];
833
- free(legitcurve); legitcurve = ALLOC_N(bool, max_in_curve);
1006
+ free(legitcurve); legitcurve = ALLOC_N_bool(max_in_curve);
834
1007
  for (i = 0; i < num_in_curve; i++) legitcurve[i] = tmpl[i];
835
1008
  free(tmpl);
836
1009
  }
@@ -852,13 +1025,15 @@ append_segment(double xr, double yr, double zr, double OKr,
852
1025
  // Draw contour stored in (xcurve[],ycurve[],legitcurve[]), possibly with
853
1026
  // labels (depending on global Label_contours).
854
1027
  //
855
- // CONTOUR_VALUE MISSING_VALUE
856
1028
  #define FACTOR 3.0 // contour must be FACTOR*len long to be labelled
857
1029
  static void
858
1030
  draw_the_contour(
859
- VALUE dest_xs,
860
- VALUE dest_ys,
861
- VALUE gaps)
1031
+ long *dest_len_ptr,
1032
+ double **dest_xs_ptr,
1033
+ double **dest_ys_ptr,
1034
+ long *dest_sz_ptr,
1035
+ OBJ_PTR gaps,
1036
+ int *ierr)
862
1037
  {
863
1038
  if (num_in_curve == 1) {
864
1039
  num_in_curve = 0;
@@ -868,13 +1043,16 @@ draw_the_contour(
868
1043
  for (i = 0, k = 0; i < num_in_curve; i++) {
869
1044
  if (legitcurve[i] == true) {
870
1045
  // PUSH_POINT does num_in_path++
871
- PUSH_POINT(xcurve[i],ycurve[i],num_in_path);
1046
+ PUSH_POINT(xcurve[i],ycurve[i]); num_in_path++;
872
1047
  } else {
873
- if (num_in_path > 0 && num_in_path != k) rb_ary_push(gaps, INT2FIX(num_in_path));
1048
+ if (num_in_path > 0 && num_in_path != k) {
1049
+ Array_Push(gaps, Integer_New(num_in_path), ierr);
1050
+ if (*ierr != 0) return;
1051
+ }
874
1052
  k = num_in_path;
875
1053
  }
876
1054
  }
877
- rb_ary_push(gaps, INT2FIX(num_in_path));
1055
+ Array_Push(gaps, Integer_New(num_in_path), ierr);
878
1056
  num_in_curve = 0;
879
1057
  }
880
1058
 
@@ -885,11 +1063,11 @@ draw_the_contour(
885
1063
  // if (ind == 1), check flag and then set it
886
1064
  // if (ind == 2), clear the flag storage space
887
1065
  // if (ind == 0), check flag, return value
888
- // RETURN VALUE: Normally, the flag value (0 or 1). If the storage is
1066
+ // RETURN value: Normally, the flag value (0 or 1). If the storage is
889
1067
  // exhausted, return a number <0.
890
1068
  #define NBITS 32
891
1069
  static int
892
- FLAG(int ni, int nj, int ind)
1070
+ FLAG(int ni, int nj, int ind, int *ierr)
893
1071
  {
894
1072
  static bool flag_storage_exists = false;
895
1073
  static unsigned long *flag, mask[NBITS];
@@ -899,10 +1077,10 @@ FLAG(int ni, int nj, int ind)
899
1077
  switch (ind) {
900
1078
  case -1:
901
1079
  // Allocate storage for flag array
902
- if (flag_storage_exists)
903
- rb_raise(rb_eArgError, "storage is messed up (internal error)");
1080
+ if (flag_storage_exists) {
1081
+ RAISE_ERROR("storage is messed up (internal error)", ierr); return 0; }
904
1082
  size = 1 + ni * nj / NBITS; // total storage array length
905
- flag = ALLOC_N(unsigned long, size);
1083
+ flag = ALLOC_N_unsigned_long(size);
906
1084
  // Create mask
907
1085
  mask[0] = 1;
908
1086
  for (i = 1; i < NBITS; i++)
@@ -913,14 +1091,14 @@ FLAG(int ni, int nj, int ind)
913
1091
  flag_storage_exists = true;
914
1092
  return 0;
915
1093
  case 2:
916
- if (!flag_storage_exists)
917
- rb_raise(rb_eArgError, "No flag storage exists");
1094
+ if (!flag_storage_exists) {
1095
+ RAISE_ERROR("No flag storage exists", ierr); return 0; }
918
1096
  free(flag);
919
1097
  flag_storage_exists = false;
920
1098
  return 0;
921
1099
  default:
922
- if (!flag_storage_exists)
923
- rb_raise(rb_eArgError, "No flag storage exists");
1100
+ if (!flag_storage_exists) {
1101
+ RAISE_ERROR("No flag storage exists", ierr); return 0; }
924
1102
  break;
925
1103
  }
926
1104
  // ind was not -1 or 2
@@ -946,44 +1124,97 @@ FLAG(int ni, int nj, int ind)
946
1124
 
947
1125
 
948
1126
 
949
- void c_make_contour(FM *p, VALUE dest_xs, VALUE dest_ys, VALUE gaps,
950
- VALUE xs, VALUE ys, VALUE zs_data, double z_level, VALUE legit_data, int use_conrec) {
951
- long xlen, ylen, num_columns, num_rows;
952
- double *x_coords = Dvector_Data_for_Read(xs, &xlen);
953
- double *y_coords = Dvector_Data_for_Read(ys, &ylen);
954
- double **zs = Dtable_Ptr(zs_data, &num_columns, &num_rows);
955
- double **legit = Dtable_Ptr(legit_data, &num_columns, &num_rows);
956
- if (x_coords == NULL || gaps == Qnil || zs == NULL || y_coords == NULL) {
957
- rb_raise(rb_eArgError, "Sorry: bad args for make_contour. Need to provide xs, ys, gaps, and zs.");
1127
+ static void c_make_contour(FM *p,
1128
+ long *dest_len_ptr,
1129
+ double **dest_xs_ptr,
1130
+ double **dest_ys_ptr,
1131
+ long *dest_sz_ptr,
1132
+ OBJ_PTR gaps,
1133
+ OBJ_PTR xs, OBJ_PTR ys,
1134
+ OBJ_PTR zs_data, double z_level,
1135
+ OBJ_PTR legit_data, int use_conrec, int *ierr) {
1136
+
1137
+ long xlen, ylen, num_zcolumns, num_zrows, num_columns, num_rows;
1138
+ double *x_coords = Vector_Data_for_Read(xs, &xlen, ierr);
1139
+ if (*ierr != 0) return;
1140
+ double *y_coords = Vector_Data_for_Read(ys, &ylen, ierr);
1141
+ if (*ierr != 0) return;
1142
+ double **zs = Table_Data_for_Read(zs_data, &num_zcolumns, &num_zrows, ierr);
1143
+ if (*ierr != 0) return;
1144
+ double **legit = Table_Data_for_Read(legit_data, &num_columns, &num_rows, ierr);
1145
+ if (*ierr != 0) return;
1146
+ double x_limit, y_limit;
1147
+
1148
+ if (x_coords == NULL || gaps == OBJ_NIL || zs == NULL || y_coords == NULL) {
1149
+ RAISE_ERROR("Sorry: bad args for make_contour. Need to provide xs, ys, gaps, and zs.", ierr); return;
958
1150
  }
959
1151
  if (xlen != num_columns || ylen != num_rows) {
960
- rb_raise(rb_eArgError, "Sorry: bad args for make_contour. Needs xs.size == num columns and ys.size == num rows.");
1152
+ RAISE_ERROR("Sorry: bad args for make_contour. Needs xs.size == num columns and ys.size == num rows.", ierr); return;
961
1153
  }
962
- double x_limit, y_limit;
963
- x_limit = 0.001*(x_coords[xlen-1] - x_coords[0])/xlen;
964
- if (x_limit < 0) x_limit = -x_limit;
965
- y_limit = 0.001*(y_coords[ylen-1] - y_coords[0])/ylen;
966
- if (y_limit < 0) y_limit = -y_limit;
967
-
968
- // NOTE: conrec data is TRANSPOSE of our data, so we switch x's and y's in the call
969
- if (use_conrec == 1)
970
- conrec(zs, 0, num_rows-1, 0, num_columns-1, y_coords, x_coords, 1, &z_level, dest_ys, dest_xs, gaps, y_limit, x_limit);
971
- else
972
- gr_contour(y_coords, x_coords, zs, legit, num_rows, num_columns, z_level, dest_ys, dest_xs, gaps);
1154
+ if (num_zcolumns != num_columns || num_zrows != num_rows) {
1155
+ RAISE_ERROR("Sorry: bad args for make_contour. Needs same dimension zs and legit flags.", ierr); return;
1156
+ }
1157
+
1158
+ // NOTE: contour data is TRANSPOSE of tioga data, so we switch x's and y's in the call
973
1159
 
1160
+ if (use_conrec == 1) {
1161
+ x_limit = 0.001*(x_coords[xlen-1] - x_coords[0])/xlen;
1162
+ if (x_limit < 0) x_limit = -x_limit;
1163
+ y_limit = 0.001*(y_coords[ylen-1] - y_coords[0])/ylen;
1164
+ if (y_limit < 0) y_limit = -y_limit;
1165
+ conrec(zs, 0, num_rows-1, 0, num_columns-1, y_coords, x_coords, 1, &z_level,
1166
+ dest_len_ptr, dest_ys_ptr, dest_xs_ptr, dest_sz_ptr, gaps, y_limit, x_limit, ierr);
1167
+ } else {
1168
+ gr_contour(y_coords, x_coords, zs, legit, num_rows, num_columns, z_level,
1169
+ dest_len_ptr, dest_ys_ptr, dest_xs_ptr, dest_sz_ptr, gaps, ierr);
1170
+ }
974
1171
  }
975
1172
 
976
- VALUE FM_private_make_contour(VALUE fmkr,
977
- VALUE dest_xs, VALUE dest_ys, VALUE gaps, // these Dvectors get the results
978
- VALUE xs, VALUE ys, // data x coordinates and y coordinates
979
- VALUE zs, VALUE z_level, // the Dtable of values and the desired contour level
980
- VALUE legit, // the Dtable of flags (nonzero means okay)
981
- VALUE method // int == 1 means CONREC
1173
+
1174
+ OBJ_PTR c_private_make_contour(OBJ_PTR fmkr, FM *p,
1175
+ OBJ_PTR gaps, // these vectors get the results
1176
+ OBJ_PTR xs, OBJ_PTR ys, // data x coordinates and y coordinates
1177
+ OBJ_PTR zs, double z_level, // the table of values and the desired contour level
1178
+ OBJ_PTR legit, // the table of flags (nonzero means okay)
1179
+ int method, // int == 1 means CONREC
1180
+ int *ierr
982
1181
  ) {
983
- FM *p = Get_FM(fmkr);
984
- z_level = rb_Float(z_level);
985
- c_make_contour(p, dest_xs, dest_ys, gaps, xs, ys, zs, NUM2DBL(z_level), legit, NUM2INT(method));
986
- return fmkr;
1182
+ /* uses Xvec_data and Yvec_data to create a cubic spline interpolant.
1183
+ once the spline interpolant is created, it is sampled at the n_pts_to_add in Xs.
1184
+ Xvec entry i is set to the value of the spline at Yvec entry i.
1185
+ Both the X_data and the Xs should be stored in ascending order.
1186
+ There is a boundary condition choice to be made for each end concerning the slope.
1187
+ If clamped is true, the corresponding slope argument value sets the slope.
1188
+ If clamped is false (known as a "free" or "natural" spline),
1189
+ the 2nd derivative is set to 0 and the slope is determined by the fit.
1190
+ In this case, the corresponding slope argument is ignored.
1191
+ */
1192
+ long dest_len, dest_sz;
1193
+ double *dest_xs_data;
1194
+ double *dest_ys_data;
1195
+ OBJ_PTR Xvec;
1196
+ OBJ_PTR Yvec;
1197
+ OBJ_PTR pts_array;
1198
+
1199
+ dest_len = 0; dest_sz = 3000;
1200
+ dest_xs_data = ALLOC_N_double(dest_sz);
1201
+ dest_ys_data = ALLOC_N_double(dest_sz);
1202
+
1203
+ c_make_contour(p, &dest_len, &dest_xs_data, &dest_ys_data, &dest_sz,
1204
+ gaps, xs, ys, zs, z_level, legit, method, ierr);
1205
+ if (*ierr != 0) RETURN_NIL;
1206
+
1207
+ Xvec = Vector_New(dest_len, dest_xs_data);
1208
+ Yvec = Vector_New(dest_len, dest_ys_data);
1209
+ free(dest_xs_data);
1210
+ free(dest_ys_data);
1211
+
1212
+ pts_array = Array_New(2);
1213
+ Array_Store(pts_array,0,Xvec,ierr);
1214
+ if (*ierr != 0) RETURN_NIL;
1215
+ Array_Store(pts_array,1,Yvec,ierr);
1216
+ if (*ierr != 0) RETURN_NIL;
1217
+ return pts_array;
987
1218
  }
988
1219
 
989
1220