tioga 1.4
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.
- data/Tioga_README +372 -0
- data/lgpl.txt +504 -0
- data/split/Dtable/defs.h +33 -0
- data/split/Dtable/dtable.c +1928 -0
- data/split/Dtable/dtable_intern.h +144 -0
- data/split/Dtable/dvector.h +61 -0
- data/split/Dtable/extconf.rb +4 -0
- data/split/Dtable/include/dtable.h +35 -0
- data/split/Dtable/lib/Dtable_extras.rb +90 -0
- data/split/Dtable/namespace.h +47 -0
- data/split/Dtable/safe_double.h +104 -0
- data/split/Dtable/symbols.c +92 -0
- data/split/Dtable/symbols.h +52 -0
- data/split/Dvector/defs.h +33 -0
- data/split/Dvector/dvector.c +5486 -0
- data/split/Dvector/dvector_intern.h +142 -0
- data/split/Dvector/extconf.rb +4 -0
- data/split/Dvector/include/dvector.h +61 -0
- data/split/Dvector/lib/Dvector_extras.rb +328 -0
- data/split/Dvector/lib/Numeric_extras.rb +134 -0
- data/split/Dvector/namespace.h +47 -0
- data/split/Dvector/safe_double.h +104 -0
- data/split/Dvector/symbols.c +92 -0
- data/split/Dvector/symbols.h +52 -0
- data/split/Flate/defs.h +33 -0
- data/split/Flate/extconf.rb +19 -0
- data/split/Flate/flate.c +156 -0
- data/split/Flate/flate_intern.h +97 -0
- data/split/Flate/include/flate.h +98 -0
- data/split/Flate/namespace.h +47 -0
- data/split/Flate/safe_double.h +104 -0
- data/split/Flate/symbols.c +92 -0
- data/split/Flate/symbols.h +52 -0
- data/split/Function/defs.h +33 -0
- data/split/Function/dvector.h +61 -0
- data/split/Function/extconf.rb +4 -0
- data/split/Function/function.c +988 -0
- data/split/Function/joint_qsort.c +258 -0
- data/split/Function/lib/Function_extras.rb +44 -0
- data/split/Function/namespace.h +47 -0
- data/split/Function/safe_double.h +104 -0
- data/split/Function/symbols.c +92 -0
- data/split/Function/symbols.h +52 -0
- data/split/Tioga/axes.c +774 -0
- data/split/Tioga/defs.h +33 -0
- data/split/Tioga/dtable.h +35 -0
- data/split/Tioga/dvector.h +61 -0
- data/split/Tioga/extconf.rb +4 -0
- data/split/Tioga/figures.c +672 -0
- data/split/Tioga/figures.h +855 -0
- data/split/Tioga/flate.h +98 -0
- data/split/Tioga/init.c +524 -0
- data/split/Tioga/lib/Arcs_and_Circles.rb +64 -0
- data/split/Tioga/lib/ColorConstants.rb +274 -0
- data/split/Tioga/lib/Colorbars.rb +10 -0
- data/split/Tioga/lib/Colormaps.rb +105 -0
- data/split/Tioga/lib/Coordinate_Conversions.rb +194 -0
- data/split/Tioga/lib/Creating_Paths.rb +94 -0
- data/split/Tioga/lib/Doc.rb +91 -0
- data/split/Tioga/lib/Executive.rb +515 -0
- data/split/Tioga/lib/FigMkr.rb +2224 -0
- data/split/Tioga/lib/FigureConstants.rb +125 -0
- data/split/Tioga/lib/Figures_and_Plots.rb +268 -0
- data/split/Tioga/lib/Images.rb +278 -0
- data/split/Tioga/lib/Legends.rb +190 -0
- data/split/Tioga/lib/MarkerConstants.rb +122 -0
- data/split/Tioga/lib/Markers.rb +129 -0
- data/split/Tioga/lib/Page_Frame_Bounds.rb +567 -0
- data/split/Tioga/lib/Rectangles.rb +94 -0
- data/split/Tioga/lib/Shading.rb +100 -0
- data/split/Tioga/lib/Special_Paths.rb +307 -0
- data/split/Tioga/lib/Strokes.rb +129 -0
- data/split/Tioga/lib/TeX_Text.rb +454 -0
- data/split/Tioga/lib/TexPreamble.rb +358 -0
- data/split/Tioga/lib/Titles_and_Labels.rb +306 -0
- data/split/Tioga/lib/Transparency.rb +89 -0
- data/split/Tioga/lib/Using_Paths.rb +164 -0
- data/split/Tioga/lib/Utils.rb +74 -0
- data/split/Tioga/lib/X_and_Y_Axes.rb +749 -0
- data/split/Tioga/lib/irb_tioga.rb +122 -0
- data/split/Tioga/lib/tioga.rb +1 -0
- data/split/Tioga/lib/tioga_ui.rb +5 -0
- data/split/Tioga/lib/tioga_ui_cmds.rb +793 -0
- data/split/Tioga/makers.c +989 -0
- data/split/Tioga/mk_tioga_sty.rb +53 -0
- data/split/Tioga/namespace.h +47 -0
- data/split/Tioga/pdf_font_dicts.c +18253 -0
- data/split/Tioga/pdfcolor.c +486 -0
- data/split/Tioga/pdfcoords.c +505 -0
- data/split/Tioga/pdffile.c +342 -0
- data/split/Tioga/pdfimage.c +536 -0
- data/split/Tioga/pdfpath.c +914 -0
- data/split/Tioga/pdfs.h +229 -0
- data/split/Tioga/pdftext.c +443 -0
- data/split/Tioga/safe_double.h +104 -0
- data/split/Tioga/symbols.c +92 -0
- data/split/Tioga/symbols.h +52 -0
- data/split/Tioga/texout.c +380 -0
- data/split/defs.h +33 -0
- data/split/extconf.rb +107 -0
- data/split/mkmf2.rb +1612 -0
- data/split/namespace.h +47 -0
- data/split/safe_double.h +104 -0
- data/split/scripts/tioga +4 -0
- data/split/symbols.c +92 -0
- data/split/symbols.h +52 -0
- data/tests/dtable_test.data +6 -0
- data/tests/dvector_read_test.data +1 -0
- data/tests/dvector_test.data +101 -0
- data/tests/tc_Dtable.rb +221 -0
- data/tests/tc_Dvector.rb +791 -0
- data/tests/tc_FMkr.rb +162 -0
- data/tests/tc_Flate.rb +45 -0
- data/tests/tc_Function.rb +111 -0
- data/tests/ts_Tioga.rb +38 -0
- metadata +163 -0
data/split/Dtable/defs.h
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**********************************************************************
|
|
2
|
+
|
|
3
|
+
defs.h:
|
|
4
|
+
some definitions that are used everywhere and that depend on some
|
|
5
|
+
HAVE_* macros.
|
|
6
|
+
|
|
7
|
+
Copyright (C) 2006 Vincent Fourmond
|
|
8
|
+
|
|
9
|
+
This program is free software; you can redistribute it and/or modify
|
|
10
|
+
it under the terms of the GNU General Library Public License as published
|
|
11
|
+
by the Free Software Foundation; either version 2 of the License, or
|
|
12
|
+
(at your option) any later version.
|
|
13
|
+
|
|
14
|
+
This program is distributed in the hope that it will be useful,
|
|
15
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
16
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
17
|
+
GNU Library General Public License for more details.
|
|
18
|
+
|
|
19
|
+
You should have received a copy of the GNU Library General Public License
|
|
20
|
+
along with this program; if not, write to the Free Software
|
|
21
|
+
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
22
|
+
|
|
23
|
+
**********************************************************************/
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
#ifdef HAVE_ISNAN
|
|
27
|
+
/* we use isnan and isinf, which are much faster than the workaround */
|
|
28
|
+
#define is_okay_number(x) (! isnan(x) && ! isinf(x))
|
|
29
|
+
#else
|
|
30
|
+
#define is_okay_number(x) ((x) - (x) == 0.0)
|
|
31
|
+
#define isnan(x) ((x) != (x))
|
|
32
|
+
/* yes, as funny as it may look NaN != NaN, and that's the only one */
|
|
33
|
+
#endif
|
|
@@ -0,0 +1,1928 @@
|
|
|
1
|
+
/* dtable.c */
|
|
2
|
+
/*
|
|
3
|
+
Copyright (C) 2004 Bill Paxton
|
|
4
|
+
|
|
5
|
+
This file is part of Dtable.
|
|
6
|
+
|
|
7
|
+
Dtable is free software; you can redistribute it and/or modify
|
|
8
|
+
it under the terms of the GNU General Library Public License as published
|
|
9
|
+
by the Free Software Foundation; either version 2 of the License, or
|
|
10
|
+
(at your option) any later version.
|
|
11
|
+
|
|
12
|
+
Dtable is distributed in the hope that it will be useful,
|
|
13
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
14
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
15
|
+
GNU Library General Public License for more details.
|
|
16
|
+
|
|
17
|
+
You should have received a copy of the GNU Library General Public License
|
|
18
|
+
along with Dtable; if not, write to the Free Software
|
|
19
|
+
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
#include <namespace.h>
|
|
23
|
+
#include "dtable_intern.h"
|
|
24
|
+
#include <stdbool.h>
|
|
25
|
+
#include <stdlib.h>
|
|
26
|
+
#include <ctype.h>
|
|
27
|
+
#include <math.h>
|
|
28
|
+
#include "intern.h"
|
|
29
|
+
|
|
30
|
+
#include <defs.h>
|
|
31
|
+
|
|
32
|
+
/* safe storing of doubles */
|
|
33
|
+
#include <safe_double.h>
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
#define is_a_dtable(d) ( TYPE(d) == T_DATA && RDATA(d)->dfree == (RUBY_DATA_FUNC)dtable_free )
|
|
37
|
+
|
|
38
|
+
#ifndef MAX
|
|
39
|
+
#define MAX(a,b) (((a) > (b)) ? (a) : (b))
|
|
40
|
+
#endif
|
|
41
|
+
#ifndef MIN
|
|
42
|
+
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
|
|
43
|
+
#endif
|
|
44
|
+
|
|
45
|
+
typedef struct {
|
|
46
|
+
long num_cols, num_rows; /* the dimensions */
|
|
47
|
+
double **ptr; /* the data */
|
|
48
|
+
} Dtable;
|
|
49
|
+
|
|
50
|
+
/* prototypes */
|
|
51
|
+
static void dtable_free(Dtable *d);
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
PRIVATE bool Is_Dtable(VALUE obj) { return is_a_dtable(obj); }
|
|
55
|
+
|
|
56
|
+
// data stored in row order
|
|
57
|
+
// i.e., array arr of num_cols W and num_rows H is actually an array of H pointers
|
|
58
|
+
// each pointing to an array of W doubles.
|
|
59
|
+
// access row i and col j as arr[i][j] in c, as arr[i,j] in Ruby.
|
|
60
|
+
|
|
61
|
+
static void Alloc2dGrid(double ***f, int num_cols, int num_rows) {
|
|
62
|
+
int i;
|
|
63
|
+
if ((*f = (double **) calloc(num_rows, sizeof(double *)))==NULL)
|
|
64
|
+
rb_raise(rb_eArgError, "Memory allocation error in \"Alloc2dGrid\"");
|
|
65
|
+
for (i = 0; i < num_rows; i++) {
|
|
66
|
+
if (((*f)[i] = (double *) calloc(num_cols ,sizeof(double)))==NULL)
|
|
67
|
+
rb_raise(rb_eArgError, "Memory allocation error in \"Alloc2dGrid\"");
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
static double Max2dGrid(double **f, int num_cols, int num_rows) {
|
|
72
|
+
int i, j;
|
|
73
|
+
double M;
|
|
74
|
+
M = f[0][0];
|
|
75
|
+
for (i = 0; i < num_rows; i++) {
|
|
76
|
+
for (j = 0; j < num_cols; j++) {
|
|
77
|
+
if (f[i][j] > M) M = f[i][j];
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return M;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
static double Min2dGrid(double **f, int num_cols, int num_rows) {
|
|
84
|
+
int i, j;
|
|
85
|
+
double M;
|
|
86
|
+
M = f[0][0];
|
|
87
|
+
for (i = 0; i < num_rows; i++) {
|
|
88
|
+
for (j = 0; j < num_cols; j++) {
|
|
89
|
+
if (f[i][j] < M) M = f[i][j];
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return M;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
static bool Max_Lt_2dGrid(double **f, double limit, int num_cols, int num_rows, double *fmax) {
|
|
96
|
+
int i, j;
|
|
97
|
+
double M=0, tmp;
|
|
98
|
+
bool found = false;
|
|
99
|
+
for (i = 0; i < num_rows; i++) {
|
|
100
|
+
for (j = 0; j < num_cols; j++) {
|
|
101
|
+
tmp = f[i][j];
|
|
102
|
+
if (tmp >= limit) continue;
|
|
103
|
+
if (!found) { found = true; M = tmp; }
|
|
104
|
+
else if (tmp > M) M = tmp;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
*fmax = M;
|
|
108
|
+
return found;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
static bool Min_Gt_2dGrid(double **f, double limit, int num_cols, int num_rows, double *fmin) {
|
|
112
|
+
int i, j;
|
|
113
|
+
double M=0, tmp;
|
|
114
|
+
bool found = false;
|
|
115
|
+
for (i = 0; i < num_rows; i++) {
|
|
116
|
+
for (j = 0; j < num_cols; j++) {
|
|
117
|
+
tmp = f[i][j];
|
|
118
|
+
if (tmp <= limit) continue;
|
|
119
|
+
if (!found) { found = true; M = tmp; }
|
|
120
|
+
else if (tmp < M) M = tmp;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
*fmin = M;
|
|
124
|
+
return found;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
static Dtable *Get_Dtable(VALUE obj) {
|
|
128
|
+
Dtable *d;
|
|
129
|
+
Data_Get_Struct(obj, Dtable, d);
|
|
130
|
+
return d;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
double **Dtable_Ptr(VALUE dtable, long *num_cols, long *num_rows) {
|
|
134
|
+
Dtable *d;
|
|
135
|
+
Data_Get_Struct(dtable, Dtable, d);
|
|
136
|
+
if(num_cols)
|
|
137
|
+
*num_cols = d->num_cols;
|
|
138
|
+
if(num_rows)
|
|
139
|
+
*num_rows = d->num_rows;
|
|
140
|
+
return d->ptr;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
static VALUE cDtable; /* the Dtable class object */
|
|
144
|
+
|
|
145
|
+
static void dtable_free(Dtable *d) {
|
|
146
|
+
double **array = d->ptr;
|
|
147
|
+
int i;
|
|
148
|
+
for (i = 0; i < d->num_rows; i++) free(array[i]);
|
|
149
|
+
free(array);
|
|
150
|
+
free(d);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
static VALUE dtable_alloc(VALUE klass) {
|
|
154
|
+
Dtable *d;
|
|
155
|
+
VALUE ary = Data_Make_Struct(klass, Dtable, NULL, dtable_free, d);
|
|
156
|
+
d->num_cols = d->num_rows = 0;
|
|
157
|
+
d->ptr = NULL;
|
|
158
|
+
return ary;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
static VALUE dtable_init(VALUE ary, int num_cols, int num_rows) {
|
|
162
|
+
Dtable *d = Get_Dtable(ary);
|
|
163
|
+
if (num_cols <= 0 || num_rows <= 0)
|
|
164
|
+
rb_raise(rb_eArgError, "bad args: Dtable.new(%d, %d)", num_cols, num_rows);
|
|
165
|
+
Alloc2dGrid(&d->ptr, num_cols, num_rows);
|
|
166
|
+
d->num_cols = num_cols;
|
|
167
|
+
d->num_rows = num_rows;
|
|
168
|
+
return ary;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
PRIVATE
|
|
172
|
+
/*
|
|
173
|
+
* call-seq:
|
|
174
|
+
* dtable.dup -> a_dtable
|
|
175
|
+
*
|
|
176
|
+
* Returns a copy of _dtable_. For performance sensitive situations involving a series of operations,
|
|
177
|
+
* first make a copy using dup and then do "bang" operations to modify the result without further copying.
|
|
178
|
+
*/
|
|
179
|
+
VALUE dtable_dup(VALUE ary) {
|
|
180
|
+
Dtable *d = Get_Dtable(ary);
|
|
181
|
+
int i, j, num_cols = d->num_cols, num_rows = d->num_rows;
|
|
182
|
+
VALUE new = dtable_init(dtable_alloc(cDtable), num_cols, num_rows);
|
|
183
|
+
Dtable *d2 = Get_Dtable(new);
|
|
184
|
+
double **src, **dest;
|
|
185
|
+
src = d->ptr; dest = d2->ptr;
|
|
186
|
+
for (i = 0; i < num_rows; i++) {
|
|
187
|
+
for (j = 0; j < num_cols; j++) {
|
|
188
|
+
dest[i][j] = src[i][j];
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
return new;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
PRIVATE
|
|
195
|
+
/*
|
|
196
|
+
* call-seq:
|
|
197
|
+
* dtable.reverse_rows -> a_dtable
|
|
198
|
+
*
|
|
199
|
+
* Returns a copy of _dtable_ with the order of rows reversed.
|
|
200
|
+
*/ VALUE dtable_reverse_rows(VALUE ary)
|
|
201
|
+
{
|
|
202
|
+
Dtable *d = Get_Dtable(ary);
|
|
203
|
+
int i, j, num_cols = d->num_cols, num_rows = d->num_rows, last_row = num_rows - 1;
|
|
204
|
+
VALUE new = dtable_init(dtable_alloc(cDtable), num_cols, num_rows);
|
|
205
|
+
Dtable *d2 = Get_Dtable(new);
|
|
206
|
+
double **src, **dest;
|
|
207
|
+
src = d->ptr; dest = d2->ptr;
|
|
208
|
+
for (i = 0; i < num_rows; i++) {
|
|
209
|
+
for (j = 0; j < num_cols; j++) {
|
|
210
|
+
dest[last_row-i][j] = src[i][j];
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
return new;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
PRIVATE
|
|
217
|
+
/*
|
|
218
|
+
* call-seq:
|
|
219
|
+
* dtable.reverse_cols -> a_dtable
|
|
220
|
+
*
|
|
221
|
+
* Returns a copy of _dtable_ with the order of columns reversed.
|
|
222
|
+
*/ VALUE dtable_reverse_cols(VALUE ary)
|
|
223
|
+
{
|
|
224
|
+
Dtable *d = Get_Dtable(ary);
|
|
225
|
+
int i, j, num_cols = d->num_cols, num_rows = d->num_rows, last_col = num_cols - 1;
|
|
226
|
+
VALUE new = dtable_init(dtable_alloc(cDtable), num_cols, num_rows);
|
|
227
|
+
Dtable *d2 = Get_Dtable(new);
|
|
228
|
+
double **src, **dest;
|
|
229
|
+
src = d->ptr; dest = d2->ptr;
|
|
230
|
+
for (i = 0; i < num_rows; i++) {
|
|
231
|
+
for (j = 0; j < num_cols; j++) {
|
|
232
|
+
dest[i][last_col-j] = src[i][j];
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
return new;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
PRIVATE
|
|
240
|
+
/*
|
|
241
|
+
* call-seq:
|
|
242
|
+
* dtable.rotate_cw90 -> a_dtable
|
|
243
|
+
*
|
|
244
|
+
* Returns a copy of _dtable_ rotated 90 degrees clockwise.
|
|
245
|
+
*/ VALUE dtable_rotate_cw90(VALUE ary)
|
|
246
|
+
{
|
|
247
|
+
Dtable *d = Get_Dtable(ary);
|
|
248
|
+
int i, j, num_cols = d->num_cols, num_rows = d->num_rows, last_row = num_rows - 1;
|
|
249
|
+
VALUE new = dtable_init(dtable_alloc(cDtable), num_rows, num_cols);
|
|
250
|
+
Dtable *d2 = Get_Dtable(new);
|
|
251
|
+
double **src, **dest;
|
|
252
|
+
src = d->ptr; dest = d2->ptr;
|
|
253
|
+
for (i = 0; i < num_rows; i++) {
|
|
254
|
+
for (j = 0; j < num_cols; j++) {
|
|
255
|
+
dest[j][last_row-i] = src[i][j];
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
return new;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
PRIVATE
|
|
263
|
+
/*
|
|
264
|
+
* call-seq:
|
|
265
|
+
* dtable.rotate_ccw90 -> a_dtable
|
|
266
|
+
*
|
|
267
|
+
* Returns a copy of _dtable_ rotated 90 degrees counter-clockwise.
|
|
268
|
+
*/ VALUE dtable_rotate_ccw90(VALUE ary)
|
|
269
|
+
{
|
|
270
|
+
Dtable *d = Get_Dtable(ary);
|
|
271
|
+
int i, j, num_cols = d->num_cols, num_rows = d->num_rows, last_col = num_cols - 1;
|
|
272
|
+
VALUE new = dtable_init(dtable_alloc(cDtable), num_rows, num_cols);
|
|
273
|
+
Dtable *d2 = Get_Dtable(new);
|
|
274
|
+
double **src, **dest;
|
|
275
|
+
src = d->ptr; dest = d2->ptr;
|
|
276
|
+
for (i = 0; i < num_rows; i++) {
|
|
277
|
+
for (j = 0; j < num_cols; j++) {
|
|
278
|
+
dest[last_col-j][i] = src[i][j];
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
return new;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
PRIVATE
|
|
285
|
+
/*
|
|
286
|
+
* call-seq:
|
|
287
|
+
* dtable.transpose -> a_dtable
|
|
288
|
+
*
|
|
289
|
+
* Returns a transposed copy of _dtable_ (i.e., exchange rows and columns).
|
|
290
|
+
*/ VALUE dtable_transpose(VALUE ary) {
|
|
291
|
+
Dtable *d = Get_Dtable(ary);
|
|
292
|
+
int i, j, num_cols = d->num_cols, num_rows = d->num_rows;
|
|
293
|
+
VALUE new = dtable_init(dtable_alloc(cDtable), num_rows, num_cols);
|
|
294
|
+
Dtable *d2 = Get_Dtable(new);
|
|
295
|
+
double **src, **dest;
|
|
296
|
+
src = d->ptr; dest = d2->ptr;
|
|
297
|
+
for (i = 0; i < num_rows; i++) {
|
|
298
|
+
for (j = 0; j < num_cols; j++) {
|
|
299
|
+
dest[j][i] = src[i][j];
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
return new;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
PRIVATE
|
|
306
|
+
/*
|
|
307
|
+
* call-seq:
|
|
308
|
+
* Dtable.new(num_cols, num_rows) -> a_dtable
|
|
309
|
+
*
|
|
310
|
+
* Returns a new Dtable with the requested dimensions.
|
|
311
|
+
*/
|
|
312
|
+
VALUE dtable_initialize(int argc, VALUE *argv, VALUE ary) {
|
|
313
|
+
if (argc != 2) rb_raise(rb_eArgError, "need 2 args for Dtable.new(num_cols, num_rows)");
|
|
314
|
+
int num_cols = NUM2INT(argv[0]), num_rows = NUM2INT(argv[1]);
|
|
315
|
+
return dtable_init(ary, num_cols, num_rows);
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
PRIVATE
|
|
319
|
+
/*
|
|
320
|
+
* call-seq:
|
|
321
|
+
* dtable.num_cols -> integer
|
|
322
|
+
*
|
|
323
|
+
* Returns the number of entries in the x dimension of _dtable_.
|
|
324
|
+
*/
|
|
325
|
+
VALUE dtable_num_cols(VALUE ary) {
|
|
326
|
+
Dtable *d = Get_Dtable(ary);
|
|
327
|
+
return LONG2NUM(d->num_cols);
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
PRIVATE
|
|
331
|
+
/*
|
|
332
|
+
* call-seq:
|
|
333
|
+
* dtable.num_rows -> integer
|
|
334
|
+
*
|
|
335
|
+
* Returns the number of entries in the y dimension of _dtable_.
|
|
336
|
+
*/ VALUE dtable_num_rows(VALUE ary) {
|
|
337
|
+
Dtable *d = Get_Dtable(ary);
|
|
338
|
+
return LONG2NUM(d->num_rows);
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
PRIVATE
|
|
342
|
+
/*
|
|
343
|
+
* call-seq:
|
|
344
|
+
* dtable.min_gt(val) -> float or nil
|
|
345
|
+
*
|
|
346
|
+
* Returns the minimum entry in _dtable_ which is greater than _val_, or <code>nil</code> if no such entry if found.
|
|
347
|
+
*/ VALUE dtable_min_gt(VALUE ary, VALUE val) {
|
|
348
|
+
Dtable *d = Get_Dtable(ary);
|
|
349
|
+
val = rb_Float(val);
|
|
350
|
+
double zmin, z = NUM2DBL(val);
|
|
351
|
+
if (Min_Gt_2dGrid(d->ptr, z, d->num_cols, d->num_rows, &zmin))
|
|
352
|
+
return rb_float_new(zmin);
|
|
353
|
+
return Qnil;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
PRIVATE
|
|
357
|
+
/*
|
|
358
|
+
* call-seq:
|
|
359
|
+
* dtable.max_lt(val) -> float or nil
|
|
360
|
+
*
|
|
361
|
+
* Returns the maximum entry in _dtable_ which is less than _val_, or <code>nil</code> if no such entry if found.
|
|
362
|
+
*/ VALUE dtable_max_lt(VALUE ary, VALUE val) {
|
|
363
|
+
Dtable *d = Get_Dtable(ary);
|
|
364
|
+
val = rb_Float(val);
|
|
365
|
+
double zmax, z = NUM2DBL(val);
|
|
366
|
+
if (Max_Lt_2dGrid(d->ptr, z, d->num_cols, d->num_rows, &zmax))
|
|
367
|
+
return rb_float_new(zmax);
|
|
368
|
+
return Qnil;
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
PRIVATE
|
|
372
|
+
/*
|
|
373
|
+
* call-seq:
|
|
374
|
+
* dtable.min -> float
|
|
375
|
+
*
|
|
376
|
+
* Returns the minimum entry in _dtable_.
|
|
377
|
+
*/ VALUE dtable_min(VALUE ary) {
|
|
378
|
+
Dtable *d = Get_Dtable(ary);
|
|
379
|
+
double zmin = Min2dGrid(d->ptr, d->num_cols, d->num_rows);
|
|
380
|
+
return rb_float_new(zmin);
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
PRIVATE
|
|
384
|
+
/*
|
|
385
|
+
* call-seq:
|
|
386
|
+
* dtable.max -> float
|
|
387
|
+
*
|
|
388
|
+
* Returns the maximum entry in _dtable_.
|
|
389
|
+
*/ VALUE dtable_max(VALUE ary) {
|
|
390
|
+
Dtable *d = Get_Dtable(ary);
|
|
391
|
+
double zmax = Max2dGrid(d->ptr, d->num_cols, d->num_rows);
|
|
392
|
+
return rb_float_new(zmax);
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
PRIVATE
|
|
396
|
+
/*
|
|
397
|
+
* call-seq:
|
|
398
|
+
* dtable.row(int) -> a_dvec
|
|
399
|
+
*
|
|
400
|
+
* Creates a Dvector holding a copy of the contents of the requested row.
|
|
401
|
+
*/ VALUE dtable_row(VALUE ary, VALUE row_num) {
|
|
402
|
+
Dtable *d = Get_Dtable(ary);
|
|
403
|
+
row_num = rb_Integer(row_num);
|
|
404
|
+
int row = NUM2INT(row_num);
|
|
405
|
+
if (row < 0 || row >= d->num_rows)
|
|
406
|
+
rb_raise(rb_eArgError, "Asking for row i = %i from array with only %i rows", row, d->num_rows);
|
|
407
|
+
VALUE dvec = Dvector_Create();
|
|
408
|
+
Dvector_Data_Replace(dvec, d->num_cols, d->ptr[row]);
|
|
409
|
+
return dvec;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
PRIVATE
|
|
413
|
+
/*
|
|
414
|
+
* call-seq:
|
|
415
|
+
* dtable.set_row(int,a_dvec) -> a_dvec
|
|
416
|
+
*
|
|
417
|
+
* Stores the contents of _a_dec_ in the specified row of the array.
|
|
418
|
+
* The length of the vector must equal the number of columns in the array.
|
|
419
|
+
*/ VALUE dtable_set_row(VALUE ary, VALUE row_num, VALUE dvec) {
|
|
420
|
+
Dtable *d = Get_Dtable(ary);
|
|
421
|
+
long len, j;
|
|
422
|
+
double *data = Dvector_Data_for_Read(dvec, &len);
|
|
423
|
+
row_num = rb_Integer(row_num);
|
|
424
|
+
int row = NUM2INT(row_num);
|
|
425
|
+
if (row < 0 || row >= d->num_rows)
|
|
426
|
+
rb_raise(rb_eArgError, "Asking for row i = %i from array with only %i rows", row, d->num_rows);
|
|
427
|
+
if (len != d->num_cols)
|
|
428
|
+
rb_raise(rb_eArgError, "Length of vector (%i) does not match number of columns (%i)", len, d->num_cols);
|
|
429
|
+
for (j=0; j < len; j++)
|
|
430
|
+
d->ptr[row][j] = data[j];
|
|
431
|
+
return dvec;
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
PRIVATE
|
|
435
|
+
/*
|
|
436
|
+
* call-seq:
|
|
437
|
+
* dtable.set_column(int,a_dvec) -> a_dvec
|
|
438
|
+
*
|
|
439
|
+
* Stores the contents of _a_dec_ in the specified column of the array.
|
|
440
|
+
* The length of the vector must equal the number of rows in the array.
|
|
441
|
+
*/ VALUE dtable_set_column(VALUE ary, VALUE col_num, VALUE dvec) {
|
|
442
|
+
Dtable *d = Get_Dtable(ary);
|
|
443
|
+
long len, i;
|
|
444
|
+
double *data = Dvector_Data_for_Read(dvec, &len);
|
|
445
|
+
col_num = rb_Integer(col_num);
|
|
446
|
+
int col = NUM2INT(col_num);
|
|
447
|
+
if (col < 0 || col >= d->num_cols)
|
|
448
|
+
rb_raise(rb_eArgError, "Asking for column i = %i from array with only %i columns", col, d->num_cols);
|
|
449
|
+
if (len != d->num_rows)
|
|
450
|
+
rb_raise(rb_eArgError, "Length of vector (%i) does not match number of rows (%i)", len, d->num_rows);
|
|
451
|
+
for (i=0; i < len; i++)
|
|
452
|
+
d->ptr[i][col] = data[i];
|
|
453
|
+
return dvec;
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
PRIVATE
|
|
457
|
+
/*
|
|
458
|
+
* call-seq:
|
|
459
|
+
* dtable.column(int) -> a_dvec
|
|
460
|
+
*
|
|
461
|
+
* Creates a Dvector holding a copy of the contents of the requested column.
|
|
462
|
+
*/ VALUE dtable_column(VALUE ary, VALUE column_num) {
|
|
463
|
+
Dtable *d = Get_Dtable(ary);
|
|
464
|
+
column_num = rb_Integer(column_num);
|
|
465
|
+
int i, column = NUM2INT(column_num), len;
|
|
466
|
+
if (column < 0 || column >= d->num_cols)
|
|
467
|
+
rb_raise(rb_eArgError, "Asking for column i = %i from array with only %i columns", column, d->num_cols);
|
|
468
|
+
VALUE dvec = Dvector_Create();
|
|
469
|
+
len = d->num_rows;
|
|
470
|
+
Dvector_Data_Resize(dvec, len);
|
|
471
|
+
for (i=0; i < len; i++)
|
|
472
|
+
Dvector_Store_Double(dvec, i, d->ptr[i][column]);
|
|
473
|
+
return dvec;
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
static void set_dtable_vals(VALUE ary, double v) {
|
|
477
|
+
Dtable *d = Get_Dtable(ary);
|
|
478
|
+
int num_cols = d->num_cols, num_rows = d->num_rows, i, j;
|
|
479
|
+
double **data = d->ptr;
|
|
480
|
+
for (i = 0; i < num_rows; i++) {
|
|
481
|
+
for (j = 0; j < num_cols; j++) {
|
|
482
|
+
data[i][j] = v;
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
PRIVATE
|
|
488
|
+
/*
|
|
489
|
+
* call-seq:
|
|
490
|
+
* dtable.clear -> dtable
|
|
491
|
+
*
|
|
492
|
+
* Sets the entries of _dtable_ array to zero.
|
|
493
|
+
*/ VALUE dtable_clear(VALUE ary, VALUE val) {
|
|
494
|
+
set_dtable_vals(ary, 0.0);
|
|
495
|
+
return ary;
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
PRIVATE
|
|
499
|
+
/*
|
|
500
|
+
* call-seq:
|
|
501
|
+
* dtable.set(float) -> dtable
|
|
502
|
+
* dtable.set(a_dtable) -> dtable
|
|
503
|
+
*
|
|
504
|
+
* Modifies the entries of _dtable_ array. If the argument is a float, then all of the
|
|
505
|
+
* entries are set to that value. If the argument is another Dtable array, then it must
|
|
506
|
+
* be the size as _dtable_, and its contents are copied to _dtable_.
|
|
507
|
+
*/ VALUE dtable_set(VALUE ary, VALUE val) {
|
|
508
|
+
if (is_a_dtable(val)) {
|
|
509
|
+
Dtable *d = Get_Dtable(ary);
|
|
510
|
+
Dtable *d2 = Get_Dtable(val);
|
|
511
|
+
int num_cols = d->num_cols, num_rows = d->num_rows, i, j;
|
|
512
|
+
double **data = d->ptr;
|
|
513
|
+
double **data2 = d2->ptr;
|
|
514
|
+
if (d2->num_cols != num_cols || d2->num_rows != num_rows)
|
|
515
|
+
rb_raise(rb_eArgError, "Arrays must be same size for Dtable set");
|
|
516
|
+
for (i = 0; i < num_rows; i++) {
|
|
517
|
+
for (j = 0; j < num_cols; j++) {
|
|
518
|
+
data[i][j] = data2[i][j];
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
} else {
|
|
522
|
+
double v = NUM2DBL(val);
|
|
523
|
+
set_dtable_vals(ary, v);
|
|
524
|
+
}
|
|
525
|
+
return ary;
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
PRIVATE
|
|
529
|
+
VALUE dtable_apply_math_op_bang(VALUE ary, double (*op)(double)) {
|
|
530
|
+
Dtable *d = Get_Dtable(ary);
|
|
531
|
+
double **p = d->ptr;
|
|
532
|
+
int num_cols = d->num_cols, num_rows = d->num_rows, i, j;
|
|
533
|
+
for (i = 0; i < num_rows; i++) {
|
|
534
|
+
for (j = 0; j < num_cols; j++) {
|
|
535
|
+
p[i][j] = (*op)(p[i][j]);
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
return ary;
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
PRIVATE VALUE dtable_apply_math_op(VALUE source, double (*op)(double)) {
|
|
542
|
+
return dtable_apply_math_op_bang(dtable_dup(source), op);
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
static double do_neg(double arg) { return -arg; }
|
|
546
|
+
|
|
547
|
+
PRIVATE
|
|
548
|
+
/*
|
|
549
|
+
* call-seq:
|
|
550
|
+
* dtable.neg -> a_dtable
|
|
551
|
+
*
|
|
552
|
+
* Returns of copy of _dtable_ with each entry x replaced by -x.
|
|
553
|
+
*/ VALUE dtable_neg(VALUE ary) {
|
|
554
|
+
return dtable_apply_math_op(ary, do_neg);
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
PRIVATE
|
|
558
|
+
/*
|
|
559
|
+
* call-seq:
|
|
560
|
+
* dtable.abs -> a_dtable
|
|
561
|
+
*
|
|
562
|
+
* Returns of copy of _dtable_ with all entries replaced by their absolute values.
|
|
563
|
+
*/ VALUE dtable_abs(VALUE ary) {
|
|
564
|
+
return dtable_apply_math_op(ary, fabs);
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
PRIVATE
|
|
568
|
+
/*
|
|
569
|
+
* call-seq:
|
|
570
|
+
* dtable.sin -> a_dtable
|
|
571
|
+
*
|
|
572
|
+
* Returns of copy of _dtable_ with entry x replaced by sin(x).
|
|
573
|
+
*/ VALUE dtable_sin(VALUE ary) {
|
|
574
|
+
return dtable_apply_math_op(ary, sin);
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
PRIVATE
|
|
578
|
+
/*
|
|
579
|
+
* call-seq:
|
|
580
|
+
* dtable.cos -> a_dtable
|
|
581
|
+
*
|
|
582
|
+
* Returns of copy of _dtable_ with entry x replaced by cos(x).
|
|
583
|
+
*/ VALUE dtable_cos(VALUE ary) {
|
|
584
|
+
return dtable_apply_math_op(ary, cos);
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
PRIVATE
|
|
588
|
+
/*
|
|
589
|
+
* call-seq:
|
|
590
|
+
* dtable.tan -> a_dtable
|
|
591
|
+
*
|
|
592
|
+
* Returns of copy of _dtable_ with entry x replaced by tan(x).
|
|
593
|
+
*/ VALUE dtable_tan(VALUE ary) {
|
|
594
|
+
return dtable_apply_math_op(ary, tan);
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
PRIVATE
|
|
598
|
+
/*
|
|
599
|
+
* call-seq:
|
|
600
|
+
* dtable.asin -> a_dtable
|
|
601
|
+
*
|
|
602
|
+
* Returns of copy of _dtable_ with entry x replaced by asin(x).
|
|
603
|
+
*/ VALUE dtable_asin(VALUE ary) {
|
|
604
|
+
return dtable_apply_math_op(ary, asin);
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
PRIVATE
|
|
608
|
+
/*
|
|
609
|
+
* call-seq:
|
|
610
|
+
* dtable.acos -> a_dtable
|
|
611
|
+
*
|
|
612
|
+
* Returns of copy of _dtable_ with entry x replaced by acos(x).
|
|
613
|
+
*/ VALUE dtable_acos(VALUE ary) {
|
|
614
|
+
return dtable_apply_math_op(ary, acos);
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
PRIVATE
|
|
618
|
+
/*
|
|
619
|
+
* call-seq:
|
|
620
|
+
* dtable.atan -> a_dtable
|
|
621
|
+
*
|
|
622
|
+
* Returns of copy of _dtable_ with entry x replaced by atan(x).
|
|
623
|
+
*/ VALUE dtable_atan(VALUE ary) {
|
|
624
|
+
return dtable_apply_math_op(ary, atan);
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
PRIVATE
|
|
628
|
+
/*
|
|
629
|
+
* call-seq:
|
|
630
|
+
* dtable.sinh -> a_dtable
|
|
631
|
+
*
|
|
632
|
+
* Returns of copy of _dtable_ with entry x replaced by sinh(x).
|
|
633
|
+
*/ VALUE dtable_sinh(VALUE ary) {
|
|
634
|
+
return dtable_apply_math_op(ary, sinh);
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
PRIVATE
|
|
638
|
+
/*
|
|
639
|
+
* call-seq:
|
|
640
|
+
* dtable.cosh -> a_dtable
|
|
641
|
+
*
|
|
642
|
+
* Returns of copy of _dtable_ with entry x replaced by cosh(x).
|
|
643
|
+
*/ VALUE dtable_cosh(VALUE ary) {
|
|
644
|
+
return dtable_apply_math_op(ary, cosh);
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
PRIVATE
|
|
648
|
+
/*
|
|
649
|
+
* call-seq:
|
|
650
|
+
* dtable.tanh -> a_dtable
|
|
651
|
+
*
|
|
652
|
+
* Returns of copy of _dtable_ with entry x replaced by tanh(x).
|
|
653
|
+
*/ VALUE dtable_tanh(VALUE ary) {
|
|
654
|
+
return dtable_apply_math_op(ary, tanh);
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
static double do_asinh(double x) { return log(x + sqrt(x*x+1.0)); }
|
|
658
|
+
|
|
659
|
+
PRIVATE
|
|
660
|
+
/*
|
|
661
|
+
* call-seq:
|
|
662
|
+
* dtable.asinh -> a_dtable
|
|
663
|
+
*
|
|
664
|
+
* Returns of copy of _dtable_ with entry x replaced by asinh(x).
|
|
665
|
+
*/ VALUE dtable_asinh(VALUE ary) {
|
|
666
|
+
return dtable_apply_math_op(ary, do_asinh);
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
static double do_acosh(double x) { return log(x + sqrt(x*x-1.0)); }
|
|
670
|
+
|
|
671
|
+
PRIVATE
|
|
672
|
+
/*
|
|
673
|
+
* call-seq:
|
|
674
|
+
* dtable.acosh -> a_dtable
|
|
675
|
+
*
|
|
676
|
+
* Returns of copy of _dtable_ with entry x replaced by acosh(x).
|
|
677
|
+
*/ VALUE dtable_acosh(VALUE ary) {
|
|
678
|
+
return dtable_apply_math_op(ary, do_acosh);
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
static double do_atanh(double x) { return 0.5*log((1.0+x)/(1.0-x)); }
|
|
682
|
+
|
|
683
|
+
PRIVATE
|
|
684
|
+
/*
|
|
685
|
+
* call-seq:
|
|
686
|
+
* dtable.atanh -> a_dtable
|
|
687
|
+
*
|
|
688
|
+
* Returns of copy of _dtable_ with entry x replaced by atanh(x).
|
|
689
|
+
*/ VALUE dtable_atanh(VALUE ary) {
|
|
690
|
+
return dtable_apply_math_op(ary, do_atanh);
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
PRIVATE
|
|
694
|
+
/*
|
|
695
|
+
* call-seq:
|
|
696
|
+
* dtable.ceil -> a_dtable
|
|
697
|
+
*
|
|
698
|
+
* Returns of copy of _dtable_ with entry x replaced by smallest integer not less than x.
|
|
699
|
+
*/ VALUE dtable_ceil(VALUE ary) {
|
|
700
|
+
return dtable_apply_math_op(ary, ceil);
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
PRIVATE
|
|
704
|
+
/*
|
|
705
|
+
* call-seq:
|
|
706
|
+
* dtable.floor -> a_dtable
|
|
707
|
+
*
|
|
708
|
+
* Returns of copy of _dtable_ with each entry x replaced by largest integer not greater than x.
|
|
709
|
+
*/ VALUE dtable_floor(VALUE ary) {
|
|
710
|
+
return dtable_apply_math_op(ary, floor);
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
static double do_round(double x) { return (x == 0.0)? 0.0 : (x > 0.0)? floor(x+0.5) : ceil(x-0.5); }
|
|
714
|
+
|
|
715
|
+
PRIVATE
|
|
716
|
+
/*
|
|
717
|
+
* call-seq:
|
|
718
|
+
* dtable.round -> a_dtable
|
|
719
|
+
*
|
|
720
|
+
* Returns of copy of _dtable_ with each entry x replaced by round(x).
|
|
721
|
+
* (Numbers midway between integers round away from zero.)
|
|
722
|
+
*/ VALUE dtable_round(VALUE ary) {
|
|
723
|
+
return dtable_apply_math_op(ary, do_round);
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
PRIVATE
|
|
727
|
+
/*
|
|
728
|
+
* call-seq:
|
|
729
|
+
* dtable.exp -> a_dtable
|
|
730
|
+
*
|
|
731
|
+
* Returns of copy of _dtable_ with each entry x replaced by exp(x).
|
|
732
|
+
*/ VALUE dtable_exp(VALUE ary) {
|
|
733
|
+
return dtable_apply_math_op(ary, exp);
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
static double do_exp10(double arg) { return pow(10.0, arg); }
|
|
737
|
+
|
|
738
|
+
PRIVATE
|
|
739
|
+
/*
|
|
740
|
+
* call-seq:
|
|
741
|
+
* dtable.exp10 -> a_dtable
|
|
742
|
+
*
|
|
743
|
+
* Returns of copy of _dtable_ with each entry x replaced by 10**x.
|
|
744
|
+
*/ VALUE dtable_exp10(VALUE ary) {
|
|
745
|
+
return dtable_apply_math_op(ary, do_exp10);
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
PRIVATE
|
|
749
|
+
/*
|
|
750
|
+
* call-seq:
|
|
751
|
+
* dtable.log -> a_dtable
|
|
752
|
+
*
|
|
753
|
+
* Returns of copy of _dtable_ with each entry x replaced by log(x).
|
|
754
|
+
*/ VALUE dtable_log(VALUE ary) {
|
|
755
|
+
return dtable_apply_math_op(ary, log);
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
PRIVATE
|
|
759
|
+
/*
|
|
760
|
+
* call-seq:
|
|
761
|
+
* dtable.log10 -> a_dtable
|
|
762
|
+
*
|
|
763
|
+
* Returns of copy of _dtable_ with each entry x replaced by log10(x).
|
|
764
|
+
*/ VALUE dtable_log10(VALUE ary) {
|
|
765
|
+
return dtable_apply_math_op(ary, log10);
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
static double do_inv(double arg) { return 1.0/arg; }
|
|
769
|
+
|
|
770
|
+
PRIVATE
|
|
771
|
+
/*
|
|
772
|
+
* call-seq:
|
|
773
|
+
* dtable.inv -> a_dtable
|
|
774
|
+
*
|
|
775
|
+
* Returns of copy of _dtable_ with each entry x replaced by 1/x.
|
|
776
|
+
*/ VALUE dtable_inv(VALUE ary) {
|
|
777
|
+
return dtable_apply_math_op(ary, do_inv);
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
PRIVATE
|
|
781
|
+
/*
|
|
782
|
+
* call-seq:
|
|
783
|
+
* dtable.sqrt -> a_dtable
|
|
784
|
+
*
|
|
785
|
+
* Returns of copy of _dtable_ with each entry x replaced by sqrt(x).
|
|
786
|
+
*/ VALUE dtable_sqrt(VALUE ary) {
|
|
787
|
+
return dtable_apply_math_op(ary, sqrt);
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
PRIVATE
|
|
791
|
+
/*
|
|
792
|
+
* call-seq:
|
|
793
|
+
* dtable.neg! -> dtable
|
|
794
|
+
*
|
|
795
|
+
* Replace each entry x of _dtable_ with -x.
|
|
796
|
+
*/ VALUE dtable_neg_bang(VALUE ary) {
|
|
797
|
+
return dtable_apply_math_op_bang(ary, do_neg);
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
PRIVATE
|
|
801
|
+
/*
|
|
802
|
+
* call-seq:
|
|
803
|
+
* dtable.abs! -> dtable
|
|
804
|
+
*
|
|
805
|
+
* Replace each entry x of _dtable_ with abs(x).
|
|
806
|
+
*/ VALUE dtable_abs_bang(VALUE ary) {
|
|
807
|
+
return dtable_apply_math_op_bang(ary, fabs);
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
PRIVATE
|
|
811
|
+
/*
|
|
812
|
+
* call-seq:
|
|
813
|
+
* dtable.sin! -> dtable
|
|
814
|
+
*
|
|
815
|
+
* Replace each entry x of _dtable_ with sin(x).
|
|
816
|
+
*/ VALUE dtable_sin_bang(VALUE ary) {
|
|
817
|
+
return dtable_apply_math_op_bang(ary, sin);
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
PRIVATE
|
|
821
|
+
/*
|
|
822
|
+
* call-seq:
|
|
823
|
+
* dtable.cos! -> dtable
|
|
824
|
+
*
|
|
825
|
+
* Replace each entry x of _dtable_ with cos(x).
|
|
826
|
+
*/ VALUE dtable_cos_bang(VALUE ary) {
|
|
827
|
+
return dtable_apply_math_op_bang(ary, cos);
|
|
828
|
+
}
|
|
829
|
+
|
|
830
|
+
PRIVATE
|
|
831
|
+
/*
|
|
832
|
+
* call-seq:
|
|
833
|
+
* dtable.tan! -> dtable
|
|
834
|
+
*
|
|
835
|
+
* Replace each entry x of _dtable_ with tan(x).
|
|
836
|
+
*/ VALUE dtable_tan_bang(VALUE ary) {
|
|
837
|
+
return dtable_apply_math_op_bang(ary, tan);
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
PRIVATE
|
|
841
|
+
/*
|
|
842
|
+
* call-seq:
|
|
843
|
+
* dtable.asin! -> dtable
|
|
844
|
+
*
|
|
845
|
+
* Replace each entry x of _dtable_ with asin(x).
|
|
846
|
+
*/ VALUE dtable_asin_bang(VALUE ary) {
|
|
847
|
+
return dtable_apply_math_op_bang(ary, asin);
|
|
848
|
+
}
|
|
849
|
+
|
|
850
|
+
PRIVATE
|
|
851
|
+
/*
|
|
852
|
+
* call-seq:
|
|
853
|
+
* dtable.acos! -> dtable
|
|
854
|
+
*
|
|
855
|
+
* Replace each entry x of _dtable_ with acos(x).
|
|
856
|
+
*/ VALUE dtable_acos_bang(VALUE ary) {
|
|
857
|
+
return dtable_apply_math_op_bang(ary, acos);
|
|
858
|
+
}
|
|
859
|
+
|
|
860
|
+
PRIVATE
|
|
861
|
+
/*
|
|
862
|
+
* call-seq:
|
|
863
|
+
* dtable.atan! -> dtable
|
|
864
|
+
*
|
|
865
|
+
* Replace each entry x of _dtable_ with atan(x).
|
|
866
|
+
*/ VALUE dtable_atan_bang(VALUE ary) {
|
|
867
|
+
return dtable_apply_math_op_bang(ary, atan);
|
|
868
|
+
}
|
|
869
|
+
|
|
870
|
+
PRIVATE
|
|
871
|
+
/*
|
|
872
|
+
* call-seq:
|
|
873
|
+
* dtable.sinh! -> dtable
|
|
874
|
+
*
|
|
875
|
+
* Replace each entry x of _dtable_ with sinh(x).
|
|
876
|
+
*/ VALUE dtable_sinh_bang(VALUE ary) {
|
|
877
|
+
return dtable_apply_math_op_bang(ary, sinh);
|
|
878
|
+
}
|
|
879
|
+
|
|
880
|
+
PRIVATE
|
|
881
|
+
/*
|
|
882
|
+
* call-seq:
|
|
883
|
+
* dtable.cosh! -> dtable
|
|
884
|
+
*
|
|
885
|
+
* Replace each entry x of _dtable_ with cosh(x).
|
|
886
|
+
*/ VALUE dtable_cosh_bang(VALUE ary) {
|
|
887
|
+
return dtable_apply_math_op_bang(ary, cosh);
|
|
888
|
+
}
|
|
889
|
+
|
|
890
|
+
PRIVATE
|
|
891
|
+
/*
|
|
892
|
+
* call-seq:
|
|
893
|
+
* dtable.tanh! -> dtable
|
|
894
|
+
*
|
|
895
|
+
* Replace each entry x of _dtable_ with tanh(x).
|
|
896
|
+
*/ VALUE dtable_tanh_bang(VALUE ary) {
|
|
897
|
+
return dtable_apply_math_op_bang(ary, tanh);
|
|
898
|
+
}
|
|
899
|
+
|
|
900
|
+
PRIVATE
|
|
901
|
+
/*
|
|
902
|
+
* call-seq:
|
|
903
|
+
* dtable.asinh! -> dtable
|
|
904
|
+
*
|
|
905
|
+
* Replace each entry x of _dtable_ with asinh(x).
|
|
906
|
+
*/ VALUE dtable_asinh_bang(VALUE ary) {
|
|
907
|
+
return dtable_apply_math_op_bang(ary, do_asinh);
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
PRIVATE
|
|
911
|
+
/*
|
|
912
|
+
* call-seq:
|
|
913
|
+
* dtable.acosh! -> dtable
|
|
914
|
+
*
|
|
915
|
+
* Replace each entry x of _dtable_ with acosh(x).
|
|
916
|
+
*/ VALUE dtable_acosh_bang(VALUE ary) {
|
|
917
|
+
return dtable_apply_math_op_bang(ary, do_acosh);
|
|
918
|
+
}
|
|
919
|
+
|
|
920
|
+
PRIVATE
|
|
921
|
+
/*
|
|
922
|
+
* call-seq:
|
|
923
|
+
* dtable.atanh! -> dtable
|
|
924
|
+
*
|
|
925
|
+
* Replace each entry x of _dtable_ with atanh(x).
|
|
926
|
+
*/ VALUE dtable_atanh_bang(VALUE ary) {
|
|
927
|
+
return dtable_apply_math_op_bang(ary, do_atanh);
|
|
928
|
+
}
|
|
929
|
+
|
|
930
|
+
PRIVATE
|
|
931
|
+
/*
|
|
932
|
+
* call-seq:
|
|
933
|
+
* dtable.ceil! -> dtable
|
|
934
|
+
*
|
|
935
|
+
* Replace each entry x of _dtable_ with the smallest integer not less than x.
|
|
936
|
+
*/ VALUE dtable_ceil_bang(VALUE ary) {
|
|
937
|
+
return dtable_apply_math_op_bang(ary, ceil);
|
|
938
|
+
}
|
|
939
|
+
|
|
940
|
+
PRIVATE
|
|
941
|
+
/*
|
|
942
|
+
* call-seq:
|
|
943
|
+
* dtable.floor! -> dtable
|
|
944
|
+
*
|
|
945
|
+
* Replace each entry x of _dtable_ with the largest integer not greater than x.
|
|
946
|
+
*/ VALUE dtable_floor_bang(VALUE ary) {
|
|
947
|
+
return dtable_apply_math_op_bang(ary, floor);
|
|
948
|
+
}
|
|
949
|
+
|
|
950
|
+
PRIVATE
|
|
951
|
+
/*
|
|
952
|
+
* call-seq:
|
|
953
|
+
* dtable.round! -> dtable
|
|
954
|
+
*
|
|
955
|
+
* Replace each entry x of _dtable_ with the integer closest to x.
|
|
956
|
+
* (Numbers midway between integers round away from zero.)
|
|
957
|
+
*/ VALUE dtable_round_bang(VALUE ary) {
|
|
958
|
+
return dtable_apply_math_op_bang(ary, do_round);
|
|
959
|
+
}
|
|
960
|
+
|
|
961
|
+
PRIVATE
|
|
962
|
+
/*
|
|
963
|
+
* call-seq:
|
|
964
|
+
* dtable.exp! -> dtable
|
|
965
|
+
*
|
|
966
|
+
* Replace each entry x of _dtable_ with exp(x).
|
|
967
|
+
*/ VALUE dtable_exp_bang(VALUE ary) {
|
|
968
|
+
return dtable_apply_math_op_bang(ary, exp);
|
|
969
|
+
}
|
|
970
|
+
|
|
971
|
+
PRIVATE
|
|
972
|
+
/*
|
|
973
|
+
* call-seq:
|
|
974
|
+
* dtable.exp10! -> dtable
|
|
975
|
+
*
|
|
976
|
+
* Replace each entry x of _dtable_ with 10**x.
|
|
977
|
+
*/ VALUE dtable_exp10_bang(VALUE ary) {
|
|
978
|
+
return dtable_apply_math_op_bang(ary, do_exp10);
|
|
979
|
+
}
|
|
980
|
+
|
|
981
|
+
PRIVATE
|
|
982
|
+
/*
|
|
983
|
+
* call-seq:
|
|
984
|
+
* dtable.log! -> dtable
|
|
985
|
+
*
|
|
986
|
+
* Replace each entry x of _dtable_ with log(x).
|
|
987
|
+
*/ VALUE dtable_log_bang(VALUE ary) {
|
|
988
|
+
return dtable_apply_math_op_bang(ary, log);
|
|
989
|
+
}
|
|
990
|
+
|
|
991
|
+
PRIVATE
|
|
992
|
+
/*
|
|
993
|
+
* call-seq:
|
|
994
|
+
* dtable.log10! -> dtable
|
|
995
|
+
*
|
|
996
|
+
* Replace each entry x of _dtable_ with log10(x).
|
|
997
|
+
*/ VALUE dtable_log10_bang(VALUE ary) {
|
|
998
|
+
return dtable_apply_math_op_bang(ary, log10);
|
|
999
|
+
}
|
|
1000
|
+
|
|
1001
|
+
PRIVATE
|
|
1002
|
+
/*
|
|
1003
|
+
* call-seq:
|
|
1004
|
+
* dtable.inv! -> dtable
|
|
1005
|
+
*
|
|
1006
|
+
* Replace each entry x of _dtable_ with 1/x.
|
|
1007
|
+
*/ VALUE dtable_inv_bang(VALUE ary) {
|
|
1008
|
+
return dtable_apply_math_op_bang(ary, do_inv);
|
|
1009
|
+
}
|
|
1010
|
+
|
|
1011
|
+
PRIVATE
|
|
1012
|
+
/*
|
|
1013
|
+
* call-seq:
|
|
1014
|
+
* dtable.sqrt! -> dtable
|
|
1015
|
+
*
|
|
1016
|
+
* Replace each entry x of _dtable_ with sqrt(x).
|
|
1017
|
+
*/ VALUE dtable_sqrt_bang(VALUE ary) {
|
|
1018
|
+
return dtable_apply_math_op_bang(ary, sqrt);
|
|
1019
|
+
}
|
|
1020
|
+
|
|
1021
|
+
PRIVATE VALUE dtable_apply_math_op1_bang(VALUE ary, VALUE arg, double (*op)(double, double)) {
|
|
1022
|
+
Dtable *d = Get_Dtable(ary);
|
|
1023
|
+
arg = rb_Float(arg);
|
|
1024
|
+
double y = NUM2DBL(arg), **p = d->ptr;
|
|
1025
|
+
int num_cols = d->num_cols, num_rows = d->num_rows, i, j;
|
|
1026
|
+
for (i = 0; i < num_rows; i++) {
|
|
1027
|
+
for (j = 0; j < num_cols; j++) {
|
|
1028
|
+
p[i][j] = (*op)(p[i][j], y);
|
|
1029
|
+
}
|
|
1030
|
+
}
|
|
1031
|
+
return ary;
|
|
1032
|
+
}
|
|
1033
|
+
|
|
1034
|
+
PRIVATE VALUE dtable_apply_math_op1(VALUE source, VALUE arg, double (*op)(double, double)) {
|
|
1035
|
+
return dtable_apply_math_op1_bang(dtable_dup(source), arg, op);
|
|
1036
|
+
}
|
|
1037
|
+
|
|
1038
|
+
static double do_trim(double x, double cutoff) { return (fabs(x) < cutoff)? 0.0 : x; }
|
|
1039
|
+
|
|
1040
|
+
PRIVATE
|
|
1041
|
+
/*
|
|
1042
|
+
* call-seq:
|
|
1043
|
+
* dtable.trim(cutoff=1e-6) -> a_dtable
|
|
1044
|
+
*
|
|
1045
|
+
* Returns a copy of _dtable_ with any entry with absolute value less than _cutoff_ replaced by 0.
|
|
1046
|
+
*/ VALUE dtable_trim(int argc, VALUE *argv, VALUE self) {
|
|
1047
|
+
VALUE arg1;
|
|
1048
|
+
if ((argc < 0) || (argc > 1))
|
|
1049
|
+
rb_raise(rb_eArgError, "wrong # of arguments(%d for 0 or 1)",argc);
|
|
1050
|
+
arg1 = (argc > 0)? argv[0] : rb_float_new(1e-6);
|
|
1051
|
+
return dtable_apply_math_op1(self, arg1, do_trim);
|
|
1052
|
+
}
|
|
1053
|
+
|
|
1054
|
+
static double do_safe_log(double x, double y) { return log(MAX(x,y)); }
|
|
1055
|
+
|
|
1056
|
+
PRIVATE
|
|
1057
|
+
/*
|
|
1058
|
+
* call-seq:
|
|
1059
|
+
* dtable.safe_log(cutoff=1e-99) -> a_dtable
|
|
1060
|
+
*
|
|
1061
|
+
* Returns a copy of _dtable_ with each entry x replaced by log(max(x,_cutoff_)).
|
|
1062
|
+
*/ VALUE dtable_safe_log(int argc, VALUE *argv, VALUE self) {
|
|
1063
|
+
VALUE arg1;
|
|
1064
|
+
if ((argc < 0) || (argc > 1))
|
|
1065
|
+
rb_raise(rb_eArgError, "wrong # of arguments(%d for 0 or 1)",argc);
|
|
1066
|
+
arg1 = (argc > 0)? argv[0] : rb_float_new(1e-99);
|
|
1067
|
+
return dtable_apply_math_op1(self, arg1, do_safe_log);
|
|
1068
|
+
}
|
|
1069
|
+
|
|
1070
|
+
static double do_safe_log10(double x, double y) { return log10(MAX(x,y)); }
|
|
1071
|
+
|
|
1072
|
+
PRIVATE
|
|
1073
|
+
/*
|
|
1074
|
+
* call-seq:
|
|
1075
|
+
* dtable.safe_log10(cutoff=1e-99) -> a_dtable
|
|
1076
|
+
*
|
|
1077
|
+
* Returns a copy of _dtable_ with each entry x replaced by log10(max(x,_cutoff_)).
|
|
1078
|
+
*
|
|
1079
|
+
*/ VALUE dtable_safe_log10(int argc, VALUE *argv, VALUE self) {
|
|
1080
|
+
VALUE arg1;
|
|
1081
|
+
if ((argc < 0) || (argc > 1))
|
|
1082
|
+
rb_raise(rb_eArgError, "wrong # of arguments(%d for 0 or 1)",argc);
|
|
1083
|
+
arg1 = (argc > 0)? argv[0] : rb_float_new(1e-99);
|
|
1084
|
+
return dtable_apply_math_op1(self, arg1, do_safe_log10);
|
|
1085
|
+
}
|
|
1086
|
+
|
|
1087
|
+
static double do_safe_inv(double x, double y) {
|
|
1088
|
+
return (fabs(x) >= y)? 1.0/x : (x > 0.0)? 1.0/y : -1.0/y; }
|
|
1089
|
+
|
|
1090
|
+
PRIVATE
|
|
1091
|
+
/*
|
|
1092
|
+
* call-seq:
|
|
1093
|
+
* dtable.safe_inv(cutoff=1e-99) -> a_dtable
|
|
1094
|
+
*
|
|
1095
|
+
* Returns a copy of _dtable_ with each entry x replaced by sign(x)/_cutoff_ if abs(x) < _cutoff_, 1/x otherwise.
|
|
1096
|
+
*
|
|
1097
|
+
*/ VALUE dtable_safe_inv(int argc, VALUE *argv, VALUE self) {
|
|
1098
|
+
VALUE arg1;
|
|
1099
|
+
if ((argc < 0) || (argc > 1))
|
|
1100
|
+
rb_raise(rb_eArgError, "wrong # of arguments(%d for 0 or 1)",argc);
|
|
1101
|
+
arg1 = (argc > 0)? argv[0] : rb_float_new(1e-99);
|
|
1102
|
+
return dtable_apply_math_op1(self, arg1, do_safe_inv);
|
|
1103
|
+
}
|
|
1104
|
+
|
|
1105
|
+
static double do_safe_asin(double x) { return asin(MAX(-1.0,MIN(1.0,x))); }
|
|
1106
|
+
|
|
1107
|
+
PRIVATE
|
|
1108
|
+
/*
|
|
1109
|
+
* call-seq:
|
|
1110
|
+
* dtable.safe_asin -> a_dtable
|
|
1111
|
+
*
|
|
1112
|
+
* Returns a copy of _dtable_ with each entry x replaced by asin(max(-1,min(1,x))).
|
|
1113
|
+
*
|
|
1114
|
+
*/ VALUE dtable_safe_asin(VALUE ary) {
|
|
1115
|
+
return dtable_apply_math_op(ary, do_safe_asin);
|
|
1116
|
+
}
|
|
1117
|
+
|
|
1118
|
+
static double do_safe_acos(double x) { return acos(MAX(-1.0,MIN(1.0,x))); }
|
|
1119
|
+
|
|
1120
|
+
PRIVATE
|
|
1121
|
+
/*
|
|
1122
|
+
* call-seq:
|
|
1123
|
+
* dtable.safe_acos -> a_dtable
|
|
1124
|
+
*
|
|
1125
|
+
* Returns a copy of _dtable_ with each entry x replaced by acos(max(-1,min(1,x))).
|
|
1126
|
+
*
|
|
1127
|
+
*/ VALUE dtable_safe_acos(VALUE ary) {
|
|
1128
|
+
return dtable_apply_math_op(ary, do_safe_acos);
|
|
1129
|
+
}
|
|
1130
|
+
|
|
1131
|
+
static double do_safe_sqrt(double x) { return sqrt(MAX(x,0.0)); }
|
|
1132
|
+
|
|
1133
|
+
PRIVATE
|
|
1134
|
+
/*
|
|
1135
|
+
* call-seq:
|
|
1136
|
+
* dtable.safe_sqrt -> a_dtable
|
|
1137
|
+
*
|
|
1138
|
+
* Returns a copy of _dtable_ with each entry x replaced by sqrt(max(x,0)).
|
|
1139
|
+
*
|
|
1140
|
+
*/ VALUE dtable_safe_sqrt(VALUE ary) {
|
|
1141
|
+
return dtable_apply_math_op(ary, do_safe_sqrt);
|
|
1142
|
+
}
|
|
1143
|
+
|
|
1144
|
+
PRIVATE
|
|
1145
|
+
/*
|
|
1146
|
+
* call-seq:
|
|
1147
|
+
* dtable.atan2!(number) -> dtable
|
|
1148
|
+
* dtable.atan2!(other) -> dtable
|
|
1149
|
+
*
|
|
1150
|
+
* When argument is a number, this operation replaces each entry x of _dtable_ by the angle whose tangent is x/_number_.
|
|
1151
|
+
* When argument is a data array, this operation replaces each entry x of _dtable_ by the angle whose tangent is x divided
|
|
1152
|
+
* by the corresponding entry in the _other_ data array.
|
|
1153
|
+
*/ VALUE dtable_atan2_bang(VALUE ary, VALUE arg) {
|
|
1154
|
+
return dtable_apply_math_op2_bang(ary, arg, atan2);
|
|
1155
|
+
}
|
|
1156
|
+
|
|
1157
|
+
static double do_mod(double x, double y) { return x - y * floor(x/y); }
|
|
1158
|
+
PRIVATE
|
|
1159
|
+
/*
|
|
1160
|
+
* call-seq:
|
|
1161
|
+
* dtable.modulo!(number) -> dtable
|
|
1162
|
+
* dtable.mod!(number) -> dtable
|
|
1163
|
+
* dtable.modulo!(other) -> dtable
|
|
1164
|
+
* dtable.mod!(other) -> dtable
|
|
1165
|
+
*
|
|
1166
|
+
* When argument is a number, this operation returns a copy of _dtable_ with each entry x replaced by x % _number_.
|
|
1167
|
+
* When argument is a data array, this operation returns a copy of _dtable_ with each entry x replaced
|
|
1168
|
+
* by x % the corresponding entry in the _other_ data array.
|
|
1169
|
+
*/ VALUE dtable_modulo_bang(VALUE ary, VALUE arg) {
|
|
1170
|
+
return dtable_apply_math_op2_bang(ary, arg, do_mod);
|
|
1171
|
+
}
|
|
1172
|
+
|
|
1173
|
+
static double do_remainder(double x, double y) { return (x*y > 0.0)? do_mod(x,y) : do_mod(x,y)-y; }
|
|
1174
|
+
|
|
1175
|
+
PRIVATE
|
|
1176
|
+
/*
|
|
1177
|
+
* call-seq:
|
|
1178
|
+
* dtable.remainder!(number) -> dtable
|
|
1179
|
+
* dtable.remainder!(other) -> dtable
|
|
1180
|
+
*
|
|
1181
|
+
* When the argument is a number, this operation replaces with each entry x of _dtable_ by the remainder of x divided by _number_.
|
|
1182
|
+
* When the argument is a data array, this operation replaces with each entry x of _dtable_
|
|
1183
|
+
* by remainder of x divided by the corresponding entry in the _other_ data array.
|
|
1184
|
+
*/ VALUE dtable_remainder_bang(VALUE ary, VALUE arg) {
|
|
1185
|
+
return dtable_apply_math_op2_bang(ary, arg, do_remainder);
|
|
1186
|
+
}
|
|
1187
|
+
|
|
1188
|
+
PRIVATE
|
|
1189
|
+
/*
|
|
1190
|
+
* call-seq:
|
|
1191
|
+
* dtable.trim!(cutoff=1e-6) -> dtable
|
|
1192
|
+
*
|
|
1193
|
+
* Each entry x in _dtable_ having absolute value less than _cutoff_ is replaced by 0.
|
|
1194
|
+
*/ VALUE dtable_trim_bang(int argc, VALUE *argv, VALUE self) {
|
|
1195
|
+
VALUE arg1;
|
|
1196
|
+
if ((argc < 0) || (argc > 1))
|
|
1197
|
+
rb_raise(rb_eArgError, "wrong # of arguments(%d for 0 or 1)",argc);
|
|
1198
|
+
arg1 = (argc > 0)? argv[0] : rb_float_new(1e-6);
|
|
1199
|
+
return dtable_apply_math_op1_bang(self, arg1, do_trim);
|
|
1200
|
+
}
|
|
1201
|
+
|
|
1202
|
+
PRIVATE
|
|
1203
|
+
/*
|
|
1204
|
+
* call-seq:
|
|
1205
|
+
* dtable.pow!(number) -> dtable
|
|
1206
|
+
* dtable.pow!(other) -> dtable
|
|
1207
|
+
* dtable.raised_to!(number) -> dtable
|
|
1208
|
+
* dtable.raised_to!(other) -> dtable
|
|
1209
|
+
*
|
|
1210
|
+
* When argument is a number, this operation returns a copy of _dtable_ with each entry x replaced by x ** _number_.
|
|
1211
|
+
* When argument is a data array, this operation returns a copy of _dtable_ with each entry x replaced
|
|
1212
|
+
* by x ** the corresponding entry in the _other_ data array.
|
|
1213
|
+
*/ VALUE dtable_pow_bang(VALUE ary, VALUE arg) {
|
|
1214
|
+
return dtable_apply_math_op1_bang(ary, arg, pow);
|
|
1215
|
+
}
|
|
1216
|
+
|
|
1217
|
+
static double do_as_exponent_of(double x, double y) { return pow(y,x); }
|
|
1218
|
+
|
|
1219
|
+
PRIVATE
|
|
1220
|
+
/*
|
|
1221
|
+
* call-seq:
|
|
1222
|
+
* dtable.as_exponent_of!(number) -> dtable
|
|
1223
|
+
* dtable.as_exponent_of!(other) -> dtable
|
|
1224
|
+
*
|
|
1225
|
+
* When argument is a number, this operation replaces each entry x of _dtable_ by _number_ ** x.
|
|
1226
|
+
* When argument is a data array, this operation replaces each entry x of _dtable_
|
|
1227
|
+
* by the corresponding entry in the _other_ data array raised to the power x.
|
|
1228
|
+
*/ VALUE dtable_as_exponent_of_bang(VALUE ary, VALUE arg) {
|
|
1229
|
+
return dtable_apply_math_op2_bang(ary, arg, do_as_exponent_of);
|
|
1230
|
+
}
|
|
1231
|
+
|
|
1232
|
+
PRIVATE
|
|
1233
|
+
/*
|
|
1234
|
+
* call-seq:
|
|
1235
|
+
* dtable.safe_log!(cutoff=1e-99) -> dtable
|
|
1236
|
+
*
|
|
1237
|
+
* Replaces each entry x in _dtable_ by log(max(x,_cutoff_)).
|
|
1238
|
+
*
|
|
1239
|
+
*/ VALUE dtable_safe_log_bang(int argc, VALUE *argv, VALUE self) {
|
|
1240
|
+
VALUE arg1;
|
|
1241
|
+
if ((argc < 0) || (argc > 1))
|
|
1242
|
+
rb_raise(rb_eArgError, "wrong # of arguments(%d for 0 or 1)",argc);
|
|
1243
|
+
arg1 = (argc > 0)? argv[0] : rb_float_new(1e-99);
|
|
1244
|
+
return dtable_apply_math_op1_bang(self, arg1, do_safe_log);
|
|
1245
|
+
}
|
|
1246
|
+
|
|
1247
|
+
PRIVATE
|
|
1248
|
+
/*
|
|
1249
|
+
* call-seq:
|
|
1250
|
+
* dtable.safe_log10!(cutoff) -> dtable
|
|
1251
|
+
*
|
|
1252
|
+
* Replaces each entry x in _dtable_ by log10(max(x,_cutoff_)).
|
|
1253
|
+
*
|
|
1254
|
+
*/ VALUE dtable_safe_log10_bang(int argc, VALUE *argv, VALUE self) {
|
|
1255
|
+
VALUE arg1;
|
|
1256
|
+
if ((argc < 0) || (argc > 1))
|
|
1257
|
+
rb_raise(rb_eArgError, "wrong # of arguments(%d for 0 or 1)",argc);
|
|
1258
|
+
arg1 = (argc > 0)? argv[0] : rb_float_new(1e-99);
|
|
1259
|
+
return dtable_apply_math_op1_bang(self, arg1, do_safe_log10);
|
|
1260
|
+
}
|
|
1261
|
+
|
|
1262
|
+
PRIVATE
|
|
1263
|
+
/*
|
|
1264
|
+
* call-seq:
|
|
1265
|
+
* dtable.safe_inv!(cutoff) -> dtable
|
|
1266
|
+
*
|
|
1267
|
+
* Replaces each entry x in _dtable_ by sign(x)/_cutoff_ if abs(x) < _cutoff_, 1/x otherwise.
|
|
1268
|
+
*
|
|
1269
|
+
*/ VALUE dtable_safe_inv_bang(int argc, VALUE *argv, VALUE self) {
|
|
1270
|
+
VALUE arg1;
|
|
1271
|
+
if ((argc < 0) || (argc > 1))
|
|
1272
|
+
rb_raise(rb_eArgError, "wrong # of arguments(%d for 0 or 1)",argc);
|
|
1273
|
+
arg1 = (argc > 0)? argv[0] : rb_float_new(1e-99);
|
|
1274
|
+
return dtable_apply_math_op1_bang(self, arg1, do_safe_inv);
|
|
1275
|
+
}
|
|
1276
|
+
|
|
1277
|
+
PRIVATE
|
|
1278
|
+
/*
|
|
1279
|
+
* call-seq:
|
|
1280
|
+
* dtable.safe_sqrt! -> dtable
|
|
1281
|
+
*
|
|
1282
|
+
* Replaces each entry x in _dtable_ by sqrt(max(x,0)).
|
|
1283
|
+
*
|
|
1284
|
+
*/ VALUE dtable_safe_sqrt_bang(VALUE ary) {
|
|
1285
|
+
return dtable_apply_math_op_bang(ary, do_safe_sqrt);
|
|
1286
|
+
}
|
|
1287
|
+
|
|
1288
|
+
PRIVATE
|
|
1289
|
+
/*
|
|
1290
|
+
* call-seq:
|
|
1291
|
+
* dtable.safe_asin! -> dtable
|
|
1292
|
+
*
|
|
1293
|
+
* Replaces each entry x in _dtable_ by asin(max(-1,min(1,x)))..
|
|
1294
|
+
*
|
|
1295
|
+
*/ VALUE dtable_safe_asin_bang(VALUE ary) {
|
|
1296
|
+
return dtable_apply_math_op_bang(ary, do_safe_asin);
|
|
1297
|
+
}
|
|
1298
|
+
|
|
1299
|
+
PRIVATE
|
|
1300
|
+
/*
|
|
1301
|
+
* call-seq:
|
|
1302
|
+
* dtable.safe_acos! -> dtable
|
|
1303
|
+
*
|
|
1304
|
+
* Replaces each entry x in _dtable_ by acos(max(-1,min(1,x)))..
|
|
1305
|
+
*
|
|
1306
|
+
*/ VALUE dtable_safe_acos_bang(VALUE ary) {
|
|
1307
|
+
return dtable_apply_math_op_bang(ary, do_safe_acos);
|
|
1308
|
+
}
|
|
1309
|
+
|
|
1310
|
+
PRIVATE VALUE dtable_apply_math_op2_bang(VALUE ary1, VALUE ary2, double (*op)(double, double)) {
|
|
1311
|
+
VALUE check = rb_obj_is_kind_of(ary2, rb_cNumeric);
|
|
1312
|
+
if (check != Qfalse) { return dtable_apply_math_op1_bang(ary1, ary2, op); }
|
|
1313
|
+
Dtable *d1 = Get_Dtable(ary1);
|
|
1314
|
+
Dtable *d2 = Get_Dtable(ary2);
|
|
1315
|
+
int num_cols = d1->num_cols, num_rows = d1->num_rows, i, j;
|
|
1316
|
+
if (num_cols != d2->num_cols || num_rows != d2->num_rows)
|
|
1317
|
+
rb_raise(rb_eArgError, "Dtable arrays must be same dimension for math operation");
|
|
1318
|
+
double **p1, **p2;
|
|
1319
|
+
p1 = d1->ptr; p2 = d2->ptr;
|
|
1320
|
+
for (i = 0; i < num_rows; i++) {
|
|
1321
|
+
for (j = 0; j < num_cols; j++) {
|
|
1322
|
+
p1[i][j] = (*op)(p1[i][j], p2[i][j]);
|
|
1323
|
+
}
|
|
1324
|
+
}
|
|
1325
|
+
return ary1;
|
|
1326
|
+
}
|
|
1327
|
+
|
|
1328
|
+
PRIVATE VALUE dtable_apply_math_op2(VALUE ary1, VALUE ary2, double (*op)(double, double)) {
|
|
1329
|
+
return dtable_apply_math_op2_bang(dtable_dup(ary1), ary2, op);
|
|
1330
|
+
}
|
|
1331
|
+
|
|
1332
|
+
static double do_add(double x, double y) { return x + y; }
|
|
1333
|
+
PRIVATE
|
|
1334
|
+
/*
|
|
1335
|
+
* call-seq:
|
|
1336
|
+
* dtable.add(number) -> a_dtable
|
|
1337
|
+
* dtable.add(other) -> a_dtable
|
|
1338
|
+
* dtable + number -> a_dtable
|
|
1339
|
+
* number + dtable -> a_dtable
|
|
1340
|
+
* dtable + other -> a_dtable
|
|
1341
|
+
*
|
|
1342
|
+
* When argument is a number, this operation returns a copy of _dtable_ with each entry x replaced by x + _number_.
|
|
1343
|
+
* When argument is a data array, this operation returns a copy of _dtable_ with each entry x replaced
|
|
1344
|
+
* by x + the corresponding entry in the _other_ data array.
|
|
1345
|
+
*/ VALUE dtable_add(VALUE ary, VALUE arg) {
|
|
1346
|
+
return dtable_apply_math_op2(ary, arg, do_add);
|
|
1347
|
+
}
|
|
1348
|
+
|
|
1349
|
+
static double do_sub(double x, double y) { return x - y; }
|
|
1350
|
+
PRIVATE
|
|
1351
|
+
/*
|
|
1352
|
+
* call-seq:
|
|
1353
|
+
* dtable.sub(number) -> a_dtable
|
|
1354
|
+
* dtable.sub(other) -> a_dtable
|
|
1355
|
+
* dtable - number -> a_dtable
|
|
1356
|
+
* number - dtable -> a_dtable
|
|
1357
|
+
* dtable - other -> a_dtable
|
|
1358
|
+
*
|
|
1359
|
+
* When argument is a number, this operation returns a copy of _dtable_ with each entry x replaced by x - _number_.
|
|
1360
|
+
* When argument is a data array, this operation returns a copy of _dtable_ with each entry x replaced
|
|
1361
|
+
* by x - the corresponding entry in the _other_ data array.
|
|
1362
|
+
*/ VALUE dtable_sub(VALUE ary, VALUE arg) {
|
|
1363
|
+
return dtable_apply_math_op2(ary, arg, do_sub);
|
|
1364
|
+
}
|
|
1365
|
+
|
|
1366
|
+
static double do_mul(double x, double y) { return x * y; }
|
|
1367
|
+
PRIVATE
|
|
1368
|
+
/*
|
|
1369
|
+
* call-seq:
|
|
1370
|
+
* dtable.mul(number) -> a_dtable
|
|
1371
|
+
* dtable.mul(other) -> a_dtable
|
|
1372
|
+
* dtable - number -> a_dtable
|
|
1373
|
+
* number - dtable -> a_dtable
|
|
1374
|
+
* dtable - other -> a_dtable
|
|
1375
|
+
*
|
|
1376
|
+
* When argument is a number, this operation returns a copy of _dtable_ with each entry x replaced by x * _number_.
|
|
1377
|
+
* When argument is a data array, this operation returns a copy of _dtable_ with each entry x replaced
|
|
1378
|
+
* by x * the corresponding entry in the _other_ data array.
|
|
1379
|
+
*/ VALUE dtable_mul(VALUE ary, VALUE arg) {
|
|
1380
|
+
return dtable_apply_math_op2(ary, arg, do_mul);
|
|
1381
|
+
}
|
|
1382
|
+
|
|
1383
|
+
static double do_div(double x, double y) { return x / y; }
|
|
1384
|
+
PRIVATE
|
|
1385
|
+
/*
|
|
1386
|
+
* call-seq:
|
|
1387
|
+
* dtable.div(number) -> a_dtable
|
|
1388
|
+
* dtable.div(other) -> a_dtable
|
|
1389
|
+
* dtable - number -> a_dtable
|
|
1390
|
+
* number - dtable -> a_dtable
|
|
1391
|
+
* dtable - other -> a_dtable
|
|
1392
|
+
*
|
|
1393
|
+
* When argument is a number, this operation returns a copy of _dtable_ with each entry x replaced by x / _number_.
|
|
1394
|
+
* When argument is a data array, this operation returns a copy of _dtable_ with each entry x replaced
|
|
1395
|
+
* by x / the corresponding entry in the _other_ data array.
|
|
1396
|
+
*/ VALUE dtable_div(VALUE ary, VALUE arg) {
|
|
1397
|
+
return dtable_apply_math_op2(ary, arg, do_div);
|
|
1398
|
+
}
|
|
1399
|
+
|
|
1400
|
+
PRIVATE
|
|
1401
|
+
/*
|
|
1402
|
+
* call-seq:
|
|
1403
|
+
* dtable.modulo(number) -> a_dtable
|
|
1404
|
+
* dtable.mod(number) -> a_dtable
|
|
1405
|
+
* dtable.modulo(other) -> a_dtable
|
|
1406
|
+
* dtable.mod(other) -> a_dtable
|
|
1407
|
+
* dtable % number -> a_dtable
|
|
1408
|
+
* dtable % other -> a_dtable
|
|
1409
|
+
*
|
|
1410
|
+
* When argument is a number, this operation returns a copy of _dtable_ with each entry x replaced by x % _number_.
|
|
1411
|
+
* When argument is a data array, this operation returns a copy of _dtable_ with each entry x replaced
|
|
1412
|
+
* by x % the corresponding entry in the _other_ data array.
|
|
1413
|
+
*
|
|
1414
|
+
*/ VALUE dtable_mod(VALUE ary, VALUE arg) {
|
|
1415
|
+
return dtable_apply_math_op2(ary, arg, do_mod);
|
|
1416
|
+
}
|
|
1417
|
+
|
|
1418
|
+
PRIVATE
|
|
1419
|
+
/*
|
|
1420
|
+
* call-seq:
|
|
1421
|
+
* dtable.remainder(number) -> a_dtable
|
|
1422
|
+
* dtable.remainder(other) -> a_dtable
|
|
1423
|
+
*
|
|
1424
|
+
* When the argument is a number, this operation returns a copy of _dtable_ with each entry x replaced by the remainder of x divided by _number_.
|
|
1425
|
+
* When the argument is a data array, this operation returns a copy of _dtable_ with each entry x replaced
|
|
1426
|
+
* by the remainder of x divided by the corresponding entry in the _other_ data array.
|
|
1427
|
+
*/ VALUE dtable_remainder(VALUE ary, VALUE arg) {
|
|
1428
|
+
return dtable_apply_math_op2(ary, arg, do_remainder);
|
|
1429
|
+
}
|
|
1430
|
+
|
|
1431
|
+
PRIVATE
|
|
1432
|
+
/*
|
|
1433
|
+
* call-seq:
|
|
1434
|
+
* dtable.pow(number) -> a_dtable
|
|
1435
|
+
* dtable.pow(other) -> a_dtable
|
|
1436
|
+
* dtable.raised_to(number) -> a_dtable
|
|
1437
|
+
* dtable.raised_to(other) -> a_dtable
|
|
1438
|
+
* dtable ** number -> a_dtable
|
|
1439
|
+
* dtable ** other -> a_dtable
|
|
1440
|
+
*
|
|
1441
|
+
* When argument is a number, this operation returns a copy of _dtable_ with each entry x replaced by x ** _number_.
|
|
1442
|
+
* When argument is a data array, this operation returns a copy of _dtable_ with each entry x replaced
|
|
1443
|
+
* by x ** the corresponding entry in the _other_ data array.
|
|
1444
|
+
*
|
|
1445
|
+
*/ VALUE dtable_pow(VALUE ary, VALUE arg) {
|
|
1446
|
+
return dtable_apply_math_op2(ary, arg, pow);
|
|
1447
|
+
}
|
|
1448
|
+
|
|
1449
|
+
PRIVATE
|
|
1450
|
+
/*
|
|
1451
|
+
* call-seq:
|
|
1452
|
+
* dtable.as_exponent_of(number) -> a_dtable
|
|
1453
|
+
* dtable.as_exponent_of(other) -> a_dtable
|
|
1454
|
+
*
|
|
1455
|
+
* When argument is a number, this operation returns a copy of _dtable_ with each entry x replaced by _number_ ** x.
|
|
1456
|
+
* When argument is a data array, this operation returns a copy of _dtable_ with each entry x replaced
|
|
1457
|
+
* by the corresponding entry in the _other_ data array raised to the power x.
|
|
1458
|
+
*/ VALUE dtable_as_exponent_of(VALUE ary, VALUE arg) {
|
|
1459
|
+
return dtable_apply_math_op2(ary, arg, do_as_exponent_of);
|
|
1460
|
+
}
|
|
1461
|
+
|
|
1462
|
+
PRIVATE
|
|
1463
|
+
/*
|
|
1464
|
+
* call-seq:
|
|
1465
|
+
* dtable.atan2(number) -> a_dtable
|
|
1466
|
+
* dtable.atan2(other) -> a_dtable
|
|
1467
|
+
*
|
|
1468
|
+
* When argument is a number, this operation returns a copy of _dtable_ with each entry x replaced by the angle whose tangent is x/_number_.
|
|
1469
|
+
* When argument is a data array, this operation returns a copy of _dtable_ with each entry x replaced
|
|
1470
|
+
* by the angle whose tangent is x divided by the corresponding entry in the _other_ data array.
|
|
1471
|
+
*/ VALUE dtable_atan2(VALUE ary, VALUE arg) {
|
|
1472
|
+
return dtable_apply_math_op2(ary, arg, atan2);
|
|
1473
|
+
}
|
|
1474
|
+
|
|
1475
|
+
PRIVATE
|
|
1476
|
+
/*
|
|
1477
|
+
* call-seq:
|
|
1478
|
+
* dtable.add!(number) -> dtable
|
|
1479
|
+
* dtable.add!(other) -> dtable
|
|
1480
|
+
*
|
|
1481
|
+
* When argument is a number, each entry x in _dtable_ is replaced by x + _number_.
|
|
1482
|
+
* When argument is a data array, each entry x in _dtable_ is replaced by x +
|
|
1483
|
+
* the corresponding entry in the _other_ data array.
|
|
1484
|
+
*/ VALUE dtable_add_bang(VALUE ary, VALUE arg) {
|
|
1485
|
+
return dtable_apply_math_op2_bang(ary, arg, do_add);
|
|
1486
|
+
}
|
|
1487
|
+
|
|
1488
|
+
PRIVATE
|
|
1489
|
+
/*
|
|
1490
|
+
* call-seq:
|
|
1491
|
+
* dtable.sub!(number) -> dtable
|
|
1492
|
+
* dtable.sub!(other) -> dtable
|
|
1493
|
+
*
|
|
1494
|
+
* When argument is a number, each entry x in _dtable_ is replaced by x - _number_.
|
|
1495
|
+
* When argument is a data array, each entry x in _dtable_ is replaced by x -
|
|
1496
|
+
* the corresponding entry in the _other_ data array.
|
|
1497
|
+
*/ VALUE dtable_sub_bang(VALUE ary, VALUE arg) {
|
|
1498
|
+
return dtable_apply_math_op2_bang(ary, arg, do_sub);
|
|
1499
|
+
}
|
|
1500
|
+
|
|
1501
|
+
PRIVATE
|
|
1502
|
+
/*
|
|
1503
|
+
* call-seq:
|
|
1504
|
+
* dtable.mul!(number) -> dtable
|
|
1505
|
+
* dtable.mul!(other) -> dtable
|
|
1506
|
+
*
|
|
1507
|
+
* When argument is a number, each entry x in _dtable_ is replaced by x * _number_.
|
|
1508
|
+
* When argument is a data array, each entry x in _dtable_ is replaced by x *
|
|
1509
|
+
* the corresponding entry in the _other_ data array.
|
|
1510
|
+
*/ VALUE dtable_mul_bang(VALUE ary, VALUE arg) {
|
|
1511
|
+
return dtable_apply_math_op2_bang(ary, arg, do_mul);
|
|
1512
|
+
}
|
|
1513
|
+
|
|
1514
|
+
PRIVATE
|
|
1515
|
+
/*
|
|
1516
|
+
* call-seq:
|
|
1517
|
+
* dtable.div!(number) -> dtable
|
|
1518
|
+
* dtable.div!(other) -> dtable
|
|
1519
|
+
*
|
|
1520
|
+
* When argument is a number, each entry x in _dtable_ is replaced by x / _number_.
|
|
1521
|
+
* When argument is a data array, each entry x in _dtable_ is replaced by x /
|
|
1522
|
+
* the corresponding entry in the _other_ data array.
|
|
1523
|
+
*/ VALUE dtable_div_bang(VALUE ary, VALUE arg) {
|
|
1524
|
+
return dtable_apply_math_op2_bang(ary, arg, do_div);
|
|
1525
|
+
}
|
|
1526
|
+
|
|
1527
|
+
PRIVATE
|
|
1528
|
+
/*======================================================================*/ VALUE Read_Dtable(VALUE dest, char *filename, int skip_lines) {
|
|
1529
|
+
FILE *file = NULL;
|
|
1530
|
+
long num_cols, num_rows;
|
|
1531
|
+
int i, j, k;
|
|
1532
|
+
const int buff_len = 10000;
|
|
1533
|
+
char c, buff[buff_len], *p, *pend;
|
|
1534
|
+
double *data, **ptr = Dtable_Ptr(dest, &num_cols, &num_rows);
|
|
1535
|
+
if ((file=fopen(filename,"r")) == NULL)
|
|
1536
|
+
rb_raise(rb_eArgError, "failed to open %s", filename);
|
|
1537
|
+
for (i = 0; i < skip_lines; i++) { /* skip over initial lines */
|
|
1538
|
+
if (fgets(buff, buff_len, file)==NULL) {
|
|
1539
|
+
fclose(file);
|
|
1540
|
+
rb_raise(rb_eArgError, "ERROR: read reached end of file before reaching line %i in %s",
|
|
1541
|
+
skip_lines, filename);
|
|
1542
|
+
}
|
|
1543
|
+
}
|
|
1544
|
+
|
|
1545
|
+
// rewrite to use strtod instead of fscanf to deal with numbers from fortran like 0.501-129 for 0.501E-129
|
|
1546
|
+
|
|
1547
|
+
for (i = 0; i < num_rows; i++) {
|
|
1548
|
+
data = ptr[i];
|
|
1549
|
+
for (j = 0; j < num_cols; j++) {
|
|
1550
|
+
// skip over blanks (includes end-of-line and tab)
|
|
1551
|
+
p = buff; k = 0;
|
|
1552
|
+
while ((c=getc(file)) != EOF) {
|
|
1553
|
+
if (!isspace(c)) break;
|
|
1554
|
+
}
|
|
1555
|
+
// save the non-blanks
|
|
1556
|
+
*p++ = c;
|
|
1557
|
+
while ((c=getc(file)) != EOF) {
|
|
1558
|
+
if (isspace(c) || k > 1000) break;
|
|
1559
|
+
*p++ = c;
|
|
1560
|
+
}
|
|
1561
|
+
*p = ' ';
|
|
1562
|
+
data[j] = strtod(buff,&pend);
|
|
1563
|
+
if (pend != p) { // need to check to see if have a number like 0.501-129
|
|
1564
|
+
if (pend[0] == '+' || pend[0] == '-') { // insert 'E' and try again
|
|
1565
|
+
pend[5] = ' '; pend[4] = pend[3]; pend[3] = pend[2]; pend[2] = pend[1]; pend[1] = pend[0]; pend[0] = 'E';
|
|
1566
|
+
data[j] = strtod(buff,&pend);
|
|
1567
|
+
}
|
|
1568
|
+
}
|
|
1569
|
+
if (!is_okay_number(data[j])) {
|
|
1570
|
+
fclose(file);
|
|
1571
|
+
rb_raise(rb_eArgError,
|
|
1572
|
+
"reached end of file before reading requested amount of data in %s (asked for %i xs and %i ys; found only %i and %i)",
|
|
1573
|
+
filename, num_cols, num_rows, i+1, j);
|
|
1574
|
+
}
|
|
1575
|
+
}
|
|
1576
|
+
}
|
|
1577
|
+
fclose(file);
|
|
1578
|
+
return dest;
|
|
1579
|
+
}
|
|
1580
|
+
|
|
1581
|
+
|
|
1582
|
+
PRIVATE
|
|
1583
|
+
/*
|
|
1584
|
+
* call-seq:
|
|
1585
|
+
* dtable.read(filename, skip_lines=0) -> dtable
|
|
1586
|
+
*
|
|
1587
|
+
* The contents of _dtable_ are replaced by the contents of the file, starting after skipping
|
|
1588
|
+
* the specified number of lines. The values in the file are listed with row number 0 first.
|
|
1589
|
+
*
|
|
1590
|
+
*/ VALUE dtable_read(int argc, VALUE *argv, VALUE self) {
|
|
1591
|
+
if ((argc < 1) || (argc > 2))
|
|
1592
|
+
rb_raise(rb_eArgError, "wrong # of arguments(%d for 1 or 2)",argc);
|
|
1593
|
+
VALUE filename = argv[0];
|
|
1594
|
+
int skip_lines = (argc==2)? NUM2INT(rb_Integer(argv[1])) : 0;
|
|
1595
|
+
return Read_Dtable(self, StringValuePtr(filename), skip_lines);
|
|
1596
|
+
}
|
|
1597
|
+
|
|
1598
|
+
PRIVATE VALUE dtable_entry(VALUE ary, long i, long j) {
|
|
1599
|
+
Dtable *d = Get_Dtable(ary);
|
|
1600
|
+
if (d->num_cols <= 0 || d->num_rows <= 0) return Qnil;
|
|
1601
|
+
if (i < 0) i += d->num_rows;
|
|
1602
|
+
if (j < 0) j += d->num_cols;
|
|
1603
|
+
if (i < 0 || d->num_rows <= i || j < 0 || d->num_cols <= j) return Qnil;
|
|
1604
|
+
return rb_float_new(d->ptr[i][j]);
|
|
1605
|
+
}
|
|
1606
|
+
|
|
1607
|
+
PRIVATE
|
|
1608
|
+
/*
|
|
1609
|
+
* call-seq:
|
|
1610
|
+
* dtable[row,col] -> number or nil
|
|
1611
|
+
* dtable.at(row,col) -> number or nil
|
|
1612
|
+
*
|
|
1613
|
+
* Returns the element at location _row_, _col_. Returns +nil+
|
|
1614
|
+
* if the location is out of range.
|
|
1615
|
+
*/ VALUE dtable_at(VALUE ary, VALUE xloc, VALUE yloc) {
|
|
1616
|
+
return dtable_entry(ary, NUM2LONG(xloc), NUM2LONG(yloc));
|
|
1617
|
+
}
|
|
1618
|
+
|
|
1619
|
+
void dtable_store(VALUE ary, long i, long j, double v) {
|
|
1620
|
+
double **ptr;
|
|
1621
|
+
long num_cols, num_rows;
|
|
1622
|
+
ptr = Dtable_Ptr(ary, &num_cols, &num_rows);
|
|
1623
|
+
if (num_cols <= 0 || num_rows <= 0) {
|
|
1624
|
+
rb_raise(rb_eArgError, "bad args for setting entry in data array");
|
|
1625
|
+
}
|
|
1626
|
+
if (i < 0) i += num_rows;
|
|
1627
|
+
if (j < 0) j += num_cols;
|
|
1628
|
+
if (i < 0 || num_rows <= i || j < 0 || num_cols <= j) {
|
|
1629
|
+
rb_raise(rb_eArgError, "bad args for setting entry in data array");
|
|
1630
|
+
}
|
|
1631
|
+
ptr[i][j] = v;
|
|
1632
|
+
}
|
|
1633
|
+
|
|
1634
|
+
PRIVATE
|
|
1635
|
+
/*
|
|
1636
|
+
* call-seq:
|
|
1637
|
+
* dtable[row,col] = number -> number
|
|
1638
|
+
*
|
|
1639
|
+
* Replaces the element at location _row_, _col_ by the given _number_.
|
|
1640
|
+
*/
|
|
1641
|
+
VALUE dtable_aset(VALUE ary, VALUE xloc, VALUE yloc, VALUE val) {
|
|
1642
|
+
dtable_store(ary, NUM2LONG(xloc), NUM2LONG(yloc), NUM2DBL(val));
|
|
1643
|
+
return val;
|
|
1644
|
+
}
|
|
1645
|
+
|
|
1646
|
+
#define DTABLE_DUMP_VERSION 1
|
|
1647
|
+
|
|
1648
|
+
PRIVATE
|
|
1649
|
+
/*
|
|
1650
|
+
Called by the marshalling mechanism to store a permanent copy of a
|
|
1651
|
+
Dtable. _limit_ is simply ignored.
|
|
1652
|
+
*/
|
|
1653
|
+
VALUE dtable_dump(VALUE ary, VALUE limit)
|
|
1654
|
+
{
|
|
1655
|
+
int i; /* for STORE_UNSIGNED */
|
|
1656
|
+
long rows, cols;
|
|
1657
|
+
long x, y;
|
|
1658
|
+
double ** data = Dtable_Ptr(ary, &cols, &rows);
|
|
1659
|
+
double * col;
|
|
1660
|
+
long target_len = 1 /* first signature byte */
|
|
1661
|
+
+ 8 /* 2 * length */
|
|
1662
|
+
+ cols * rows * 8 ;
|
|
1663
|
+
unsigned u_len;
|
|
1664
|
+
VALUE str = rb_str_buf_new(target_len);
|
|
1665
|
+
/* \begin{playing with ruby's internals} */
|
|
1666
|
+
unsigned char * ptr = (unsigned char *) RSTRING(str)->ptr;
|
|
1667
|
+
/* signature byte */
|
|
1668
|
+
(*ptr++) = DTABLE_DUMP_VERSION;
|
|
1669
|
+
u_len = (unsigned) rows; /* limits to 4 billions rows */
|
|
1670
|
+
STORE_UNSIGNED(u_len, ptr); /* destroys u_len */
|
|
1671
|
+
u_len = (unsigned) cols; /* limits to 4 billions columns */
|
|
1672
|
+
STORE_UNSIGNED(u_len, ptr); /* destroys u_len */
|
|
1673
|
+
for(x = 0; x < rows; x++)
|
|
1674
|
+
{
|
|
1675
|
+
col = data[x];
|
|
1676
|
+
for(y = 0; y < cols; y++)
|
|
1677
|
+
{
|
|
1678
|
+
store_double(*(col++), ptr);
|
|
1679
|
+
ptr += 8;
|
|
1680
|
+
}
|
|
1681
|
+
}
|
|
1682
|
+
RSTRING(str)->len = target_len;
|
|
1683
|
+
return str;
|
|
1684
|
+
/* \end{playing with ruby's internals} */
|
|
1685
|
+
}
|
|
1686
|
+
|
|
1687
|
+
PRIVATE
|
|
1688
|
+
/*
|
|
1689
|
+
Called by the marshalling mechanism to retrieve a permanent copy of a
|
|
1690
|
+
Dtable.
|
|
1691
|
+
*/
|
|
1692
|
+
VALUE dtable_load(VALUE klass, VALUE str)
|
|
1693
|
+
{
|
|
1694
|
+
VALUE ret = Qnil;
|
|
1695
|
+
VALUE s = StringValue(str);
|
|
1696
|
+
unsigned char * buf = (unsigned char *) StringValuePtr(s);
|
|
1697
|
+
unsigned char * dest = buf + RSTRING(s)->len;
|
|
1698
|
+
unsigned i; /* for GET_UNSIGNED */
|
|
1699
|
+
unsigned tmp = 0;
|
|
1700
|
+
long rows, cols;
|
|
1701
|
+
long x,y;
|
|
1702
|
+
double ** data;
|
|
1703
|
+
double * col;
|
|
1704
|
+
/* depending on the first byte, the decoding will be different */
|
|
1705
|
+
switch(*(buf++))
|
|
1706
|
+
{
|
|
1707
|
+
case 1:
|
|
1708
|
+
GET_UNSIGNED(tmp, buf);
|
|
1709
|
+
rows = tmp;
|
|
1710
|
+
GET_UNSIGNED(tmp, buf);
|
|
1711
|
+
cols = tmp;
|
|
1712
|
+
/* create a new Dtable with the right size */
|
|
1713
|
+
ret = dtable_init(dtable_alloc(cDtable), cols, rows);
|
|
1714
|
+
data = Dtable_Ptr(ret, NULL, NULL);
|
|
1715
|
+
for(x = 0; x < rows; x++)
|
|
1716
|
+
{
|
|
1717
|
+
col = data[x];
|
|
1718
|
+
for(y = 0; y< cols; y++)
|
|
1719
|
+
{
|
|
1720
|
+
if(buf + 8 > dest)
|
|
1721
|
+
{
|
|
1722
|
+
rb_raise(rb_eRuntimeError,
|
|
1723
|
+
"corrupted data given to Dtable._load");
|
|
1724
|
+
break;
|
|
1725
|
+
}
|
|
1726
|
+
else
|
|
1727
|
+
{
|
|
1728
|
+
col[y] = get_double(buf);
|
|
1729
|
+
buf += 8;
|
|
1730
|
+
}
|
|
1731
|
+
}
|
|
1732
|
+
}
|
|
1733
|
+
break;
|
|
1734
|
+
default:
|
|
1735
|
+
rb_raise(rb_eRuntimeError, "corrupted data given to Dtable._load");
|
|
1736
|
+
}
|
|
1737
|
+
return ret;
|
|
1738
|
+
}
|
|
1739
|
+
|
|
1740
|
+
/*
|
|
1741
|
+
* Document-class: Dobjects::Dtable
|
|
1742
|
+
*
|
|
1743
|
+
* Dtables are a specialized implementation of two-dimensional arrays of double precision floating point numbers.
|
|
1744
|
+
* They are intended for use in applications needing efficient processing of large 2D tables of numeric data.
|
|
1745
|
+
* Essentially any of the operations you might do with a Ruby Array of numbers can also be done with a Dtable.
|
|
1746
|
+
* Dtables follow the same design philosophy as Dvector and uses Dvectors for several operations.
|
|
1747
|
+
*/
|
|
1748
|
+
|
|
1749
|
+
|
|
1750
|
+
PUBLIC void Init_Dtable() {
|
|
1751
|
+
/* modified by Vincent Fourmond, for splitting out the libraries */
|
|
1752
|
+
|
|
1753
|
+
rb_require("Dobjects/Dvector");
|
|
1754
|
+
/* we first make sure Dvector is included */
|
|
1755
|
+
VALUE mDobjects = rb_define_module("Dobjects");
|
|
1756
|
+
cDtable = rb_define_class_under(mDobjects, "Dtable", rb_cObject);
|
|
1757
|
+
/* end of modification */
|
|
1758
|
+
|
|
1759
|
+
rb_define_alloc_func(cDtable, dtable_alloc);
|
|
1760
|
+
rb_define_method(cDtable, "initialize", dtable_initialize, -1);
|
|
1761
|
+
|
|
1762
|
+
rb_define_method(cDtable, "read", dtable_read, -1);
|
|
1763
|
+
|
|
1764
|
+
rb_define_method(cDtable, "num_cols", dtable_num_cols, 0);
|
|
1765
|
+
rb_define_method(cDtable, "num_rows", dtable_num_rows, 0);
|
|
1766
|
+
|
|
1767
|
+
rb_define_method(cDtable, "at", dtable_at, 2);
|
|
1768
|
+
rb_define_alias(cDtable, "[]", "at");
|
|
1769
|
+
rb_define_method(cDtable, "[]=", dtable_aset, 3);
|
|
1770
|
+
|
|
1771
|
+
rb_define_method(cDtable, "row", dtable_row, 1);
|
|
1772
|
+
rb_define_method(cDtable, "column", dtable_column, 1);
|
|
1773
|
+
rb_define_method(cDtable, "set_row", dtable_set_row, 2);
|
|
1774
|
+
rb_define_method(cDtable, "set_column", dtable_set_column, 2);
|
|
1775
|
+
|
|
1776
|
+
rb_define_method(cDtable, "clear", dtable_clear, 0);
|
|
1777
|
+
rb_define_method(cDtable, "set", dtable_set, 1);
|
|
1778
|
+
rb_define_method(cDtable, "max", dtable_max, 0);
|
|
1779
|
+
rb_define_method(cDtable, "min", dtable_min, 0);
|
|
1780
|
+
rb_define_method(cDtable, "min_gt", dtable_min_gt, 1);
|
|
1781
|
+
rb_define_method(cDtable, "max_lt", dtable_max_lt, 1);
|
|
1782
|
+
|
|
1783
|
+
rb_define_method(cDtable, "dup", dtable_dup, 0);
|
|
1784
|
+
rb_define_method(cDtable, "transpose", dtable_transpose, 0);
|
|
1785
|
+
rb_define_method(cDtable, "reverse_rows", dtable_reverse_rows, 0);
|
|
1786
|
+
rb_define_method(cDtable, "reverse_cols", dtable_reverse_cols, 0);
|
|
1787
|
+
rb_define_method(cDtable, "rotate_cw90", dtable_rotate_cw90, 0);
|
|
1788
|
+
rb_define_method(cDtable, "rotate_ccw90", dtable_rotate_ccw90, 0);
|
|
1789
|
+
|
|
1790
|
+
/* math operations */
|
|
1791
|
+
rb_define_method(cDtable, "add", dtable_add, 1);
|
|
1792
|
+
rb_define_alias(cDtable, "+", "add");
|
|
1793
|
+
rb_define_alias(cDtable, "plus", "add");
|
|
1794
|
+
rb_define_method(cDtable, "sub", dtable_sub, 1);
|
|
1795
|
+
rb_define_alias(cDtable, "-", "sub");
|
|
1796
|
+
rb_define_alias(cDtable, "minus", "sub");
|
|
1797
|
+
rb_define_method(cDtable, "mul", dtable_mul, 1);
|
|
1798
|
+
rb_define_alias(cDtable, "*", "mul");
|
|
1799
|
+
rb_define_alias(cDtable, "times", "mul");
|
|
1800
|
+
rb_define_method(cDtable, "div", dtable_div, 1);
|
|
1801
|
+
rb_define_alias(cDtable, "/", "div");
|
|
1802
|
+
rb_define_method(cDtable, "modulo", dtable_mod, 1);
|
|
1803
|
+
rb_define_alias(cDtable, "mod", "modulo");
|
|
1804
|
+
rb_define_alias(cDtable, "%", "modulo");
|
|
1805
|
+
rb_define_method(cDtable, "remainder", dtable_remainder, 1);
|
|
1806
|
+
rb_define_method(cDtable, "pow", dtable_pow, 1);
|
|
1807
|
+
rb_define_alias(cDtable, "raised_to", "pow");
|
|
1808
|
+
rb_define_alias(cDtable, "**", "pow");
|
|
1809
|
+
rb_define_method(cDtable, "as_exponent_of", dtable_as_exponent_of, 1);
|
|
1810
|
+
rb_define_method(cDtable, "atan2", dtable_atan2, 1);
|
|
1811
|
+
|
|
1812
|
+
/* numeric methods */
|
|
1813
|
+
rb_define_method(cDtable, "abs", dtable_abs, 0);
|
|
1814
|
+
rb_define_method(cDtable, "ceil", dtable_ceil, 0);
|
|
1815
|
+
rb_define_method(cDtable, "floor", dtable_floor, 0);
|
|
1816
|
+
rb_define_method(cDtable, "round", dtable_round, 0);
|
|
1817
|
+
|
|
1818
|
+
/* standard math functions */
|
|
1819
|
+
rb_define_method(cDtable, "acos", dtable_acos, 0);
|
|
1820
|
+
rb_define_method(cDtable, "acosh", dtable_acosh, 0);
|
|
1821
|
+
rb_define_method(cDtable, "asin", dtable_asin, 0);
|
|
1822
|
+
rb_define_method(cDtable, "asinh", dtable_asinh, 0);
|
|
1823
|
+
rb_define_method(cDtable, "atan", dtable_atan, 0);
|
|
1824
|
+
rb_define_method(cDtable, "atanh", dtable_atanh, 0);
|
|
1825
|
+
rb_define_method(cDtable, "cos", dtable_cos, 0);
|
|
1826
|
+
rb_define_method(cDtable, "cosh", dtable_cosh, 0);
|
|
1827
|
+
rb_define_method(cDtable, "exp", dtable_exp, 0);
|
|
1828
|
+
rb_define_method(cDtable, "log", dtable_log, 0);
|
|
1829
|
+
rb_define_method(cDtable, "log10", dtable_log10, 0);
|
|
1830
|
+
rb_define_method(cDtable, "sin", dtable_sin, 0);
|
|
1831
|
+
rb_define_method(cDtable, "sinh", dtable_sinh, 0);
|
|
1832
|
+
rb_define_method(cDtable, "sqrt", dtable_sqrt, 0);
|
|
1833
|
+
rb_define_method(cDtable, "tan", dtable_tan, 0);
|
|
1834
|
+
rb_define_method(cDtable, "tanh", dtable_tanh, 0);
|
|
1835
|
+
|
|
1836
|
+
/* nonstandard math functions */
|
|
1837
|
+
rb_define_method(cDtable, "neg", dtable_neg, 0);
|
|
1838
|
+
rb_define_method(cDtable, "exp10", dtable_exp10, 0);
|
|
1839
|
+
rb_define_method(cDtable, "inv", dtable_inv, 0);
|
|
1840
|
+
rb_define_method(cDtable, "trim", dtable_trim, -1);
|
|
1841
|
+
rb_define_method(cDtable, "safe_log", dtable_safe_log, -1);
|
|
1842
|
+
rb_define_method(cDtable, "safe_log10", dtable_safe_log10, -1);
|
|
1843
|
+
rb_define_method(cDtable, "safe_inv", dtable_safe_inv, -1);
|
|
1844
|
+
rb_define_method(cDtable, "safe_sqrt", dtable_safe_sqrt, 0);
|
|
1845
|
+
rb_define_method(cDtable, "safe_asin", dtable_safe_asin, 0);
|
|
1846
|
+
rb_define_method(cDtable, "safe_acos", dtable_safe_acos, 0);
|
|
1847
|
+
|
|
1848
|
+
rb_define_method(cDtable, "add!", dtable_add_bang, 1);
|
|
1849
|
+
rb_define_alias(cDtable, "plus!", "add!");
|
|
1850
|
+
rb_define_method(cDtable, "sub!", dtable_sub_bang, 1);
|
|
1851
|
+
rb_define_alias(cDtable, "minus!", "sub!");
|
|
1852
|
+
rb_define_method(cDtable, "mul!", dtable_mul_bang, 1);
|
|
1853
|
+
rb_define_alias(cDtable, "times!", "mul!");
|
|
1854
|
+
rb_define_method(cDtable, "div!", dtable_div_bang, 1);
|
|
1855
|
+
rb_define_method(cDtable, "modulo!", dtable_modulo_bang, 1);
|
|
1856
|
+
rb_define_alias(cDtable, "mod!", "modulo!");
|
|
1857
|
+
rb_define_method(cDtable, "remainder!", dtable_remainder_bang, 1);
|
|
1858
|
+
rb_define_method(cDtable, "pow!", dtable_pow_bang, 1);
|
|
1859
|
+
rb_define_alias(cDtable, "raised_to!", "pow!");
|
|
1860
|
+
rb_define_method(cDtable, "as_exponent_of!", dtable_as_exponent_of_bang, 1);
|
|
1861
|
+
rb_define_method(cDtable, "atan2!", dtable_atan2_bang, 1);
|
|
1862
|
+
|
|
1863
|
+
rb_define_method(cDtable, "neg!", dtable_neg_bang, 0);
|
|
1864
|
+
rb_define_method(cDtable, "abs!", dtable_abs_bang, 0);
|
|
1865
|
+
rb_define_method(cDtable, "sin!", dtable_sin_bang, 0);
|
|
1866
|
+
rb_define_method(cDtable, "cos!", dtable_cos_bang, 0);
|
|
1867
|
+
rb_define_method(cDtable, "tan!", dtable_tan_bang, 0);
|
|
1868
|
+
rb_define_method(cDtable, "asin!", dtable_asin_bang, 0);
|
|
1869
|
+
rb_define_method(cDtable, "acos!", dtable_acos_bang, 0);
|
|
1870
|
+
rb_define_method(cDtable, "atan!", dtable_atan_bang, 0);
|
|
1871
|
+
rb_define_method(cDtable, "sinh!", dtable_sinh_bang, 0);
|
|
1872
|
+
rb_define_method(cDtable, "cosh!", dtable_cosh_bang, 0);
|
|
1873
|
+
rb_define_method(cDtable, "tanh!", dtable_tanh_bang, 0);
|
|
1874
|
+
rb_define_method(cDtable, "asinh!", dtable_asinh_bang, 0);
|
|
1875
|
+
rb_define_method(cDtable, "acosh!", dtable_acosh_bang, 0);
|
|
1876
|
+
rb_define_method(cDtable, "atanh!", dtable_atanh_bang, 0);
|
|
1877
|
+
rb_define_method(cDtable, "ceil!", dtable_ceil_bang, 0);
|
|
1878
|
+
rb_define_method(cDtable, "floor!", dtable_floor_bang, 0);
|
|
1879
|
+
rb_define_method(cDtable, "round!", dtable_round_bang, 0);
|
|
1880
|
+
rb_define_method(cDtable, "exp!", dtable_exp_bang, 0);
|
|
1881
|
+
rb_define_method(cDtable, "exp10!", dtable_exp10_bang, 0);
|
|
1882
|
+
rb_define_method(cDtable, "log!", dtable_log_bang, 0);
|
|
1883
|
+
rb_define_method(cDtable, "log10!", dtable_log10_bang, 0);
|
|
1884
|
+
rb_define_method(cDtable, "inv!", dtable_inv_bang, 0);
|
|
1885
|
+
rb_define_method(cDtable, "sqrt!", dtable_sqrt_bang, 0);
|
|
1886
|
+
|
|
1887
|
+
rb_define_method(cDtable, "trim!", dtable_trim_bang, -1);
|
|
1888
|
+
rb_define_method(cDtable, "safe_log!", dtable_safe_log_bang, -1);
|
|
1889
|
+
rb_define_method(cDtable, "safe_log10!", dtable_safe_log10_bang, -1);
|
|
1890
|
+
rb_define_method(cDtable, "safe_inv!", dtable_safe_inv_bang, -1);
|
|
1891
|
+
rb_define_method(cDtable, "safe_sqrt!", dtable_safe_sqrt_bang, 0);
|
|
1892
|
+
rb_define_method(cDtable, "safe_asin!", dtable_safe_asin_bang, 0);
|
|
1893
|
+
rb_define_method(cDtable, "safe_acos!", dtable_safe_acos_bang, 0);
|
|
1894
|
+
|
|
1895
|
+
/* Marshal : */
|
|
1896
|
+
rb_define_method(cDtable, "_dump", dtable_dump, 1);
|
|
1897
|
+
rb_define_singleton_method(cDtable, "_load", dtable_load, 1);
|
|
1898
|
+
/* modified by Vincent Fourmond, for splitting out the libraries */
|
|
1899
|
+
rb_require("Dobjects/Dtable_extras.rb");
|
|
1900
|
+
/* end of modification */
|
|
1901
|
+
|
|
1902
|
+
/* first, we export the symbols needed by other libraries
|
|
1903
|
+
see include/dtable.h for their description
|
|
1904
|
+
*/
|
|
1905
|
+
RB_EXPORT_SYMBOL(cDtable, Read_Dtable);
|
|
1906
|
+
RB_EXPORT_SYMBOL(cDtable, Dtable_Ptr);
|
|
1907
|
+
|
|
1908
|
+
/* now we import the symbols from Dvector */
|
|
1909
|
+
|
|
1910
|
+
VALUE cDvector = rb_define_class_under(mDobjects, "Dvector", rb_cObject);
|
|
1911
|
+
RB_IMPORT_SYMBOL(cDvector, Dvector_Create);
|
|
1912
|
+
RB_IMPORT_SYMBOL(cDvector, Dvector_Data_Resize);
|
|
1913
|
+
RB_IMPORT_SYMBOL(cDvector, Dvector_Data_Replace);
|
|
1914
|
+
RB_IMPORT_SYMBOL(cDvector, Dvector_Data_for_Read);
|
|
1915
|
+
RB_IMPORT_SYMBOL(cDvector, Dvector_Store_Double);
|
|
1916
|
+
|
|
1917
|
+
}
|
|
1918
|
+
|
|
1919
|
+
/* implementing the symnbols just means that the location
|
|
1920
|
+
of the global variable with the pointer function will be here
|
|
1921
|
+
*/
|
|
1922
|
+
IMPLEMENT_SYMBOL(Dvector_Create);
|
|
1923
|
+
IMPLEMENT_SYMBOL(Dvector_Data_Resize);
|
|
1924
|
+
IMPLEMENT_SYMBOL(Dvector_Data_Replace);
|
|
1925
|
+
IMPLEMENT_SYMBOL(Dvector_Data_for_Read);
|
|
1926
|
+
IMPLEMENT_SYMBOL(Dvector_Store_Double);
|
|
1927
|
+
|
|
1928
|
+
|