tioga 1.11 → 1.13
Sign up to get free protection for your applications and to get access to all the features.
- 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(" ");
|