tioga 1.11 → 1.13
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 +58 -35
- data/{split/scripts → bin}/tioga +1 -1
- data/{split → ext/Dobjects}/Dtable/dtable.c +81 -15
- data/{split → ext/Dobjects}/Dtable/dtable_intern.h +0 -0
- data/ext/Dobjects/Dtable/extconf.rb +7 -0
- data/{split → ext/Dobjects}/Dtable/include/dtable.h +0 -0
- data/{split → ext/Dobjects}/Dvector/dvector.c +361 -51
- data/{split → ext/Dobjects}/Dvector/dvector_intern.h +0 -0
- data/ext/Dobjects/Dvector/extconf.rb +22 -0
- data/{split/Dtable → ext/Dobjects/Dvector/include}/dvector.h +0 -0
- data/ext/Dobjects/Function/extconf.rb +7 -0
- data/{split → ext/Dobjects}/Function/function.c +636 -11
- data/{split → ext/Dobjects}/Function/joint_qsort.c +0 -0
- data/ext/Flate/extconf.rb +26 -0
- data/{split → ext}/Flate/flate.c +7 -3
- data/{split → ext}/Flate/flate_intern.h +0 -0
- data/{split → ext}/Flate/include/flate.h +0 -0
- data/ext/Flate/zlib/adler32.c +149 -0
- data/ext/Flate/zlib/compress.c +79 -0
- data/ext/Flate/zlib/crc32.c +423 -0
- data/ext/Flate/zlib/crc32.h +441 -0
- data/ext/Flate/zlib/deflate.c +1736 -0
- data/ext/Flate/zlib/deflate.h +331 -0
- data/ext/Flate/zlib/gzio.c +1026 -0
- data/ext/Flate/zlib/infback.c +623 -0
- data/ext/Flate/zlib/inffast.c +318 -0
- data/ext/Flate/zlib/inffast.h +11 -0
- data/ext/Flate/zlib/inffixed.h +94 -0
- data/ext/Flate/zlib/inflate.c +1368 -0
- data/ext/Flate/zlib/inflate.h +115 -0
- data/ext/Flate/zlib/inftrees.c +329 -0
- data/ext/Flate/zlib/inftrees.h +55 -0
- data/ext/Flate/zlib/trees.c +1219 -0
- data/ext/Flate/zlib/trees.h +128 -0
- data/ext/Flate/zlib/uncompr.c +61 -0
- data/ext/Flate/zlib/zlib.h +1357 -0
- data/ext/Flate/zlib/zutil.c +318 -0
- data/ext/Flate/zlib/zutil.h +269 -0
- data/ext/Tioga/FigureMaker/__shared_axes.c +1373 -0
- data/ext/Tioga/FigureMaker/__shared_makers.c +1303 -0
- data/{split/Tioga/pdf_font_dicts.c → ext/Tioga/FigureMaker/__shared_pdf_font_dicts.c} +0 -0
- data/{split/Tioga/pdfcolor.c → ext/Tioga/FigureMaker/__shared_pdfcolor.c} +0 -0
- data/{split/Tioga/pdfcoords.c → ext/Tioga/FigureMaker/__shared_pdfcoords.c} +0 -0
- data/{split/Tioga/pdffile.c → ext/Tioga/FigureMaker/__shared_pdffile.c} +0 -0
- data/{split/Tioga/pdfimage.c → ext/Tioga/FigureMaker/__shared_pdfimage.c} +0 -0
- data/{split/Tioga/pdfpath.c → ext/Tioga/FigureMaker/__shared_pdfpath.c} +0 -0
- data/{split/Tioga/pdftext.c → ext/Tioga/FigureMaker/__shared_pdftext.c} +0 -0
- data/{split/Tioga/texout.c → ext/Tioga/FigureMaker/__shared_texout.c} +0 -0
- data/ext/Tioga/FigureMaker/extconf.rb +7 -0
- data/{split/Tioga → ext/Tioga/FigureMaker}/figures.c +14 -2
- data/{split/Tioga → ext/Tioga/FigureMaker}/figures.h +0 -0
- data/{split/Tioga → ext/Tioga/FigureMaker}/generic.c +1 -2
- data/{split/Tioga → ext/Tioga/FigureMaker}/generic.h +0 -1
- data/{split/Tioga → ext/Tioga/FigureMaker}/init.c +0 -0
- data/{split/Tioga → ext/Tioga/FigureMaker}/pdfs.h +0 -0
- data/{split/Tioga → ext/Tioga/FigureMaker/shared}/axes.c +32 -7
- data/{split/Tioga → ext/Tioga/FigureMaker/shared}/makers.c +2 -2
- data/ext/Tioga/FigureMaker/shared/pdf_font_dicts.c +18253 -0
- data/ext/Tioga/FigureMaker/shared/pdfcolor.c +904 -0
- data/ext/Tioga/FigureMaker/shared/pdfcoords.c +518 -0
- data/ext/Tioga/FigureMaker/shared/pdffile.c +451 -0
- data/ext/Tioga/FigureMaker/shared/pdfimage.c +539 -0
- data/ext/Tioga/FigureMaker/shared/pdfpath.c +766 -0
- data/ext/Tioga/FigureMaker/shared/pdftext.c +710 -0
- data/ext/Tioga/FigureMaker/shared/texout.c +533 -0
- data/{split/Tioga → ext/Tioga/FigureMaker}/wrappers.c +5 -5
- data/{split/Tioga → ext/Tioga/FigureMaker}/wrappers.h +0 -0
- data/{split/Dtable → ext/includes}/defs.h +0 -0
- data/{split/Dtable → ext/includes}/namespace.h +0 -0
- data/{split/Dtable → ext/includes}/safe_double.h +0 -0
- data/{split → ext/includes}/symbols.c +0 -1
- data/{split/Dtable → ext/includes}/symbols.h +0 -0
- data/{split/Dtable/lib → lib/Dobjects}/Dtable_extras.rb +0 -0
- data/{split/Dvector/lib → lib/Dobjects}/Dvector_extras.rb +1 -0
- data/{split/Function/lib → lib/Dobjects}/Function_extras.rb +0 -0
- data/{split/Dvector/lib → lib/Dobjects}/Numeric_extras.rb +0 -0
- data/{split/Tioga/lib → lib/Tioga}/Arcs_and_Circles.rb +0 -0
- data/{split/Tioga/lib → lib/Tioga}/ColorConstants.rb +0 -0
- data/{split/Tioga/lib → lib/Tioga}/Colorbars.rb +0 -0
- data/{split/Tioga/lib → lib/Tioga}/Colormaps.rb +0 -0
- data/{split/Tioga/lib → lib/Tioga}/Coordinate_Conversions.rb +0 -0
- data/{split/Tioga/lib → lib/Tioga}/Creating_Paths.rb +0 -0
- data/{split/Tioga/lib → lib/Tioga}/Doc.rb +0 -0
- data/{split/Tioga/lib → lib/Tioga}/Executive.rb +0 -0
- data/{split/Tioga/lib → lib/Tioga}/FigMkr.rb +13 -70
- data/{split/Tioga/lib → lib/Tioga}/FigureConstants.rb +0 -0
- data/{split/Tioga/lib → lib/Tioga}/Figures_and_Plots.rb +0 -0
- data/{split/Tioga/lib → lib/Tioga}/Images.rb +0 -0
- data/{split/Tioga/lib → lib/Tioga}/Legends.rb +0 -0
- data/{split/Tioga/lib → lib/Tioga}/MarkerConstants.rb +0 -0
- data/{split/Tioga/lib → lib/Tioga}/Markers.rb +0 -0
- data/{split/Tioga/lib → lib/Tioga}/Page_Frame_Bounds.rb +0 -0
- data/{split/Tioga/lib → lib/Tioga}/Rectangles.rb +0 -0
- data/{split/Tioga/lib → lib/Tioga}/Shading.rb +0 -0
- data/{split/Tioga/lib → lib/Tioga}/Special_Paths.rb +0 -0
- data/{split/Tioga/lib → lib/Tioga}/Strokes.rb +0 -0
- data/{split/Tioga/lib → lib/Tioga}/TeX_Text.rb +0 -0
- data/{split/Tioga/lib → lib/Tioga}/TexPreamble.rb +0 -0
- data/{split/Tioga/lib → lib/Tioga}/Titles_and_Labels.rb +0 -0
- data/{split/Tioga/lib → lib/Tioga}/Transparency.rb +0 -0
- data/{split/Tioga/lib → lib/Tioga}/Using_Paths.rb +0 -0
- data/{split/Tioga/lib → lib/Tioga}/Utils.rb +74 -0
- data/{split/Tioga/lib → lib/Tioga}/X_and_Y_Axes.rb +0 -0
- data/{split/Tioga/lib → lib/Tioga}/irb_tioga.rb +0 -0
- data/{split/Tioga/lib → lib/Tioga}/maker.rb +0 -0
- data/{split/Tioga/lib → lib/Tioga}/tioga.rb +0 -0
- data/{split/Tioga/lib → lib/Tioga}/tioga_ui.rb +0 -0
- data/{split/Tioga/lib → lib/Tioga}/tioga_ui_cmds.rb +0 -0
- data/tests/Icon_Test.pdf +0 -0
- data/tests/benchmark_dvector_reads.rb +20 -42
- data/tests/tc_Dvector.rb +45 -4
- data/tests/tc_Flate.rb +4 -5
- data/tests/tc_Function.rb +79 -0
- data/tests/vg.log +1453 -0
- metadata +141 -122
- data/split/Dtable/extconf.rb +0 -4
- data/split/Dvector/defs.h +0 -39
- data/split/Dvector/extconf.rb +0 -4
- data/split/Dvector/include/dvector.h +0 -77
- data/split/Dvector/namespace.h +0 -59
- data/split/Dvector/safe_double.h +0 -104
- data/split/Dvector/symbols.h +0 -52
- data/split/Flate/defs.h +0 -39
- data/split/Flate/extconf.rb +0 -19
- data/split/Flate/namespace.h +0 -59
- data/split/Flate/safe_double.h +0 -104
- data/split/Flate/symbols.h +0 -52
- data/split/Function/defs.h +0 -39
- data/split/Function/dvector.h +0 -77
- data/split/Function/extconf.rb +0 -4
- data/split/Function/namespace.h +0 -59
- data/split/Function/safe_double.h +0 -104
- data/split/Function/symbols.h +0 -52
- data/split/Tioga/defs.h +0 -39
- data/split/Tioga/dtable.h +0 -35
- data/split/Tioga/dvector.h +0 -77
- data/split/Tioga/extconf.rb +0 -4
- data/split/Tioga/flate.h +0 -98
- data/split/Tioga/mk_tioga_sty.rb +0 -53
- data/split/Tioga/namespace.h +0 -59
- data/split/Tioga/safe_double.h +0 -104
- data/split/Tioga/symbols.h +0 -52
- data/split/defs.h +0 -39
- data/split/extconf.rb +0 -125
- data/split/mkmf2.rb +0 -1623
- data/split/namespace.h +0 -59
- data/split/safe_double.h +0 -104
- data/split/symbols.h +0 -52
data/Tioga_README
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
This is the README for the Tioga kernel, version 1.10, March 7, 2009.
|
|
2
2
|
|
|
3
3
|
Copyright (C) 2005, 2006, 2007, 2008, 2009 Bill Paxton
|
|
4
|
-
Copyright (C) 2007, 2008, 2009 Vincent Fourmond, Taro Sato
|
|
4
|
+
Copyright (C) 2007, 2008, 2009, 2010 Vincent Fourmond, Taro Sato,
|
|
5
|
+
Benjamin ter Kuile
|
|
5
6
|
|
|
6
7
|
This file is part of Tioga.
|
|
7
8
|
|
|
@@ -21,16 +22,13 @@ This is the README for the Tioga kernel, version 1.10, March 7, 2009.
|
|
|
21
22
|
|
|
22
23
|
<< What's new >>
|
|
23
24
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
x/yaxis_labels_color= accessors. The show_axis/axis_info functions
|
|
28
|
-
have been updated accordingly, and are now complete.
|
|
29
|
-
|
|
30
|
-
Second, a new interpolation function for monotonic interpolations
|
|
31
|
-
has been added to Dvector (check out the Sampled_pm_cubics sample in
|
|
32
|
-
samples/plots/plots.rb).
|
|
25
|
+
Tioga 1.13 brings in a fix for a well-hidden memory leak that was
|
|
26
|
+
unlikely to hit you unless you were allocating a huge number of
|
|
27
|
+
vectors.
|
|
33
28
|
|
|
29
|
+
More interestingly, a few instance functions that did not depend on
|
|
30
|
+
FigureMaker's internal state (color conversion functions and
|
|
31
|
+
contouring algorithms) were made available as module functions too.
|
|
34
32
|
|
|
35
33
|
<< Quick Installation of Tioga >>
|
|
36
34
|
|
|
@@ -56,41 +54,27 @@ be working, go directly to the << Documentation >> section below.
|
|
|
56
54
|
<< Step-by-Step Installation >>
|
|
57
55
|
|
|
58
56
|
To get Tioga running, you need to have a working Ruby, a C
|
|
59
|
-
compiler, make, and
|
|
57
|
+
compiler, make, and pdflatex. Assuming you've got all that (more
|
|
60
58
|
later if you don't), connect to the Tioga directory that you just
|
|
61
59
|
unpacked and do the following:
|
|
62
60
|
|
|
63
61
|
[ this has been changed, be careful ! ]
|
|
64
62
|
|
|
65
|
-
|
|
66
|
-
ruby
|
|
67
|
-
|
|
68
|
-
make install
|
|
63
|
+
ruby setup.rb config
|
|
64
|
+
ruby setup.rb seutp
|
|
65
|
+
ruby setup.rb install
|
|
69
66
|
|
|
70
|
-
|
|
71
|
-
installation. The "make install" needs to copy some files to the ruby
|
|
72
|
-
directory. On the Mac, this probably means you need to do the whole
|
|
73
|
-
thing inside a 'sudo'. For Linux, you may have to become root.
|
|
67
|
+
(that's exactly what the ./QUICK_INSTALL script is doing)
|
|
74
68
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
sequence anyway just to be safe.
|
|
79
|
-
|
|
80
|
-
You now have another option to install: if you replace the line
|
|
81
|
-
|
|
82
|
-
ruby extconf.rb
|
|
83
|
-
|
|
84
|
-
with
|
|
85
|
-
|
|
86
|
-
ruby extconf.rb --home
|
|
87
|
-
|
|
88
|
-
it will install the files to your home directory, namely
|
|
89
|
-
~/lib/ruby. You don't need root privileges to do that, but make sure
|
|
90
|
-
that you set RUBYLIB=~/lib/ruby somewhere, so that ruby can find it.
|
|
69
|
+
Tioga now uses the standard setup.rb installation tool, so you get
|
|
70
|
+
a lot of customization possibilities for free. For more information on
|
|
71
|
+
how to use setup.rb to suit your needs, try
|
|
91
72
|
|
|
73
|
+
ruby setup.rb --help
|
|
92
74
|
|
|
75
|
+
or, even better, take a look at its documentation:
|
|
93
76
|
|
|
77
|
+
http://i.loveruby.net/en/projects/setup/doc/usage.html
|
|
94
78
|
|
|
95
79
|
<< Checking The Installation >>
|
|
96
80
|
|
|
@@ -188,6 +172,45 @@ Bill Paxton
|
|
|
188
172
|
|
|
189
173
|
Here are the old release messages:
|
|
190
174
|
|
|
175
|
+
Tioga 1.12 has seen quite a lot of action. The first and major
|
|
176
|
+
change is the switch from a custom rewrite of mkmf.rb for
|
|
177
|
+
building/installing to the standard setup.rb tool, which finally has
|
|
178
|
+
the gem version build exactly the same way as the pristine one.
|
|
179
|
+
|
|
180
|
+
Another side effect of this is that, for a big part thanks to
|
|
181
|
+
Carlo E. Prelz <fluido@fluido.as>, we now have tioga that works just
|
|
182
|
+
fine with Ruby 1.9.1 (though there is a weird bug while testing the
|
|
183
|
+
Flate library, we welcome any input on that).
|
|
184
|
+
|
|
185
|
+
Apart from that, Tioga has seen many improvements on the numerical
|
|
186
|
+
side. First, we welcome the participation of Benjamin ter Kuile, who
|
|
187
|
+
has started improving some aspects of Dtable.
|
|
188
|
+
|
|
189
|
+
Second, now Dvector is gifted with FFT capacities if the
|
|
190
|
+
development files of fftw3 are available at compile time (have a look
|
|
191
|
+
at the documentation).
|
|
192
|
+
|
|
193
|
+
Third, Function has been endowed with a whole bunch of new
|
|
194
|
+
functions for data processing, such as linear regression, spline
|
|
195
|
+
approximation (that almost looks like a good filter !), 4th order
|
|
196
|
+
accurate first and second derivatives.
|
|
197
|
+
|
|
198
|
+
Finally, a couple of annoying bugs were fixed.
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
--------------------------
|
|
202
|
+
|
|
203
|
+
Version 1.11 brings in a few new features. First, it is now
|
|
204
|
+
possible to set the color of axis tick labels - if you love pink axes,
|
|
205
|
+
you can them fully in Pink, now ;-) ! Check out the
|
|
206
|
+
x/yaxis_labels_color= accessors. The show_axis/axis_info functions
|
|
207
|
+
have been updated accordingly, and are now complete.
|
|
208
|
+
|
|
209
|
+
Second, a new interpolation function for monotonic interpolations
|
|
210
|
+
has been added to Dvector (check out the Sampled_pm_cubics sample in
|
|
211
|
+
samples/plots/plots.rb).
|
|
212
|
+
|
|
213
|
+
|
|
191
214
|
--------------------------
|
|
192
215
|
|
|
193
216
|
Version 1.10 is a minor bug-fix release, the most important one
|
data/{split/scripts → bin}/tioga
RENAMED
|
@@ -25,15 +25,16 @@
|
|
|
25
25
|
#include <stdlib.h>
|
|
26
26
|
#include <ctype.h>
|
|
27
27
|
#include <math.h>
|
|
28
|
-
#include "intern.h"
|
|
29
28
|
|
|
30
|
-
|
|
31
|
-
#include
|
|
29
|
+
/* Internal include files, from the ext/includes directory */
|
|
30
|
+
#include <symbols.h>
|
|
31
|
+
#include <symbols.c>
|
|
32
32
|
|
|
33
33
|
#include <defs.h>
|
|
34
34
|
|
|
35
35
|
/* safe storing of doubles */
|
|
36
36
|
#include <safe_double.h>
|
|
37
|
+
/* End of internal files */
|
|
37
38
|
|
|
38
39
|
|
|
39
40
|
#define is_a_dtable(d) ( TYPE(d) == T_DATA && RDATA(d)->dfree == (RUBY_DATA_FUNC)dtable_free )
|
|
@@ -406,7 +407,7 @@ PRIVATE
|
|
|
406
407
|
row_num = rb_Integer(row_num);
|
|
407
408
|
int row = NUM2INT(row_num);
|
|
408
409
|
if (row < 0 || row >= d->num_rows)
|
|
409
|
-
rb_raise(rb_eArgError, "Asking for row i = %i from array with only %
|
|
410
|
+
rb_raise(rb_eArgError, "Asking for row i = %i from array with only %li rows", row, d->num_rows);
|
|
410
411
|
VALUE dvec = Dvector_Create();
|
|
411
412
|
Dvector_Data_Replace(dvec, d->num_cols, d->ptr[row]);
|
|
412
413
|
return dvec;
|
|
@@ -426,14 +427,31 @@ PRIVATE
|
|
|
426
427
|
row_num = rb_Integer(row_num);
|
|
427
428
|
int row = NUM2INT(row_num);
|
|
428
429
|
if (row < 0 || row >= d->num_rows)
|
|
429
|
-
rb_raise(rb_eArgError, "Asking for row i = %i from array with only %
|
|
430
|
+
rb_raise(rb_eArgError, "Asking for row i = %i from array with only %li rows", row, d->num_rows);
|
|
430
431
|
if (len != d->num_cols)
|
|
431
|
-
rb_raise(rb_eArgError, "Length of vector (%
|
|
432
|
+
rb_raise(rb_eArgError, "Length of vector (%li) does not match number of columns (%li)", len, d->num_cols);
|
|
432
433
|
for (j=0; j < len; j++)
|
|
433
434
|
d->ptr[row][j] = data[j];
|
|
434
435
|
return dvec;
|
|
435
436
|
}
|
|
436
437
|
|
|
438
|
+
PRIVATE
|
|
439
|
+
/*
|
|
440
|
+
* call-seq:
|
|
441
|
+
* dtable.each_row{|row| }
|
|
442
|
+
*
|
|
443
|
+
* Iterates over all rows and executes the given block
|
|
444
|
+
*/ VALUE dtable_each_row(VALUE ary){
|
|
445
|
+
Dtable *d = Get_Dtable(ary);
|
|
446
|
+
VALUE dvec = Dvector_Create();
|
|
447
|
+
int i;
|
|
448
|
+
for(i=0; i < d->num_rows; i++){
|
|
449
|
+
Dvector_Data_Replace(dvec, d->num_cols, d->ptr[i]);
|
|
450
|
+
rb_yield(dvec);
|
|
451
|
+
}
|
|
452
|
+
return ary;
|
|
453
|
+
}
|
|
454
|
+
|
|
437
455
|
PRIVATE
|
|
438
456
|
/*
|
|
439
457
|
* call-seq:
|
|
@@ -448,9 +466,9 @@ PRIVATE
|
|
|
448
466
|
col_num = rb_Integer(col_num);
|
|
449
467
|
int col = NUM2INT(col_num);
|
|
450
468
|
if (col < 0 || col >= d->num_cols)
|
|
451
|
-
rb_raise(rb_eArgError, "Asking for column i = %i from array with only %
|
|
469
|
+
rb_raise(rb_eArgError, "Asking for column i = %i from array with only %li columns", col, d->num_cols);
|
|
452
470
|
if (len != d->num_rows)
|
|
453
|
-
rb_raise(rb_eArgError, "Length of vector (%
|
|
471
|
+
rb_raise(rb_eArgError, "Length of vector (%li) does not match number of rows (%li)", len, d->num_rows);
|
|
454
472
|
for (i=0; i < len; i++)
|
|
455
473
|
d->ptr[i][col] = data[i];
|
|
456
474
|
return dvec;
|
|
@@ -467,7 +485,7 @@ PRIVATE
|
|
|
467
485
|
column_num = rb_Integer(column_num);
|
|
468
486
|
int i, column = NUM2INT(column_num), len;
|
|
469
487
|
if (column < 0 || column >= d->num_cols)
|
|
470
|
-
rb_raise(rb_eArgError, "Asking for column i = %i from array with only %
|
|
488
|
+
rb_raise(rb_eArgError, "Asking for column i = %i from array with only %li columns", column, d->num_cols);
|
|
471
489
|
VALUE dvec = Dvector_Create();
|
|
472
490
|
len = d->num_rows;
|
|
473
491
|
Dvector_Data_Resize(dvec, len);
|
|
@@ -476,6 +494,25 @@ PRIVATE
|
|
|
476
494
|
return dvec;
|
|
477
495
|
}
|
|
478
496
|
|
|
497
|
+
PRIVATE
|
|
498
|
+
/*
|
|
499
|
+
* call-seq:
|
|
500
|
+
* dtable.each_column{|col| }
|
|
501
|
+
*
|
|
502
|
+
* Iterates over all columns and executes the given block
|
|
503
|
+
*/ VALUE dtable_each_column(VALUE ary){
|
|
504
|
+
Dtable *d = Get_Dtable(ary);
|
|
505
|
+
VALUE dvec = Dvector_Create();
|
|
506
|
+
int i,j;
|
|
507
|
+
for(j=0; j < d->num_cols; j++){
|
|
508
|
+
for(i=0; i < d->num_rows; i++){
|
|
509
|
+
Dvector_Store_Double(dvec, i, d->ptr[i][j]);
|
|
510
|
+
}
|
|
511
|
+
rb_yield(dvec);
|
|
512
|
+
}
|
|
513
|
+
return ary;
|
|
514
|
+
}
|
|
515
|
+
|
|
479
516
|
static void set_dtable_vals(VALUE ary, double v) {
|
|
480
517
|
Dtable *d = Get_Dtable(ary);
|
|
481
518
|
int num_cols = d->num_cols, num_rows = d->num_rows, i, j;
|
|
@@ -1576,7 +1613,7 @@ PRIVATE
|
|
|
1576
1613
|
printf("len %i\n", len);
|
|
1577
1614
|
strncpy(err_str,buff,len);
|
|
1578
1615
|
rb_raise(rb_eArgError,
|
|
1579
|
-
"failed to read requested amount of data in %s (asked for %
|
|
1616
|
+
"failed to read requested amount of data in %s (asked for %li xs and %li ys; found only %i and %i). last attempt to read got %g from string starting with: %s",
|
|
1580
1617
|
filename, num_cols, num_rows, i+1, j, data[j], err_str);
|
|
1581
1618
|
}
|
|
1582
1619
|
}
|
|
@@ -1759,13 +1796,13 @@ PRIVATE
|
|
|
1759
1796
|
Dtable *d = Get_Dtable(ary);
|
|
1760
1797
|
int nx = NUM2DBL(rb_Integer(nx_val));
|
|
1761
1798
|
int ny = NUM2DBL(rb_Integer(ny_val));
|
|
1762
|
-
|
|
1799
|
+
int i, j, num_cols = d->num_cols, num_rows = d->num_rows/*, last_row = num_rows - 1*/;
|
|
1763
1800
|
|
|
1764
1801
|
long xsrc_len, ysrc_len;
|
|
1765
1802
|
double *xsrc = Dvector_Data_for_Read(x_vec, &xsrc_len);
|
|
1766
1803
|
double *ysrc = Dvector_Data_for_Read(y_vec, &ysrc_len);
|
|
1767
|
-
if(xsrc_len != num_cols) rb_raise(rb_eArgError, "Number of x values (%
|
|
1768
|
-
if(ysrc_len != num_rows) rb_raise(rb_eArgError, "Number of y values (%
|
|
1804
|
+
if(xsrc_len != num_cols) rb_raise(rb_eArgError, "Number of x values (%ld) do not match the number of columns (%d)", xsrc_len, num_cols);
|
|
1805
|
+
if(ysrc_len != num_rows) rb_raise(rb_eArgError, "Number of y values (%ld) do not match the number of rows (%d)", ysrc_len, num_rows);
|
|
1769
1806
|
VALUE new = dtable_init(dtable_alloc(cDtable), nx, ny);
|
|
1770
1807
|
Dtable *d2 = Get_Dtable(new);
|
|
1771
1808
|
double **src, **dest;
|
|
@@ -1811,6 +1848,34 @@ PRIVATE
|
|
|
1811
1848
|
return new;
|
|
1812
1849
|
}
|
|
1813
1850
|
|
|
1851
|
+
PRIVATE
|
|
1852
|
+
/*
|
|
1853
|
+
* call-seq:
|
|
1854
|
+
* dtable.sum -> number
|
|
1855
|
+
*
|
|
1856
|
+
* Returns the sum of the entries in _dtable_. Returns 0.0 if
|
|
1857
|
+
* _dtable_ is empty.
|
|
1858
|
+
*
|
|
1859
|
+
* a = Dtable.new(2,4)
|
|
1860
|
+
* a.set_column(0, Dvector[1,2,3,4])
|
|
1861
|
+
* a.set_column(1, Dvector[0, 1, 0, 1])
|
|
1862
|
+
* a.sum -> 12.0
|
|
1863
|
+
* Dtable.new(2,2).sum -> 0.0
|
|
1864
|
+
*/
|
|
1865
|
+
VALUE dtable_sum(VALUE tabl){
|
|
1866
|
+
int i,j;
|
|
1867
|
+
double sum=0.0;
|
|
1868
|
+
double **src;
|
|
1869
|
+
Dtable *d = Get_Dtable(tabl);
|
|
1870
|
+
src = d->ptr;
|
|
1871
|
+
for(i=0; i < d->num_cols; i++){
|
|
1872
|
+
for(j=0; j < d->num_rows; j++){
|
|
1873
|
+
sum = sum + src[j][i];
|
|
1874
|
+
}
|
|
1875
|
+
}
|
|
1876
|
+
return rb_float_new(sum);
|
|
1877
|
+
}
|
|
1878
|
+
|
|
1814
1879
|
/*
|
|
1815
1880
|
* Document-class: Dobjects::Dtable
|
|
1816
1881
|
*
|
|
@@ -1819,8 +1884,6 @@ PRIVATE
|
|
|
1819
1884
|
* Essentially any of the operations you might do with a Ruby Array of numbers can also be done with a Dtable.
|
|
1820
1885
|
* Dtables follow the same design philosophy as Dvector and uses Dvectors for several operations.
|
|
1821
1886
|
*/
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
1887
|
PUBLIC void Init_Dtable() {
|
|
1825
1888
|
/* modified by Vincent Fourmond, for splitting out the libraries */
|
|
1826
1889
|
|
|
@@ -1968,6 +2031,9 @@ PUBLIC void Init_Dtable() {
|
|
|
1968
2031
|
rb_define_method(cDtable, "safe_acos!", dtable_safe_acos_bang, 0);
|
|
1969
2032
|
|
|
1970
2033
|
rb_define_method(cDtable, "interpolate", dtable_interpolate, 8);
|
|
2034
|
+
rb_define_method(cDtable, "sum", dtable_sum, 0);
|
|
2035
|
+
rb_define_method(cDtable, "each_row", dtable_each_row, 0);
|
|
2036
|
+
rb_define_method(cDtable, "each_column", dtable_each_column, 0);
|
|
1971
2037
|
|
|
1972
2038
|
/* Marshal : */
|
|
1973
2039
|
rb_define_method(cDtable, "_dump", dtable_dump, 1);
|
|
File without changes
|
|
File without changes
|
|
@@ -27,11 +27,12 @@
|
|
|
27
27
|
#include <ctype.h>
|
|
28
28
|
#include <math.h>
|
|
29
29
|
#include "ruby.h"
|
|
30
|
-
#include "intern.h"
|
|
31
30
|
#include "dvector_intern.h"
|
|
32
31
|
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
|
|
33
|
+
/* Internal files that are defined in the ext/includes directory */
|
|
34
|
+
#include <symbols.h>
|
|
35
|
+
#include <symbols.c>
|
|
35
36
|
|
|
36
37
|
/* compiler-dependent definitions, such as is_okay_number */
|
|
37
38
|
#include <defs.h>
|
|
@@ -39,8 +40,8 @@
|
|
|
39
40
|
/* safe storing of doubles */
|
|
40
41
|
#include <safe_double.h>
|
|
41
42
|
|
|
42
|
-
/*
|
|
43
|
-
|
|
43
|
+
/* End of internal files */
|
|
44
|
+
|
|
44
45
|
#define is_a_dvector(d) ( TYPE(d) == T_DATA && RDATA(d)->dfree == (RUBY_DATA_FUNC)dvector_free )
|
|
45
46
|
|
|
46
47
|
#ifndef MAX
|
|
@@ -119,8 +120,8 @@ static VALUE dvector_alloc(VALUE klass) {
|
|
|
119
120
|
Dvector *d;
|
|
120
121
|
VALUE ary = Data_Make_Struct(klass, Dvector, dvector_mark, dvector_free, d);
|
|
121
122
|
d->len = 0;
|
|
122
|
-
d->ptr =
|
|
123
|
-
d->capa =
|
|
123
|
+
d->ptr = NULL;
|
|
124
|
+
d->capa = 0;
|
|
124
125
|
d->shared = Qnil;
|
|
125
126
|
return ary;
|
|
126
127
|
}
|
|
@@ -187,7 +188,7 @@ static void dvector_store(VALUE ary, long idx, VALUE val) {
|
|
|
187
188
|
static VALUE dvector_to_dvector(VALUE obj) {
|
|
188
189
|
if ( is_a_dvector(obj) ) return obj;
|
|
189
190
|
obj = rb_Array(obj);
|
|
190
|
-
return dvector_s_create(
|
|
191
|
+
return dvector_s_create(RARRAY_LEN(obj), RARRAY_PTR(obj), cDvector);
|
|
191
192
|
}
|
|
192
193
|
|
|
193
194
|
static Dvector *Get_Dvector(VALUE obj) {
|
|
@@ -910,7 +911,7 @@ static void dvector_splice(VALUE ary, long beg, long len, VALUE rpl) {
|
|
|
910
911
|
rlen = 0;
|
|
911
912
|
} else if (rb_obj_is_kind_of(rpl,rb_cArray)) {
|
|
912
913
|
rpl = rb_Array(rpl);
|
|
913
|
-
rlen =
|
|
914
|
+
rlen = RARRAY_LEN(rpl);
|
|
914
915
|
} else {
|
|
915
916
|
rpl = dvector_to_dvector(rpl);
|
|
916
917
|
r = Get_Dvector(rpl);
|
|
@@ -925,7 +926,7 @@ static void dvector_splice(VALUE ary, long beg, long len, VALUE rpl) {
|
|
|
925
926
|
dvector_mem_clear(d->ptr + d->len, beg - d->len);
|
|
926
927
|
if (rlen > 0) {
|
|
927
928
|
if (r != NULL) MEMCPY(d->ptr + beg, r->ptr, double, rlen);
|
|
928
|
-
else ary_to_dvector(
|
|
929
|
+
else ary_to_dvector(RARRAY_PTR(rpl), rlen, d->ptr);
|
|
929
930
|
}
|
|
930
931
|
d->len = len;
|
|
931
932
|
} else {
|
|
@@ -944,7 +945,7 @@ static void dvector_splice(VALUE ary, long beg, long len, VALUE rpl) {
|
|
|
944
945
|
}
|
|
945
946
|
if (rlen > 0) {
|
|
946
947
|
if (r != NULL) MEMMOVE(d->ptr + beg, r->ptr, double, rlen);
|
|
947
|
-
else ary_to_dvector(
|
|
948
|
+
else ary_to_dvector(RARRAY_PTR(rpl), rlen, d->ptr + beg);
|
|
948
949
|
}
|
|
949
950
|
}
|
|
950
951
|
}
|
|
@@ -1190,7 +1191,7 @@ PRIVATE
|
|
|
1190
1191
|
Dvector *d2 = Get_Dvector(ary2);
|
|
1191
1192
|
long i;
|
|
1192
1193
|
if (d->len != d2->len) {
|
|
1193
|
-
rb_raise(rb_eArgError, "vectors with different lengths (%
|
|
1194
|
+
rb_raise(rb_eArgError, "vectors with different lengths (%ld vs %ld) for each2", d->len, d2->len);
|
|
1194
1195
|
}
|
|
1195
1196
|
for (i=0; i < d->len; i++) {
|
|
1196
1197
|
rb_yield_values(2, rb_float_new(d->ptr[i]), rb_float_new(d2->ptr[i]));
|
|
@@ -1258,7 +1259,7 @@ PRIVATE
|
|
|
1258
1259
|
Dvector *d2 = Get_Dvector(ary2);
|
|
1259
1260
|
long i;
|
|
1260
1261
|
if (d->len != d2->len) {
|
|
1261
|
-
rb_raise(rb_eArgError, "vectors with different lengths (%
|
|
1262
|
+
rb_raise(rb_eArgError, "vectors with different lengths (%ld vs %ld) for each2_with_index", d->len, d2->len);
|
|
1262
1263
|
}
|
|
1263
1264
|
for (i=0; i < d->len; i++) {
|
|
1264
1265
|
rb_yield_values(3, rb_float_new(d->ptr[i]), rb_float_new(d2->ptr[i]), LONG2NUM(i));
|
|
@@ -1312,7 +1313,7 @@ PRIVATE
|
|
|
1312
1313
|
Dvector *d2 = Get_Dvector(ary2);
|
|
1313
1314
|
long len = d->len;
|
|
1314
1315
|
if (len != d2->len) {
|
|
1315
|
-
rb_raise(rb_eArgError, "vectors with different lengths (%
|
|
1316
|
+
rb_raise(rb_eArgError, "vectors with different lengths (%ld vs %ld) for reverse_each2", len, d2->len);
|
|
1316
1317
|
}
|
|
1317
1318
|
while (len--) {
|
|
1318
1319
|
rb_yield_values(2, rb_float_new(d->ptr[len]), rb_float_new(d2->ptr[len]));
|
|
@@ -1395,7 +1396,7 @@ PRIVATE
|
|
|
1395
1396
|
Dvector *d2 = Get_Dvector(ary2);
|
|
1396
1397
|
long len = d->len;
|
|
1397
1398
|
if (len != d2->len) {
|
|
1398
|
-
rb_raise(rb_eArgError, "vectors with different lengths (%
|
|
1399
|
+
rb_raise(rb_eArgError, "vectors with different lengths (%ld vs %ld) for reverse_each2_with_index",
|
|
1399
1400
|
len, d2->len);
|
|
1400
1401
|
}
|
|
1401
1402
|
while (len--) {
|
|
@@ -1522,7 +1523,7 @@ PRIVATE
|
|
|
1522
1523
|
gam[j] = c[j-1] / bet;
|
|
1523
1524
|
bet = b[j] - a[j]*gam[j];
|
|
1524
1525
|
if (bet == 0.0) {
|
|
1525
|
-
rb_raise(rb_eArgError, "zero divisor in tridag (j=%
|
|
1526
|
+
rb_raise(rb_eArgError, "zero divisor in tridag (j=%ld)", j);
|
|
1526
1527
|
}
|
|
1527
1528
|
u[j] = (r[j] - a[j]*u[j-1]) / bet;
|
|
1528
1529
|
}
|
|
@@ -1632,7 +1633,7 @@ static VALUE dvector_sort_internal(VALUE ary) {
|
|
|
1632
1633
|
else {
|
|
1633
1634
|
ary2 = dvector_to_a(ary);
|
|
1634
1635
|
ary2 = rb_ary_sort_bang(ary2);
|
|
1635
|
-
ary_to_dvector(
|
|
1636
|
+
ary_to_dvector(RARRAY_PTR(ary2), d->len, d->ptr);
|
|
1636
1637
|
}
|
|
1637
1638
|
return ary;
|
|
1638
1639
|
}
|
|
@@ -1727,7 +1728,7 @@ PRIVATE
|
|
|
1727
1728
|
return dvector_new4_dbl(d->len, d->ptr);
|
|
1728
1729
|
}
|
|
1729
1730
|
ary = rb_Array(ary);
|
|
1730
|
-
return dvector_new4(d->len,
|
|
1731
|
+
return dvector_new4(d->len, RARRAY_PTR(ary));
|
|
1731
1732
|
}
|
|
1732
1733
|
collect = dvector_new2(0,d->len);
|
|
1733
1734
|
for (i = 0; i < d->len; i++) {
|
|
@@ -1755,7 +1756,7 @@ PRIVATE
|
|
|
1755
1756
|
Dvector *d = Get_Dvector(ary);
|
|
1756
1757
|
Dvector *d2 = Get_Dvector(ary2);
|
|
1757
1758
|
if (d->len != d2->len) {
|
|
1758
|
-
rb_raise(rb_eArgError, "vectors with different lengths (%
|
|
1759
|
+
rb_raise(rb_eArgError, "vectors with different lengths (%ld vs %ld) for collect2", d->len, d2->len);
|
|
1759
1760
|
}
|
|
1760
1761
|
if (!rb_block_given_p()) {
|
|
1761
1762
|
return dvector_collect(ary);
|
|
@@ -1813,7 +1814,7 @@ VALUE dvector_collect2_bang(VALUE ary, VALUE ary2) {
|
|
|
1813
1814
|
Dvector *d = dvector_modify(ary);
|
|
1814
1815
|
Dvector *d2 = Get_Dvector(ary2);
|
|
1815
1816
|
if (d->len != d2->len) {
|
|
1816
|
-
rb_raise(rb_eArgError, "vectors with different lengths (%
|
|
1817
|
+
rb_raise(rb_eArgError, "vectors with different lengths (%ld vs %ld) for collect2!", d->len, d2->len);
|
|
1817
1818
|
}
|
|
1818
1819
|
for (i = 0; i < d->len; i++) {
|
|
1819
1820
|
dvector_store(ary, i, rb_yield_values(2, rb_float_new(d->ptr[i]), rb_float_new(d2->ptr[i])));
|
|
@@ -2014,8 +2015,8 @@ VALUE dvector_prune_bang(VALUE ary, VALUE lst) {
|
|
|
2014
2015
|
int i, lst_len, ary_len, pos, j;
|
|
2015
2016
|
VALUE *lst_ptr;
|
|
2016
2017
|
lst = rb_Array(lst);
|
|
2017
|
-
lst_ptr =
|
|
2018
|
-
lst_len =
|
|
2018
|
+
lst_ptr = RARRAY_PTR(lst);
|
|
2019
|
+
lst_len = RARRAY_LEN(lst);
|
|
2019
2020
|
for (i = lst_len-1; i >= 0; i--) {
|
|
2020
2021
|
ary_len = d->len;
|
|
2021
2022
|
pos = NUM2INT(lst_ptr[i]); // remove this one from ary
|
|
@@ -3011,7 +3012,7 @@ VALUE dvector_dot(VALUE ary1, VALUE ary2) {
|
|
|
3011
3012
|
double *p1 = d1->ptr, *p2 = d2->ptr, sum = 0.0;
|
|
3012
3013
|
long len = d1->len, i;
|
|
3013
3014
|
if (len != d2->len) {
|
|
3014
|
-
rb_raise(rb_eArgError, "vectors with different lengths (%
|
|
3015
|
+
rb_raise(rb_eArgError, "vectors with different lengths (%ld vs %ld) for dot", d1->len, d2->len);
|
|
3015
3016
|
}
|
|
3016
3017
|
for (i=0; i<len; i++) sum += p1[i] * p2[i];
|
|
3017
3018
|
return rb_float_new(sum);
|
|
@@ -4079,7 +4080,7 @@ VALUE dvector_apply_math_op2_bang(VALUE ary1, VALUE ary2, double (*op)(double, d
|
|
|
4079
4080
|
double *p1 = d1->ptr, *p2 = d2->ptr;
|
|
4080
4081
|
long len = d1->len, i;
|
|
4081
4082
|
if (len != d2->len) {
|
|
4082
|
-
rb_raise(rb_eArgError, "vectors with different lengths (%
|
|
4083
|
+
rb_raise(rb_eArgError, "vectors with different lengths (%ld vs %ld) math operation", d1->len, d2->len);
|
|
4083
4084
|
}
|
|
4084
4085
|
for (i=0; i<len; i++) p1[i] = (*op)(p1[i], p2[i]);
|
|
4085
4086
|
return ary1;
|
|
@@ -4446,8 +4447,8 @@ VALUE Read_Dvectors(char *filename, VALUE destinations, int first_row_of_file, i
|
|
|
4446
4447
|
if ((last_row_of_file != -1 && last_row_of_file < first_row_of_file) || filename == NULL) return false;
|
|
4447
4448
|
if (destinations != Qnil) {
|
|
4448
4449
|
cols_obj = rb_Array(destinations);
|
|
4449
|
-
num_cols =
|
|
4450
|
-
cols_ptr =
|
|
4450
|
+
num_cols = RARRAY_LEN(cols_obj);
|
|
4451
|
+
cols_ptr = RARRAY_PTR(cols_obj);
|
|
4451
4452
|
for (i = 0; i < num_cols; i++) { /* first pass to check validity */
|
|
4452
4453
|
col_obj = cols_ptr[i];
|
|
4453
4454
|
if (col_obj == Qnil) continue;
|
|
@@ -4494,8 +4495,8 @@ VALUE Read_Dvectors(char *filename, VALUE destinations, int first_row_of_file, i
|
|
|
4494
4495
|
}
|
|
4495
4496
|
if (row == 0) {
|
|
4496
4497
|
cols_obj = rb_Array(destinations);
|
|
4497
|
-
num_cols =
|
|
4498
|
-
cols_ptr =
|
|
4498
|
+
num_cols = RARRAY_LEN(cols_obj);
|
|
4499
|
+
cols_ptr = RARRAY_PTR(cols_obj);
|
|
4499
4500
|
}
|
|
4500
4501
|
buff_loc = 0;
|
|
4501
4502
|
for (col = 0; col < num_cols; col++) {
|
|
@@ -4592,8 +4593,8 @@ VALUE Read_Rows_of_Dvectors(char *filename, VALUE destinations, int first_row_of
|
|
|
4592
4593
|
char *buff, *num_str, *pend, c, *cptr;
|
|
4593
4594
|
int num_rows = 0, i, row, col, buff_loc, skip = first_row_of_file - 1;
|
|
4594
4595
|
rows_obj = rb_Array(destinations);
|
|
4595
|
-
num_rows =
|
|
4596
|
-
rows_ptr =
|
|
4596
|
+
num_rows = RARRAY_LEN(rows_obj);
|
|
4597
|
+
rows_ptr = RARRAY_PTR(rows_obj);
|
|
4597
4598
|
for (i = 0; i < num_rows; i++) { /* first pass to check validity */
|
|
4598
4599
|
row_obj = rows_ptr[i];
|
|
4599
4600
|
if (row_obj == Qnil) continue;
|
|
@@ -4854,7 +4855,7 @@ double *Dvector_Data_Replace(VALUE dvector, long len, double *data) { /* copies
|
|
|
4854
4855
|
return dvector_replace_dbls(dvector, len, data); }
|
|
4855
4856
|
PRIVATE
|
|
4856
4857
|
VALUE Dvector_Create(void) { return dvector_new(); }
|
|
4857
|
-
|
|
4858
|
+
/*
|
|
4858
4859
|
PRIVATE int Find_First_Both_Greater(VALUE Xs, VALUE Ys, double x, double y) {
|
|
4859
4860
|
int i;
|
|
4860
4861
|
long xlen, ylen;
|
|
@@ -4882,7 +4883,7 @@ PRIVATE int Find_First_Both_Smaller(VALUE Xs, VALUE Ys, double x, double y) {
|
|
|
4882
4883
|
}
|
|
4883
4884
|
return -1;
|
|
4884
4885
|
}
|
|
4885
|
-
|
|
4886
|
+
*/
|
|
4886
4887
|
PRIVATE
|
|
4887
4888
|
VALUE c_make_bezier_control_points_for_cubic_in_x(VALUE dest, double x0, double y0, double delta_x, double a, double b, double c)
|
|
4888
4889
|
{
|
|
@@ -5011,7 +5012,6 @@ VALUE dvector_create_pm_cubic_interpolant(int argc, VALUE *argv, VALUE klass) {
|
|
|
5011
5012
|
klass = Qnil;
|
|
5012
5013
|
VALUE Xs = argv[0], Ys = argv[1];
|
|
5013
5014
|
long xdlen, ydlen;
|
|
5014
|
-
double start = 0.0, end = 0.0;
|
|
5015
5015
|
double *X_data = Dvector_Data_for_Read(Xs, &xdlen);
|
|
5016
5016
|
double *Y_data = Dvector_Data_for_Read(Ys, &ydlen);
|
|
5017
5017
|
if (X_data == NULL || Y_data == NULL || xdlen != ydlen)
|
|
@@ -5060,7 +5060,7 @@ VALUE dvector_pm_cubic_interpolate(int argc, VALUE *argv, VALUE klass) {
|
|
|
5060
5060
|
VALUE interpolant = argv[1];
|
|
5061
5061
|
x = rb_Float(x);
|
|
5062
5062
|
interpolant = rb_Array(interpolant);
|
|
5063
|
-
if (
|
|
5063
|
+
if (RARRAY_LEN(interpolant) != 5)
|
|
5064
5064
|
rb_raise(rb_eArgError, "interpolant must be array of length 5 from create_pm_cubic_interpolant");
|
|
5065
5065
|
Dvector *Xs = Get_Dvector(rb_ary_entry(interpolant,0));
|
|
5066
5066
|
Dvector *Ys = Get_Dvector(rb_ary_entry(interpolant,1));
|
|
@@ -5189,7 +5189,7 @@ VALUE dvector_spline_interpolate(int argc, VALUE *argv, VALUE klass) {
|
|
|
5189
5189
|
VALUE interpolant = argv[1];
|
|
5190
5190
|
x = rb_Float(x);
|
|
5191
5191
|
interpolant = rb_Array(interpolant);
|
|
5192
|
-
if (
|
|
5192
|
+
if (RARRAY_LEN(interpolant) != 5)
|
|
5193
5193
|
rb_raise(rb_eArgError, "Spline interpolant must be array of length 5 from create_spline_interpolant");
|
|
5194
5194
|
Dvector *Xs = Get_Dvector(rb_ary_entry(interpolant,0));
|
|
5195
5195
|
Dvector *Ys = Get_Dvector(rb_ary_entry(interpolant,1));
|
|
@@ -5232,7 +5232,7 @@ VALUE dvector_linear_interpolate(int argc, VALUE *argv, VALUE klass) {
|
|
|
5232
5232
|
Dvector *X_data = Get_Dvector(Xs);
|
|
5233
5233
|
Dvector *Y_data = Get_Dvector(Ys);
|
|
5234
5234
|
if (X_data->len <= 0 || X_data->len != Y_data->len)
|
|
5235
|
-
rb_raise(rb_eArgError, "Xs and Ys for linear_interpolate must be equal length Dvectors: xlen %
|
|
5235
|
+
rb_raise(rb_eArgError, "Xs and Ys for linear_interpolate must be equal length Dvectors: xlen %ld ylen %ld.",
|
|
5236
5236
|
X_data->len, Y_data->len);
|
|
5237
5237
|
x = rb_Float(x);
|
|
5238
5238
|
double y = c_dvector_linear_interpolate(X_data->len, X_data->ptr, Y_data->ptr, NUM2DBL(x));
|
|
@@ -5255,8 +5255,8 @@ VALUE dvector_min_of_many(VALUE klass, VALUE ary) {
|
|
|
5255
5255
|
double m=0.0, tmp;
|
|
5256
5256
|
bool found_one = false;
|
|
5257
5257
|
ary = rb_Array(ary);
|
|
5258
|
-
ary_ptr =
|
|
5259
|
-
ary_len =
|
|
5258
|
+
ary_ptr = RARRAY_PTR(ary);
|
|
5259
|
+
ary_len = RARRAY_LEN(ary);
|
|
5260
5260
|
if (ary_len == 0) return Qnil;
|
|
5261
5261
|
for (i = 0; i < ary_len; i++) {
|
|
5262
5262
|
if (ary_ptr[i] == Qnil) continue;
|
|
@@ -5289,8 +5289,8 @@ VALUE dvector_max_of_many(VALUE klass, VALUE ary) {
|
|
|
5289
5289
|
double m=0.0, tmp;
|
|
5290
5290
|
bool found_one = false;
|
|
5291
5291
|
ary = rb_Array(ary);
|
|
5292
|
-
ary_ptr =
|
|
5293
|
-
ary_len =
|
|
5292
|
+
ary_ptr = RARRAY_PTR(ary);
|
|
5293
|
+
ary_len = RARRAY_LEN(ary);
|
|
5294
5294
|
if (ary_len == 0) return Qnil;
|
|
5295
5295
|
for (i = 0; i < ary_len; i++) {
|
|
5296
5296
|
if (ary_ptr[i] == Qnil) continue;
|
|
@@ -5496,14 +5496,17 @@ static VALUE dvector_convolve(VALUE self, VALUE kernel, VALUE middle)
|
|
|
5496
5496
|
number of the line read
|
|
5497
5497
|
* 'remove_space': whether to remove spaces at the beginning of a line. *This
|
|
5498
5498
|
option is currently not implemented !*
|
|
5499
|
+
* 'comment_out': this should be an array into which the comments
|
|
5500
|
+
will be dumped one by one.
|
|
5499
5501
|
* 'default': what to put when nothing was found but a number must be used
|
|
5500
5502
|
|
|
5501
|
-
|
|
5502
|
-
|
|
5503
|
+
In addition to these options that control the output, here are a few
|
|
5504
|
+
others to tune memory allocation; these can strongly improve the
|
|
5505
|
+
performance (or make it worse if you wish):
|
|
5503
5506
|
|
|
5504
|
-
|
|
5505
|
-
|
|
5506
|
-
|
|
5507
|
+
* 'initial_size': the initial size of the memory buffers: if there
|
|
5508
|
+
are not more lines than that, no additional memory allocation/copy
|
|
5509
|
+
occurs.
|
|
5507
5510
|
*/
|
|
5508
5511
|
static VALUE dvector_fast_fancy_read(VALUE self, VALUE stream, VALUE options)
|
|
5509
5512
|
{
|
|
@@ -5512,12 +5515,13 @@ static VALUE dvector_fast_fancy_read(VALUE self, VALUE stream, VALUE options)
|
|
|
5512
5515
|
rb_str_new2("default")));
|
|
5513
5516
|
int remove_space = RTEST(rb_hash_aref(options,
|
|
5514
5517
|
rb_str_new2("remove_space")));
|
|
5515
|
-
int index_col = RTEST(rb_hash_aref(options,
|
|
5516
|
-
rb_str_new2("index_col")));
|
|
5518
|
+
// int index_col = RTEST(rb_hash_aref(options,
|
|
5519
|
+
// rb_str_new2("index_col")));
|
|
5517
5520
|
long skip_first = FIX2LONG(rb_hash_aref(options,
|
|
5518
5521
|
rb_str_new2("skip_first")));
|
|
5519
5522
|
VALUE sep = rb_hash_aref(options, rb_str_new2("sep"));
|
|
5520
5523
|
VALUE comments = rb_hash_aref(options, rb_str_new2("comments"));
|
|
5524
|
+
VALUE comment_out = rb_hash_aref(options, rb_str_new2("comment_out"));
|
|
5521
5525
|
|
|
5522
5526
|
/* Then, some various variables: */
|
|
5523
5527
|
VALUE line;
|
|
@@ -5527,13 +5531,19 @@ static VALUE dvector_fast_fancy_read(VALUE self, VALUE stream, VALUE options)
|
|
|
5527
5531
|
long line_number = 0;
|
|
5528
5532
|
|
|
5529
5533
|
/*
|
|
5530
|
-
Now come the fun part - rudimentary vectors management
|
|
5534
|
+
Now come the fun part - rudimentary vectors management
|
|
5535
|
+
|
|
5536
|
+
TODO: if the stream provides functionality to get its total size,
|
|
5537
|
+
it could be interesting to estimate the total number of lines
|
|
5538
|
+
based on some small heuristics
|
|
5531
5539
|
*/
|
|
5532
5540
|
int nb_vectors = 0; /* The number of vectors currently created */
|
|
5533
5541
|
int current_size = 10; /* The number of slots available */
|
|
5534
5542
|
double ** vectors = ALLOC_N(double *, current_size);
|
|
5535
5543
|
long index = 0; /* The current index in the vectors */
|
|
5536
|
-
|
|
5544
|
+
/* The size available in the vectors */
|
|
5545
|
+
int allocated_size =
|
|
5546
|
+
FIX2LONG(rb_hash_aref(options, rb_str_new2("initial_size")));
|
|
5537
5547
|
|
|
5538
5548
|
|
|
5539
5549
|
int i;
|
|
@@ -5541,7 +5551,7 @@ static VALUE dvector_fast_fancy_read(VALUE self, VALUE stream, VALUE options)
|
|
|
5541
5551
|
/* The return value */
|
|
5542
5552
|
VALUE ary;
|
|
5543
5553
|
|
|
5544
|
-
/* We use a real gets so we can also
|
|
5554
|
+
/* We use a real gets so we can also use StringIO, for instance */
|
|
5545
5555
|
while(RTEST(line = rb_funcall(stream, gets_id, 0))) {
|
|
5546
5556
|
VALUE pre, post, match;
|
|
5547
5557
|
const char * line_ptr;
|
|
@@ -5564,8 +5574,11 @@ static VALUE dvector_fast_fancy_read(VALUE self, VALUE stream, VALUE options)
|
|
|
5564
5574
|
line = rb_str_new2(line_ptr);
|
|
5565
5575
|
|
|
5566
5576
|
/* ... or a comment line */
|
|
5567
|
-
if(RTEST(comments) && RTEST(rb_reg_match(comments, line)))
|
|
5577
|
+
if(RTEST(comments) && RTEST(rb_reg_match(comments, line))) {
|
|
5578
|
+
if(RTEST(comment_out))
|
|
5579
|
+
rb_ary_push(comment_out, line);
|
|
5568
5580
|
continue;
|
|
5581
|
+
}
|
|
5569
5582
|
|
|
5570
5583
|
/* Then, we remove the newline: */
|
|
5571
5584
|
post = line;
|
|
@@ -5630,6 +5643,288 @@ static VALUE dvector_fast_fancy_read(VALUE self, VALUE stream, VALUE options)
|
|
|
5630
5643
|
return ary;
|
|
5631
5644
|
}
|
|
5632
5645
|
|
|
5646
|
+
/*
|
|
5647
|
+
Returns a list of local extrema of the vector, organized thus:
|
|
5648
|
+
|
|
5649
|
+
[ [:min, idmin1], [:max, idmax1], ...]
|
|
5650
|
+
|
|
5651
|
+
The values are pushed in the order in which they are found. It works
|
|
5652
|
+
thus: it scans the vector and looks around the current point in a
|
|
5653
|
+
given window. If the current point is the maximum or the minimum, it
|
|
5654
|
+
is considered as a local maximum/minimum. Control over which extrema
|
|
5655
|
+
are included is given to the used through threshold mechanisms.
|
|
5656
|
+
|
|
5657
|
+
The _options_ hash controls how the peaks are detected:
|
|
5658
|
+
* _window_: the number of elements on which we look on
|
|
5659
|
+
both sides (default 5, ie the local maximum is over 11 points)
|
|
5660
|
+
* _threshold_: the minimum amplitude the extrema must have to
|
|
5661
|
+
be considered (default 0)
|
|
5662
|
+
* _dthreshold_: how much over/under the average an extremum must be
|
|
5663
|
+
(default 0)
|
|
5664
|
+
* _or_: whether the _threshold_ and _dthreshold_ tests are both
|
|
5665
|
+
necessary or if only one is (default false: both tests are
|
|
5666
|
+
necessary)
|
|
5667
|
+
|
|
5668
|
+
*Note:* beware of NANs ! They *will* screw up peak detection, as
|
|
5669
|
+
they are neither bigger nor smaller than anything...
|
|
5670
|
+
*/
|
|
5671
|
+
static VALUE dvector_extrema(int argc, VALUE *argv, VALUE self)
|
|
5672
|
+
{
|
|
5673
|
+
long window = 5;
|
|
5674
|
+
double threshold = 0;
|
|
5675
|
+
double dthreshold = 0;
|
|
5676
|
+
int inclusive = 1;
|
|
5677
|
+
|
|
5678
|
+
if(argc == 1) {
|
|
5679
|
+
VALUE t;
|
|
5680
|
+
t = rb_hash_aref(argv[0], rb_str_new2("window"));
|
|
5681
|
+
if(RTEST(t)) {
|
|
5682
|
+
window = FIX2LONG(t);
|
|
5683
|
+
}
|
|
5684
|
+
t = rb_hash_aref(argv[0], rb_str_new2("threshold"));
|
|
5685
|
+
if(RTEST(t)) {
|
|
5686
|
+
threshold = rb_num2dbl(t);
|
|
5687
|
+
}
|
|
5688
|
+
t = rb_hash_aref(argv[0], rb_str_new2("dthreshold"));
|
|
5689
|
+
if(RTEST(t)) {
|
|
5690
|
+
dthreshold = rb_num2dbl(t);
|
|
5691
|
+
}
|
|
5692
|
+
|
|
5693
|
+
t = rb_hash_aref(argv[0], rb_str_new2("or"));
|
|
5694
|
+
inclusive = ! RTEST(t);
|
|
5695
|
+
} else if(argc > 1)
|
|
5696
|
+
rb_raise(rb_eArgError, "Dvector.extrema only takes 0 or 1 argument");
|
|
5697
|
+
|
|
5698
|
+
/* Handling of the vector */
|
|
5699
|
+
long len, i,j;
|
|
5700
|
+
double * data = Dvector_Data_for_Read(self, &len);
|
|
5701
|
+
VALUE s_min = ID2SYM(rb_intern("min"));
|
|
5702
|
+
VALUE s_max = ID2SYM(rb_intern("max"));
|
|
5703
|
+
|
|
5704
|
+
|
|
5705
|
+
|
|
5706
|
+
VALUE ret = rb_ary_new();
|
|
5707
|
+
|
|
5708
|
+
for(i = 0; i < len; i++) {
|
|
5709
|
+
|
|
5710
|
+
/* This is stupid and will need decent optimization when I have
|
|
5711
|
+
time */
|
|
5712
|
+
long first = i > window ? i - window : 0;
|
|
5713
|
+
double cur_min = data[first];
|
|
5714
|
+
long cur_min_idx = first;
|
|
5715
|
+
double cur_max = data[first];
|
|
5716
|
+
long cur_max_idx = first;
|
|
5717
|
+
double average = 0;
|
|
5718
|
+
long nb = 0;
|
|
5719
|
+
|
|
5720
|
+
for(j = first; (j < i+window) && (j < len); j++,nb++) {
|
|
5721
|
+
average += data[j];
|
|
5722
|
+
if(data[j] <= cur_min) {
|
|
5723
|
+
cur_min = data[j];
|
|
5724
|
+
cur_min_idx = j;
|
|
5725
|
+
}
|
|
5726
|
+
if(data[j] >= cur_max) {
|
|
5727
|
+
cur_max = data[j];
|
|
5728
|
+
cur_max_idx = j;
|
|
5729
|
+
}
|
|
5730
|
+
}
|
|
5731
|
+
average /= nb;
|
|
5732
|
+
|
|
5733
|
+
if(cur_min_idx == i) {
|
|
5734
|
+
/* This is a potential minimum */
|
|
5735
|
+
if((inclusive &&
|
|
5736
|
+
(fabs(cur_min) >= threshold) &&
|
|
5737
|
+
(fabs(cur_min - average) >= dthreshold))
|
|
5738
|
+
|| (!inclusive &&
|
|
5739
|
+
((fabs(cur_min) >= threshold) ||
|
|
5740
|
+
(fabs(cur_min - average) >= dthreshold))
|
|
5741
|
+
)) {
|
|
5742
|
+
VALUE min = rb_ary_new();
|
|
5743
|
+
rb_ary_push(min, s_min);
|
|
5744
|
+
rb_ary_push(min, LONG2FIX(i));
|
|
5745
|
+
rb_ary_push(ret, min);
|
|
5746
|
+
}
|
|
5747
|
+
}
|
|
5748
|
+
else if(cur_max_idx == i) {
|
|
5749
|
+
/* A potential maximum */
|
|
5750
|
+
if((inclusive &&
|
|
5751
|
+
(fabs(cur_max) >= threshold) &&
|
|
5752
|
+
(fabs(cur_max - average) >= dthreshold))
|
|
5753
|
+
|| (!inclusive &&
|
|
5754
|
+
((fabs(cur_max) >= threshold) ||
|
|
5755
|
+
(fabs(cur_max - average) >= dthreshold))
|
|
5756
|
+
)) {
|
|
5757
|
+
VALUE max = rb_ary_new();
|
|
5758
|
+
rb_ary_push(max, s_max);
|
|
5759
|
+
rb_ary_push(max, LONG2FIX(i));
|
|
5760
|
+
rb_ary_push(ret, max);
|
|
5761
|
+
}
|
|
5762
|
+
}
|
|
5763
|
+
}
|
|
5764
|
+
return ret;
|
|
5765
|
+
}
|
|
5766
|
+
|
|
5767
|
+
/* This is the FFTW-based part of the game */
|
|
5768
|
+
#ifdef HAVE_FFTW3_H
|
|
5769
|
+
#include <fftw3.h>
|
|
5770
|
+
|
|
5771
|
+
/*
|
|
5772
|
+
Performs an in-place Fourier transform of the vector. The results
|
|
5773
|
+
is stored in the so-called "half-complex" format (see
|
|
5774
|
+
http://www.fftw.org/fftw3_doc/The-Halfcomplex_002dformat-DFT.html
|
|
5775
|
+
for more information).
|
|
5776
|
+
|
|
5777
|
+
*/
|
|
5778
|
+
static VALUE dvector_fft(VALUE self)
|
|
5779
|
+
{
|
|
5780
|
+
long len;
|
|
5781
|
+
double * values = Dvector_Data_for_Write(self, &len);
|
|
5782
|
+
fftw_plan plan = fftw_plan_r2r_1d(len, values, values,
|
|
5783
|
+
FFTW_R2HC, FFTW_ESTIMATE);
|
|
5784
|
+
fftw_execute(plan);
|
|
5785
|
+
fftw_destroy_plan(plan);
|
|
5786
|
+
return self;
|
|
5787
|
+
}
|
|
5788
|
+
|
|
5789
|
+
/*
|
|
5790
|
+
Performs a reverse in-place Fourier transform of the vector. The
|
|
5791
|
+
original data must have been stored in the so called "half-complex"
|
|
5792
|
+
format (see #fft!).
|
|
5793
|
+
*/
|
|
5794
|
+
|
|
5795
|
+
static VALUE dvector_rfft(VALUE self)
|
|
5796
|
+
{
|
|
5797
|
+
long len;
|
|
5798
|
+
double * values = Dvector_Data_for_Write(self, &len);
|
|
5799
|
+
fftw_plan plan = fftw_plan_r2r_1d(len, values, values,
|
|
5800
|
+
FFTW_HC2R, FFTW_ESTIMATE);
|
|
5801
|
+
fftw_execute(plan);
|
|
5802
|
+
fftw_destroy_plan(plan);
|
|
5803
|
+
return self;
|
|
5804
|
+
}
|
|
5805
|
+
|
|
5806
|
+
/*
|
|
5807
|
+
Now, small functions to manipulate the FFTed data:
|
|
5808
|
+
* multiply them
|
|
5809
|
+
* divide them
|
|
5810
|
+
* get (the square of) their module
|
|
5811
|
+
*/
|
|
5812
|
+
|
|
5813
|
+
|
|
5814
|
+
/*
|
|
5815
|
+
Returns the power spectra of the ffted data (ie the square of the
|
|
5816
|
+
norm of the complex fourier coefficients.
|
|
5817
|
+
|
|
5818
|
+
The returned value is a new Dvector of size about two times smaller
|
|
5819
|
+
than the original (precisely size/2 + 1)
|
|
5820
|
+
|
|
5821
|
+
For some reasons, convolutions don't work for now.
|
|
5822
|
+
*/
|
|
5823
|
+
static VALUE dvector_fft_spectrum(VALUE self)
|
|
5824
|
+
{
|
|
5825
|
+
long len;
|
|
5826
|
+
const double * values = Dvector_Data_for_Read(self, &len);
|
|
5827
|
+
/* First compute the size of the target: */
|
|
5828
|
+
long target_size = len/2+1;
|
|
5829
|
+
long i;
|
|
5830
|
+
VALUE retval = dvector_new2(target_size,target_size);
|
|
5831
|
+
double * ret = Dvector_Data_for_Write(retval,NULL);
|
|
5832
|
+
|
|
5833
|
+
/* Pointer to real and imaginary parts */
|
|
5834
|
+
const double * real;
|
|
5835
|
+
const double * img;
|
|
5836
|
+
ret[0] = values[0] * values[0];
|
|
5837
|
+
|
|
5838
|
+
|
|
5839
|
+
/* The Nyquist frequency */
|
|
5840
|
+
if(len % 2 == 0)
|
|
5841
|
+
ret[target_size - 1] = values[target_size-1] * values[target_size-1];
|
|
5842
|
+
for(i = 1, real = values + 1, img = values + len-1; i < len/2;
|
|
5843
|
+
i++, real++, img--)
|
|
5844
|
+
ret[i] = *real * *real + *img * *img;
|
|
5845
|
+
return retval;
|
|
5846
|
+
}
|
|
5847
|
+
|
|
5848
|
+
/*
|
|
5849
|
+
Converts the FFTed data in the complex conjugate
|
|
5850
|
+
*/
|
|
5851
|
+
static VALUE dvector_fft_conj(VALUE self)
|
|
5852
|
+
{
|
|
5853
|
+
long len;
|
|
5854
|
+
double * v1 = Dvector_Data_for_Write(self, &len);
|
|
5855
|
+
double * img;
|
|
5856
|
+
long i;
|
|
5857
|
+
for(i = 1, img = v1 + len-1; i < (len+1)/2;
|
|
5858
|
+
i++, img--)
|
|
5859
|
+
*img = -*img;
|
|
5860
|
+
return self;
|
|
5861
|
+
}
|
|
5862
|
+
|
|
5863
|
+
|
|
5864
|
+
/*
|
|
5865
|
+
Multiplies the FFTed data held in the vector by another vector. The
|
|
5866
|
+
behaviour depends on the size of the target vector:
|
|
5867
|
+
|
|
5868
|
+
* if it is the same size, it is assumed to be FFTed data
|
|
5869
|
+
* if it is the same size of a power spectrum, then it is assumed that it
|
|
5870
|
+
is multiplication by real values
|
|
5871
|
+
* anything else won't make this function happy.
|
|
5872
|
+
|
|
5873
|
+
As a side note, if you only want multiplication by a scalar, the
|
|
5874
|
+
standard #mul! should be what you look for.
|
|
5875
|
+
*/
|
|
5876
|
+
static VALUE dvector_fft_mul(VALUE self, VALUE m)
|
|
5877
|
+
{
|
|
5878
|
+
long len;
|
|
5879
|
+
double * v1 = Dvector_Data_for_Write(self, &len);
|
|
5880
|
+
long len2;
|
|
5881
|
+
const double * v2 = Dvector_Data_for_Write(m, &len2);
|
|
5882
|
+
if(len2 == len) { /* Full complex multiplication */
|
|
5883
|
+
const double * m_img;
|
|
5884
|
+
const double * m_real;
|
|
5885
|
+
double * v_img;
|
|
5886
|
+
double * v_real;
|
|
5887
|
+
long i;
|
|
5888
|
+
/* First, special cases */
|
|
5889
|
+
v1[0] *= v2[0];
|
|
5890
|
+
if(len % 2 == 0)
|
|
5891
|
+
v1[len/2] *= v2[len/2];
|
|
5892
|
+
|
|
5893
|
+
for(i = 1, m_real = v2 + 1, m_img = v2 + len-1,
|
|
5894
|
+
v_real = v1 + 1, v_img = v1 + len-1; i < (len+1)/2;
|
|
5895
|
+
i++, m_real++, v_real++, m_img--, v_img--) {
|
|
5896
|
+
double r = *m_real * *v_real - *m_img * *v_img;
|
|
5897
|
+
*v_img = *m_real * *v_img + *v_real * *m_img;
|
|
5898
|
+
*v_real = r;
|
|
5899
|
+
}
|
|
5900
|
+
return self;
|
|
5901
|
+
}
|
|
5902
|
+
else if(len2 == len/2+1) { /* Complex * real*/
|
|
5903
|
+
const double * val;
|
|
5904
|
+
double * v_img;
|
|
5905
|
+
double * v_real;
|
|
5906
|
+
long i;
|
|
5907
|
+
/* First, special cases */
|
|
5908
|
+
v1[0] *= v2[0];
|
|
5909
|
+
if(len % 2 == 0)
|
|
5910
|
+
v1[len/2] *= v2[len/2];
|
|
5911
|
+
|
|
5912
|
+
for(i = 1, val = v2 + 1,
|
|
5913
|
+
v_real = v1 + 1, v_img = v1 + len-1; i < (len+1)/2;
|
|
5914
|
+
i++, val++, v_real++, v_img--) {
|
|
5915
|
+
*v_real *= *val;
|
|
5916
|
+
*v_img *= *val;
|
|
5917
|
+
}
|
|
5918
|
+
return self;
|
|
5919
|
+
}
|
|
5920
|
+
else {
|
|
5921
|
+
rb_raise(rb_eArgError, "incorrect Dvector size for fft_mul!");
|
|
5922
|
+
}
|
|
5923
|
+
}
|
|
5924
|
+
|
|
5925
|
+
|
|
5926
|
+
#endif
|
|
5927
|
+
|
|
5633
5928
|
|
|
5634
5929
|
/*
|
|
5635
5930
|
* Document-class: Dobjects::Dvector
|
|
@@ -5958,6 +6253,21 @@ void Init_Dvector() {
|
|
|
5958
6253
|
dvector_fast_fancy_read, 2);
|
|
5959
6254
|
|
|
5960
6255
|
|
|
6256
|
+
/* Local extrema */
|
|
6257
|
+
rb_define_method(cDvector, "extrema", dvector_extrema, -1);
|
|
6258
|
+
|
|
6259
|
+
/* FFT functions */
|
|
6260
|
+
#ifdef HAVE_FFTW3_H
|
|
6261
|
+
|
|
6262
|
+
rb_define_method(cDvector, "fft!", dvector_fft, 0);
|
|
6263
|
+
rb_define_method(cDvector, "rfft!", dvector_rfft, 0);
|
|
6264
|
+
rb_define_method(cDvector, "fft_spectrum", dvector_fft_spectrum, 0);
|
|
6265
|
+
rb_define_method(cDvector, "fft_mul!", dvector_fft_mul, 1);
|
|
6266
|
+
rb_define_method(cDvector, "fft_conj!", dvector_fft_conj, 0);
|
|
6267
|
+
|
|
6268
|
+
#endif
|
|
6269
|
+
|
|
6270
|
+
|
|
5961
6271
|
dvector_output_fs = Qnil;
|
|
5962
6272
|
rb_global_variable(&dvector_output_fs);
|
|
5963
6273
|
dvector_output_fs = rb_str_new2(" ");
|