tioga 1.9 → 1.11
Sign up to get free protection for your applications and to get access to all the features.
- data/Tioga_README +186 -142
- data/split/Dtable/dtable.c +68 -0
- data/split/Dtable/dvector.h +13 -5
- data/split/Dvector/dvector.c +179 -10
- data/split/Dvector/dvector_intern.h +12 -0
- data/split/Dvector/include/dvector.h +13 -5
- data/split/Dvector/lib/Dvector_extras.rb +19 -0
- data/split/Function/dvector.h +13 -5
- data/split/Tioga/axes.c +100 -16
- data/split/Tioga/dvector.h +13 -5
- data/split/Tioga/figures.c +2 -0
- data/split/Tioga/figures.h +18 -0
- data/split/Tioga/init.c +9 -0
- data/split/Tioga/lib/FigMkr.rb +55 -41
- data/split/Tioga/pdfcolor.c +61 -0
- data/split/Tioga/wrappers.c +11 -0
- data/split/Tioga/wrappers.h +5 -0
- data/tests/Icon_Test.pdf +0 -0
- metadata +32 -28
data/split/Dtable/dvector.h
CHANGED
@@ -55,15 +55,23 @@ DECLARE_SYMBOL(void, Dvector_Push_Double, (VALUE ary, double val));
|
|
55
55
|
|
56
56
|
|
57
57
|
/* functions for interpolation */
|
58
|
-
DECLARE_SYMBOL(double, c_dvector_spline_interpolate,
|
59
|
-
(double x, int n_pts_data, double *Xs, double *Ys,
|
60
|
-
double *Bs, double *Cs, double *Ds));
|
61
|
-
DECLARE_SYMBOL(double, c_dvector_linear_interpolate,
|
62
|
-
(int num_pts, double *xs, double *ys, double x));
|
63
58
|
DECLARE_SYMBOL(void, c_dvector_create_spline_interpolant,
|
64
59
|
(int n_pts_data, double *Xs, double *Ys,
|
65
60
|
bool start_clamped, double start_slope,
|
66
61
|
bool end_clamped, double end_slope,
|
67
62
|
double *As, double *Bs, double *Cs));
|
63
|
+
DECLARE_SYMBOL(double, c_dvector_spline_interpolate,
|
64
|
+
(double x, int n_pts_data, double *Xs, double *Ys,
|
65
|
+
double *Bs, double *Cs, double *Ds));
|
66
|
+
|
67
|
+
DECLARE_SYMBOL(void, c_dvector_create_pm_cubic_interpolant,
|
68
|
+
(int n_pts_data, double *Xs, double *Ys,
|
69
|
+
double *As, double *Bs, double *Cs));
|
70
|
+
DECLARE_SYMBOL(double, c_dvector_pm_cubic_interpolate,
|
71
|
+
(double x, int n_pts_data, double *Xs, double *Ys,
|
72
|
+
double *Bs, double *Cs, double *Ds));
|
73
|
+
|
74
|
+
DECLARE_SYMBOL(double, c_dvector_linear_interpolate,
|
75
|
+
(int num_pts, double *xs, double *ys, double x));
|
68
76
|
#endif /* __Dvector_H__ */
|
69
77
|
|
data/split/Dvector/dvector.c
CHANGED
@@ -49,6 +49,9 @@
|
|
49
49
|
#ifndef MIN
|
50
50
|
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
|
51
51
|
#endif
|
52
|
+
#ifndef SIGN
|
53
|
+
#define SIGN(a) (((a) > 0) ? 1 : -1)
|
54
|
+
#endif
|
52
55
|
|
53
56
|
|
54
57
|
|
@@ -1068,7 +1071,8 @@ PRIVATE
|
|
1068
1071
|
* call-seq:
|
1069
1072
|
* dvector.min_gt(val) -> float or nil
|
1070
1073
|
*
|
1071
|
-
* Returns the minimum entry in _dvector_ which is greater than _val_,
|
1074
|
+
* Returns the minimum entry in _dvector_ which is greater than _val_,
|
1075
|
+
* or <code>nil</code> if no such entry if found.
|
1072
1076
|
*/ VALUE dvector_min_gt(VALUE ary, VALUE val) {
|
1073
1077
|
Dvector *d = Get_Dvector(ary);
|
1074
1078
|
val = rb_Float(val);
|
@@ -1092,7 +1096,8 @@ PRIVATE
|
|
1092
1096
|
* call-seq:
|
1093
1097
|
* dvector.max_lt(val) -> float or nil
|
1094
1098
|
*
|
1095
|
-
* Returns the maximum entry in _dvector_ which is less than _val_,
|
1099
|
+
* Returns the maximum entry in _dvector_ which is less than _val_,
|
1100
|
+
* or <code>nil</code> if no such entry if found.
|
1096
1101
|
*/ VALUE dvector_max_lt(VALUE ary, VALUE val) {
|
1097
1102
|
Dvector *d = Get_Dvector(ary);
|
1098
1103
|
val = rb_Float(val);
|
@@ -1390,7 +1395,8 @@ PRIVATE
|
|
1390
1395
|
Dvector *d2 = Get_Dvector(ary2);
|
1391
1396
|
long len = d->len;
|
1392
1397
|
if (len != d2->len) {
|
1393
|
-
rb_raise(rb_eArgError, "vectors with different lengths (%d vs %d) for reverse_each2_with_index",
|
1398
|
+
rb_raise(rb_eArgError, "vectors with different lengths (%d vs %d) for reverse_each2_with_index",
|
1399
|
+
len, d2->len);
|
1394
1400
|
}
|
1395
1401
|
while (len--) {
|
1396
1402
|
rb_yield_values(3, rb_float_new(d->ptr[len]), rb_float_new(d2->ptr[len]), LONG2NUM(len));
|
@@ -1687,8 +1693,10 @@ PRIVATE
|
|
1687
1693
|
* call-seq:
|
1688
1694
|
* dvector.dup -> a_dvector
|
1689
1695
|
*
|
1690
|
-
* Returns a copy of _dvector_.
|
1691
|
-
*
|
1696
|
+
* Returns a copy of _dvector_.
|
1697
|
+
* For performance sensitive situations involving a series of vector operations,
|
1698
|
+
* first make a copy using dup and then do "bang" operations to modify the result
|
1699
|
+
* without further copying.
|
1692
1700
|
*/ VALUE dvector_dup(VALUE ary) {
|
1693
1701
|
Dvector *d = Get_Dvector(ary);
|
1694
1702
|
return dvector_new4_dbl(d->len, d->ptr);
|
@@ -1700,7 +1708,8 @@ PRIVATE
|
|
1700
1708
|
* dvector.collect {|x| block } -> a_dvector
|
1701
1709
|
* dvector.map {|x| block } -> a_dvector
|
1702
1710
|
*
|
1703
|
-
* Invokes <i>block</i> once for each element of _dvector_.
|
1711
|
+
* Invokes <i>block</i> once for each element of _dvector_.
|
1712
|
+
* Returns a new vector holding the values returned by _block_.
|
1704
1713
|
* Note that for numeric operations on long vectors, it is more efficient to
|
1705
1714
|
* apply the operator directly to the vector rather than using map or collect.
|
1706
1715
|
*
|
@@ -4896,7 +4905,8 @@ PRIVATE
|
|
4896
4905
|
* Replaces contents of _dvector_ by control points for Bezier curve.
|
4897
4906
|
* The cubic, y(x), is defined from x0 to x0+delta_x.
|
4898
4907
|
* At location x = x0 + dx, with dx between 0 and delta_x, define y = a*dx^3 + b*dx^2 + c*dx + y0.
|
4899
|
-
* This routine replaces the contents of _dest_ by [x1, y1, x2, y2, x3, y3],
|
4908
|
+
* This routine replaces the contents of _dest_ by [x1, y1, x2, y2, x3, y3],
|
4909
|
+
* the Bezier control points to match this cubic.
|
4900
4910
|
*
|
4901
4911
|
*/
|
4902
4912
|
VALUE dvector_make_bezier_control_points_for_cubic_in_x(VALUE dest, VALUE x0, VALUE y0, VALUE delta_x, VALUE a, VALUE b, VALUE c)
|
@@ -4911,6 +4921,162 @@ VALUE dvector_make_bezier_control_points_for_cubic_in_x(VALUE dest, VALUE x0, VA
|
|
4911
4921
|
NUM2DBL(x0), NUM2DBL(y0), NUM2DBL(delta_x), NUM2DBL(a), NUM2DBL(b), NUM2DBL(c));
|
4912
4922
|
}
|
4913
4923
|
|
4924
|
+
|
4925
|
+
|
4926
|
+
|
4927
|
+
|
4928
|
+
void c_dvector_create_pm_cubic_interpolant(int nx, double *x, double *f,
|
4929
|
+
double *As, double *Bs, double *Cs)
|
4930
|
+
{
|
4931
|
+
double *h = (double *)ALLOC_N(double, nx);
|
4932
|
+
double *s = (double *)ALLOC_N(double, nx);
|
4933
|
+
double *p = (double *)ALLOC_N(double, nx);
|
4934
|
+
double as00, asm1, ap00, sm1, s00;
|
4935
|
+
int n = nx-1, i;
|
4936
|
+
|
4937
|
+
|
4938
|
+
for (i=0; i < n; i++) {
|
4939
|
+
h[i] = x[i+1] - x[i];
|
4940
|
+
s[i] = (f[i+1] - f[i])/h[i];
|
4941
|
+
}
|
4942
|
+
|
4943
|
+
/* slope at i of parabola through i-1, i, and i+1 */
|
4944
|
+
for (i=1; i < n; i++) {
|
4945
|
+
p[i] = (s[i-1]*h[i] + s[i]*h[i-1])/(h[i]+h[i-1]);
|
4946
|
+
}
|
4947
|
+
|
4948
|
+
/* "safe" slope at i to ensure monotonic -- see Steffen paper for explanation. */
|
4949
|
+
for (i=1; i < n; i++) {
|
4950
|
+
asm1 = fabs(s[i-1]);
|
4951
|
+
as00 = fabs(s[i]);
|
4952
|
+
ap00 = fabs(p[i]);
|
4953
|
+
sm1 = (s[i-1] > 0)? 1.0 : -1.0;
|
4954
|
+
s00 = (s[i] > 0)? 1.0 : -1.0;
|
4955
|
+
Cs[i] = (sm1+s00)*MIN(asm1, MIN(as00, 0.5*ap00));
|
4956
|
+
}
|
4957
|
+
|
4958
|
+
/* slope at 1st point of parabola through 1st 3 points */
|
4959
|
+
p[0] = s[0]*(1 + h[0] / (h[0] + h[1])) - s[1] * h[0] / (h[0] + h[1]);
|
4960
|
+
|
4961
|
+
/* safe slope at 1st point */
|
4962
|
+
if (p[0]*s[0] <= 0) {
|
4963
|
+
Cs[0] = 0;
|
4964
|
+
} else if (fabs(p[0]) > 2.0*fabs(s[0])) {
|
4965
|
+
Cs[0] = 2.0*s[0];
|
4966
|
+
} else {
|
4967
|
+
Cs[0] = p[0];
|
4968
|
+
}
|
4969
|
+
|
4970
|
+
/* slope at last point of parabola through last 3 points */
|
4971
|
+
p[n] = s[n-1]*(1 + h[n-1] / (h[n-1] + h[n-2])) - s[n-2]*h[n-1] / (h[n-1] + h[n-2]);
|
4972
|
+
|
4973
|
+
/* safe slope at last point */
|
4974
|
+
if (p[n]*s[n-1] <= 0) {
|
4975
|
+
Cs[n] = 0;
|
4976
|
+
} else if (fabs(p[n]) > 2.0*fabs(s[n-1])) {
|
4977
|
+
Cs[n] = 2.0*s[n-1];
|
4978
|
+
} else {
|
4979
|
+
Cs[n] = p[n];
|
4980
|
+
}
|
4981
|
+
|
4982
|
+
for (i=0; i < n; i++) {
|
4983
|
+
Bs[i] = (3.0*s[i] - 2.0*Cs[i] - Cs[i+1]) / h[i];
|
4984
|
+
}
|
4985
|
+
Bs[n] = 0;
|
4986
|
+
|
4987
|
+
for (i=1; i < n; i++) {
|
4988
|
+
As[i] = (Cs[i] + Cs[i+1] - 2.0*s[i]) / (h[i]*h[i]);
|
4989
|
+
}
|
4990
|
+
As[n] = 0;
|
4991
|
+
|
4992
|
+
free(p); free(s); free(h);
|
4993
|
+
}
|
4994
|
+
|
4995
|
+
PRIVATE
|
4996
|
+
/*
|
4997
|
+
* call-seq:
|
4998
|
+
* Dvector.create_pm_cubic_interpolant(xs, ys) -> interpolant
|
4999
|
+
*
|
5000
|
+
* Uses Dvectors _xs_ and _ys_ to create a cubic pm_cubic interpolant. The _xs_ must be given in ascending order.
|
5001
|
+
* The interpolant is an array of Dvectors: [Xs, Ys, As, Bs, Cs].
|
5002
|
+
* For x between Xs[j] and Xs[j+1], let dx = x - Xs[j], and find interpolated y for x by
|
5003
|
+
* y = As[j]*dx^3 + Bs[j]*dx^2 + Cs[j]*dx + Ys[j].
|
5004
|
+
* pm_cubic algorithms derived from Steffen, M., "A simple method for monotonic interpolation in one dimension",
|
5005
|
+
* Astron. Astrophys., (239) 1990, 443-450.
|
5006
|
+
*
|
5007
|
+
*/
|
5008
|
+
VALUE dvector_create_pm_cubic_interpolant(int argc, VALUE *argv, VALUE klass) {
|
5009
|
+
if (argc != 2)
|
5010
|
+
rb_raise(rb_eArgError, "wrong # of arguments(%d) for create_pm_cubic_interpolant", argc);
|
5011
|
+
klass = Qnil;
|
5012
|
+
VALUE Xs = argv[0], Ys = argv[1];
|
5013
|
+
long xdlen, ydlen;
|
5014
|
+
double start = 0.0, end = 0.0;
|
5015
|
+
double *X_data = Dvector_Data_for_Read(Xs, &xdlen);
|
5016
|
+
double *Y_data = Dvector_Data_for_Read(Ys, &ydlen);
|
5017
|
+
if (X_data == NULL || Y_data == NULL || xdlen != ydlen)
|
5018
|
+
rb_raise(rb_eArgError, "Data for create_pm_cubic_interpolant must be equal length Dvectors");
|
5019
|
+
int nx = xdlen;
|
5020
|
+
VALUE As = Dvector_Create(), Bs = Dvector_Create(), Cs = Dvector_Create();
|
5021
|
+
double *As_data = Dvector_Data_Resize(As, nx);
|
5022
|
+
double *Bs_data = Dvector_Data_Resize(Bs, nx);
|
5023
|
+
double *Cs_data = Dvector_Data_Resize(Cs, nx);
|
5024
|
+
c_dvector_create_pm_cubic_interpolant(nx, X_data, Y_data, As_data, Bs_data, Cs_data);
|
5025
|
+
VALUE result = rb_ary_new2(5);
|
5026
|
+
rb_ary_store(result, 0, Xs);
|
5027
|
+
rb_ary_store(result, 1, Ys);
|
5028
|
+
rb_ary_store(result, 2, As);
|
5029
|
+
rb_ary_store(result, 3, Bs);
|
5030
|
+
rb_ary_store(result, 4, Cs);
|
5031
|
+
return result;
|
5032
|
+
}
|
5033
|
+
|
5034
|
+
double c_dvector_pm_cubic_interpolate(double x, int nx,
|
5035
|
+
double *Xs, double *Ys, double *As, double *Bs, double *Cs)
|
5036
|
+
{
|
5037
|
+
int j;
|
5038
|
+
for (j = 0; j < nx && x >= Xs[j]; j++);
|
5039
|
+
if (j == nx) return Ys[j-1];
|
5040
|
+
if (j == 0) return Ys[0];
|
5041
|
+
j--;
|
5042
|
+
double dx = x - Xs[j];
|
5043
|
+
return Ys[j] + dx*(Cs[j] + dx*(Bs[j] + dx*As[j]));
|
5044
|
+
}
|
5045
|
+
|
5046
|
+
PRIVATE
|
5047
|
+
/*
|
5048
|
+
* call-seq:
|
5049
|
+
* Dvector.pm_cubic_interpolate(x, interpolant) -> y
|
5050
|
+
*
|
5051
|
+
* Returns the _y_ corresponding to _x_ by pm_cubic interpolation using the _interpolant_
|
5052
|
+
* which was previously created by calling _create_pm_cubic_interpolant_.
|
5053
|
+
*
|
5054
|
+
*/
|
5055
|
+
VALUE dvector_pm_cubic_interpolate(int argc, VALUE *argv, VALUE klass) {
|
5056
|
+
if (argc != 2)
|
5057
|
+
rb_raise(rb_eArgError, "wrong # of arguments(%d) for pm_cubic_interpolate", argc);
|
5058
|
+
klass = Qnil;
|
5059
|
+
VALUE x = argv[0];
|
5060
|
+
VALUE interpolant = argv[1];
|
5061
|
+
x = rb_Float(x);
|
5062
|
+
interpolant = rb_Array(interpolant);
|
5063
|
+
if (RARRAY(interpolant)->len != 5)
|
5064
|
+
rb_raise(rb_eArgError, "interpolant must be array of length 5 from create_pm_cubic_interpolant");
|
5065
|
+
Dvector *Xs = Get_Dvector(rb_ary_entry(interpolant,0));
|
5066
|
+
Dvector *Ys = Get_Dvector(rb_ary_entry(interpolant,1));
|
5067
|
+
Dvector *As = Get_Dvector(rb_ary_entry(interpolant,2));
|
5068
|
+
Dvector *Bs = Get_Dvector(rb_ary_entry(interpolant,3));
|
5069
|
+
Dvector *Cs = Get_Dvector(rb_ary_entry(interpolant,4));
|
5070
|
+
if (Xs->len <= 0 || Xs->len != Ys->len || Xs->len != Bs->len || Xs->len != Cs->len || Xs->len != As->len)
|
5071
|
+
rb_raise(rb_eArgError, "interpolant must be from create_pm_cubic_interpolant");
|
5072
|
+
double y = c_dvector_pm_cubic_interpolate(NUM2DBL(x), Xs->len, Xs->ptr, Ys->ptr, As->ptr, Bs->ptr, Cs->ptr);
|
5073
|
+
return rb_float_new(y);
|
5074
|
+
}
|
5075
|
+
|
5076
|
+
|
5077
|
+
|
5078
|
+
|
5079
|
+
|
4914
5080
|
void c_dvector_create_spline_interpolant(int n_pts_data, double *Xs, double *Ys,
|
4915
5081
|
bool start_clamped, double start_slope, bool end_clamped, double end_slope,
|
4916
5082
|
double *As, double *Bs, double *Cs)
|
@@ -5319,7 +5485,8 @@ static VALUE dvector_convolve(VALUE self, VALUE kernel, VALUE middle)
|
|
5319
5485
|
:call-seq:
|
5320
5486
|
Dvector.fast_fancy_read(stream, options) => Array_of_Dvectors
|
5321
5487
|
|
5322
|
-
Reads data from an IO stream
|
5488
|
+
Reads data from an IO stream (or anything that supports a gets method)
|
5489
|
+
and separate it into columns of data
|
5323
5490
|
according to the _options_, a hash holding the following elements
|
5324
5491
|
(compulsory, but you can use FANCY_READ_DEFAULTS):
|
5325
5492
|
* 'sep': a regular expression that separate the entries
|
@@ -5333,8 +5500,6 @@ static VALUE dvector_convolve(VALUE self, VALUE kernel, VALUE middle)
|
|
5333
5500
|
|
5334
5501
|
As a side note, the read time is highly non-linear, which suggests that
|
5335
5502
|
the read is memory-allocation/copying-limited, at least for big files.
|
5336
|
-
Well, the read time is non-linear for
|
5337
|
-
|
5338
5503
|
|
5339
5504
|
An internal memory allocation with aggressive policy should solve that,
|
5340
5505
|
that is, not using directly Dvectors (and it would be way faster to store
|
@@ -5534,6 +5699,10 @@ void Init_Dvector() {
|
|
5534
5699
|
rb_define_singleton_method(cDvector, "read_row", dvector_read_row, -1);
|
5535
5700
|
rb_define_singleton_method(cDvector, "create_spline_interpolant", dvector_create_spline_interpolant, -1);
|
5536
5701
|
rb_define_singleton_method(cDvector, "spline_interpolate", dvector_spline_interpolate, -1);
|
5702
|
+
|
5703
|
+
rb_define_singleton_method(cDvector, "create_pm_cubic_interpolant", dvector_create_pm_cubic_interpolant, -1);
|
5704
|
+
rb_define_singleton_method(cDvector, "pm_cubic_interpolate", dvector_pm_cubic_interpolate, -1);
|
5705
|
+
|
5537
5706
|
rb_define_singleton_method(cDvector, "linear_interpolate", dvector_linear_interpolate, -1);
|
5538
5707
|
rb_define_singleton_method(cDvector, "min_of_many", dvector_min_of_many, 1);
|
5539
5708
|
rb_define_singleton_method(cDvector, "max_of_many", dvector_max_of_many, 1);
|
@@ -135,6 +135,18 @@ PRIVATE double c_dvector_spline_interpolate(double x, int n_pts_data,
|
|
135
135
|
double *Xs, double *Ys, double *Bs, double *Cs, double *Ds);
|
136
136
|
PRIVATE VALUE dvector_spline_interpolate(int argc, VALUE *argv, VALUE klass);
|
137
137
|
|
138
|
+
|
139
|
+
|
140
|
+
PRIVATE void c_dvector_create_pm_cubic_interpolant(int n_pts_data, double *Xs, double *Ys,
|
141
|
+
double *Bs, double *Cs, double *Ds);
|
142
|
+
PRIVATE VALUE dvector_create_pm_cubic_interpolant(int argc, VALUE *argv, VALUE klass);
|
143
|
+
|
144
|
+
PRIVATE double c_dvector_pm_cubic_interpolate(double x, int n_pts_data,
|
145
|
+
double *Xs, double *Ys, double *Bs, double *Cs, double *Ds);
|
146
|
+
PRIVATE VALUE dvector_pm_cubic_interpolate(int argc, VALUE *argv, VALUE klass);
|
147
|
+
|
148
|
+
|
149
|
+
|
138
150
|
PRIVATE double c_dvector_linear_interpolate(int num_pts, double *xs, double *ys, double x);
|
139
151
|
PRIVATE VALUE dvector_linear_interpolate(int argc, VALUE *argv, VALUE klass);
|
140
152
|
|
@@ -55,15 +55,23 @@ DECLARE_SYMBOL(void, Dvector_Push_Double, (VALUE ary, double val));
|
|
55
55
|
|
56
56
|
|
57
57
|
/* functions for interpolation */
|
58
|
-
DECLARE_SYMBOL(double, c_dvector_spline_interpolate,
|
59
|
-
(double x, int n_pts_data, double *Xs, double *Ys,
|
60
|
-
double *Bs, double *Cs, double *Ds));
|
61
|
-
DECLARE_SYMBOL(double, c_dvector_linear_interpolate,
|
62
|
-
(int num_pts, double *xs, double *ys, double x));
|
63
58
|
DECLARE_SYMBOL(void, c_dvector_create_spline_interpolant,
|
64
59
|
(int n_pts_data, double *Xs, double *Ys,
|
65
60
|
bool start_clamped, double start_slope,
|
66
61
|
bool end_clamped, double end_slope,
|
67
62
|
double *As, double *Bs, double *Cs));
|
63
|
+
DECLARE_SYMBOL(double, c_dvector_spline_interpolate,
|
64
|
+
(double x, int n_pts_data, double *Xs, double *Ys,
|
65
|
+
double *Bs, double *Cs, double *Ds));
|
66
|
+
|
67
|
+
DECLARE_SYMBOL(void, c_dvector_create_pm_cubic_interpolant,
|
68
|
+
(int n_pts_data, double *Xs, double *Ys,
|
69
|
+
double *As, double *Bs, double *Cs));
|
70
|
+
DECLARE_SYMBOL(double, c_dvector_pm_cubic_interpolate,
|
71
|
+
(double x, int n_pts_data, double *Xs, double *Ys,
|
72
|
+
double *Bs, double *Cs, double *Ds));
|
73
|
+
|
74
|
+
DECLARE_SYMBOL(double, c_dvector_linear_interpolate,
|
75
|
+
(int num_pts, double *xs, double *ys, double x));
|
68
76
|
#endif /* __Dvector_H__ */
|
69
77
|
|
@@ -33,9 +33,28 @@ module Dobjects
|
|
33
33
|
#
|
34
34
|
# e = MathEvaluator.new("x*y", "x,y")
|
35
35
|
# e.compute(1,2) -> 2
|
36
|
+
#
|
37
|
+
# If an exception arises, NaN is returned. Note that compilation
|
38
|
+
# problems will be caught before ;-)...
|
36
39
|
def compute(*args)
|
40
|
+
begin
|
41
|
+
return compute_unsafe(*args)
|
42
|
+
rescue
|
43
|
+
return 0.0/0.0
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# This function does the actual evaluation with the blocks
|
48
|
+
# given.
|
49
|
+
#
|
50
|
+
# e = MathEvaluator.new("x*y", "x,y")
|
51
|
+
# e.compute(1,2) -> 2
|
52
|
+
#
|
53
|
+
# No care is taken to intercept exceptions.
|
54
|
+
def compute_unsafe(*args)
|
37
55
|
return @block.call(*args)
|
38
56
|
end
|
57
|
+
|
39
58
|
end
|
40
59
|
|
41
60
|
class Dvector
|
data/split/Function/dvector.h
CHANGED
@@ -55,15 +55,23 @@ DECLARE_SYMBOL(void, Dvector_Push_Double, (VALUE ary, double val));
|
|
55
55
|
|
56
56
|
|
57
57
|
/* functions for interpolation */
|
58
|
-
DECLARE_SYMBOL(double, c_dvector_spline_interpolate,
|
59
|
-
(double x, int n_pts_data, double *Xs, double *Ys,
|
60
|
-
double *Bs, double *Cs, double *Ds));
|
61
|
-
DECLARE_SYMBOL(double, c_dvector_linear_interpolate,
|
62
|
-
(int num_pts, double *xs, double *ys, double x));
|
63
58
|
DECLARE_SYMBOL(void, c_dvector_create_spline_interpolant,
|
64
59
|
(int n_pts_data, double *Xs, double *Ys,
|
65
60
|
bool start_clamped, double start_slope,
|
66
61
|
bool end_clamped, double end_slope,
|
67
62
|
double *As, double *Bs, double *Cs));
|
63
|
+
DECLARE_SYMBOL(double, c_dvector_spline_interpolate,
|
64
|
+
(double x, int n_pts_data, double *Xs, double *Ys,
|
65
|
+
double *Bs, double *Cs, double *Ds));
|
66
|
+
|
67
|
+
DECLARE_SYMBOL(void, c_dvector_create_pm_cubic_interpolant,
|
68
|
+
(int n_pts_data, double *Xs, double *Ys,
|
69
|
+
double *As, double *Bs, double *Cs));
|
70
|
+
DECLARE_SYMBOL(double, c_dvector_pm_cubic_interpolate,
|
71
|
+
(double x, int n_pts_data, double *Xs, double *Ys,
|
72
|
+
double *Bs, double *Cs, double *Ds));
|
73
|
+
|
74
|
+
DECLARE_SYMBOL(double, c_dvector_linear_interpolate,
|
75
|
+
(int num_pts, double *xs, double *ys, double x));
|
68
76
|
#endif /* __Dvector_H__ */
|
69
77
|
|
data/split/Tioga/axes.c
CHANGED
@@ -20,19 +20,15 @@
|
|
20
20
|
along with Tioga; if not, write to the Free Software
|
21
21
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
22
22
|
*/
|
23
|
+
#include <math.h>
|
24
|
+
|
23
25
|
#include "figures.h"
|
24
26
|
#include "pdfs.h"
|
25
27
|
|
28
|
+
|
29
|
+
|
26
30
|
/*
|
27
31
|
Here is my (Vincent) big TODO-list for the axes stuff:
|
28
|
-
* provide a way to reliably get the location from major/minor
|
29
|
-
ticks for a given axis, so users can build lines/grids that build on
|
30
|
-
top of that (or rather under it ;-)...)
|
31
|
-
-> this is partly done, as you can now get the major ticks position.
|
32
|
-
* let the users choose between the current way to pick up ticks position
|
33
|
-
and another, such as the one I'm using in SciYAG, which seems to give
|
34
|
-
results that are more according to my expectations.
|
35
|
-
|
36
32
|
* BUG fix: apparently, two calls to the axes stuff do no return the
|
37
33
|
same thing, so I'll need to have a careful look at that
|
38
34
|
*/
|
@@ -41,9 +37,17 @@ typedef struct {
|
|
41
37
|
int type;
|
42
38
|
int other_axis_type;
|
43
39
|
double line_width;
|
40
|
+
|
41
|
+
/* Stroke color... */
|
44
42
|
double stroke_color_R;
|
45
43
|
double stroke_color_G;
|
46
44
|
double stroke_color_B;
|
45
|
+
|
46
|
+
/* Tick labels color */
|
47
|
+
double labels_color_R;
|
48
|
+
double labels_color_G;
|
49
|
+
double labels_color_B;
|
50
|
+
|
47
51
|
double major_tick_width; // same units as line_width
|
48
52
|
double minor_tick_width; // same units as line_width
|
49
53
|
double major_tick_length; // in units of numeric label char heights
|
@@ -127,6 +131,11 @@ static void Get_xaxis_Specs(OBJ_PTR fmkr, FM *p, PlotAxis *s, int *ierr)
|
|
127
131
|
s->stroke_color_R = p->xaxis_stroke_color_R; // for axis line and tick marks
|
128
132
|
s->stroke_color_G = p->xaxis_stroke_color_G;
|
129
133
|
s->stroke_color_B = p->xaxis_stroke_color_B;
|
134
|
+
|
135
|
+
s->labels_color_R = p->xaxis_labels_color_R; // for axis line and tick marks
|
136
|
+
s->labels_color_G = p->xaxis_labels_color_G;
|
137
|
+
s->labels_color_B = p->xaxis_labels_color_B;
|
138
|
+
|
130
139
|
s->major_tick_width = p->xaxis_major_tick_width; // same units as line_width
|
131
140
|
s->minor_tick_width = p->xaxis_minor_tick_width; // same units as line_width
|
132
141
|
s->major_tick_length = p->xaxis_major_tick_length; // in units of numeric label char heights
|
@@ -163,9 +172,15 @@ static void Get_yaxis_Specs(OBJ_PTR fmkr, FM *p, PlotAxis *s, int *ierr)
|
|
163
172
|
s->type = p->yaxis_type;
|
164
173
|
s->other_axis_type = p->xaxis_type;
|
165
174
|
s->line_width = p->yaxis_line_width; // for axis line
|
175
|
+
|
166
176
|
s->stroke_color_R = p->yaxis_stroke_color_R; // for axis line and tick marks
|
167
177
|
s->stroke_color_G = p->yaxis_stroke_color_G;
|
168
178
|
s->stroke_color_B = p->yaxis_stroke_color_B;
|
179
|
+
|
180
|
+
s->labels_color_R = p->yaxis_labels_color_R; // for axis line and tick marks
|
181
|
+
s->labels_color_G = p->yaxis_labels_color_G;
|
182
|
+
s->labels_color_B = p->yaxis_labels_color_B;
|
183
|
+
|
169
184
|
s->major_tick_width = p->yaxis_major_tick_width; // same units as line_width
|
170
185
|
s->minor_tick_width = p->yaxis_minor_tick_width; // same units as line_width
|
171
186
|
s->major_tick_length = p->yaxis_major_tick_length; // in units of numeric label char heights
|
@@ -635,16 +650,21 @@ static double * pick_major_ticks_positions_Vincent(OBJ_PTR fmkr, FM *p,
|
|
635
650
|
double norm_tick_min = tick_min/factor;
|
636
651
|
int i;
|
637
652
|
|
653
|
+
/* printf("axis_min: %g\taxis_max: %g\n", axis_min, axis_max); */
|
638
654
|
/* We get the one just above tick_min */
|
639
655
|
for(i = 0; i < nb_natural_distances; i++)
|
640
656
|
if(natural_distances[i] >= norm_tick_min)
|
641
657
|
break;
|
642
658
|
|
659
|
+
|
643
660
|
*tick = natural_distances[i] * factor;
|
661
|
+
/* printf("norm_tick_min: %g\ttick: %g\ttick_min:%g\n", */
|
662
|
+
/* norm_tick_min, *tick, tick_min); */
|
644
663
|
double first_tick = ceil(axis_min /(*tick)) * (*tick);
|
645
664
|
double last_tick = floor(axis_max /(*tick)) * (*tick);
|
646
665
|
|
647
|
-
*num_locations = (int)((last_tick - first_tick)/(*tick)
|
666
|
+
*num_locations = (int)round((last_tick - first_tick)/(*tick));
|
667
|
+
*num_locations += 1;
|
648
668
|
|
649
669
|
double *majors = ALLOC_N_double(*num_locations);
|
650
670
|
for (i = 0; i < *num_locations; i++)
|
@@ -831,6 +851,13 @@ static void draw_minor_ticks(OBJ_PTR fmkr, FM *p, PlotAxis *s, int *ierr)
|
|
831
851
|
static void show_numeric_label(OBJ_PTR fmkr, FM *p, PlotAxis *s,
|
832
852
|
char *text, int location, double position, double shift, int *ierr)
|
833
853
|
{
|
854
|
+
/* We need a buffer to implement the color */
|
855
|
+
long len = strlen(text) + 100; /* Should be enough overhead ! */
|
856
|
+
char * buffer = ALLOC_N_char(len);
|
857
|
+
snprintf(buffer, len, "\\textcolor[rgb]{%0.2f,%0.2f,%0.2f}{%s}",
|
858
|
+
s->labels_color_R, s->labels_color_G, s->labels_color_B,
|
859
|
+
text);
|
860
|
+
|
834
861
|
if(location == AXIS_FREE_LOCATION) {
|
835
862
|
/* We convert the tick position into frame position */
|
836
863
|
double x,y, ft_ht = p->default_text_scale *
|
@@ -852,7 +879,7 @@ static void show_numeric_label(OBJ_PTR fmkr, FM *p, PlotAxis *s,
|
|
852
879
|
ft_ht * ENLARGE * shift);
|
853
880
|
}
|
854
881
|
|
855
|
-
c_show_rotated_label(fmkr, p,
|
882
|
+
c_show_rotated_label(fmkr, p, buffer, x, y,
|
856
883
|
s->numeric_label_scale,
|
857
884
|
s->numeric_label_angle + angle,
|
858
885
|
s->numeric_label_justification,
|
@@ -862,9 +889,10 @@ static void show_numeric_label(OBJ_PTR fmkr, FM *p, PlotAxis *s,
|
|
862
889
|
else {
|
863
890
|
// position is in figure coords and must be converted to frame coords
|
864
891
|
double pos = ((!s->reversed)? (position - s->axis_min) : (s->axis_max - position)) / s->length;
|
865
|
-
c_show_rotated_text(fmkr, p,
|
892
|
+
c_show_rotated_text(fmkr, p, buffer, location, shift, pos,
|
866
893
|
s->numeric_label_scale, s->numeric_label_angle, s->numeric_label_justification, s->numeric_label_alignment, OBJ_NIL, ierr);
|
867
894
|
}
|
895
|
+
free(buffer);
|
868
896
|
}
|
869
897
|
|
870
898
|
static void draw_numeric_labels(OBJ_PTR fmkr, FM *p, int location, PlotAxis *s, int *ierr)
|
@@ -1168,6 +1196,40 @@ static int prepare_dict_PlotAxis(OBJ_PTR fmkr, FM *p,
|
|
1168
1196
|
if(Hash_Has_Key(axis_spec, "minor_tick_length"))
|
1169
1197
|
axis->minor_tick_length = Hash_Get_Double(axis_spec, "minor_tick_length");
|
1170
1198
|
|
1199
|
+
/* Stroke color */
|
1200
|
+
if(Hash_Has_Key(axis_spec, "stroke_color") ||
|
1201
|
+
Hash_Has_Key(axis_spec, "color")) {
|
1202
|
+
OBJ_PTR color = (Hash_Has_Key(axis_spec, "stroke_color") ?
|
1203
|
+
Hash_Get_Obj(axis_spec, "stroke_color") :
|
1204
|
+
Hash_Get_Obj(axis_spec, "color") );
|
1205
|
+
int err;
|
1206
|
+
axis->stroke_color_R = Array_Entry_double(color, 0, &err);
|
1207
|
+
axis->stroke_color_G = Array_Entry_double(color, 1, &err);
|
1208
|
+
axis->stroke_color_B = Array_Entry_double(color, 2, &err);
|
1209
|
+
}
|
1210
|
+
|
1211
|
+
/* Labels color */
|
1212
|
+
if(Hash_Has_Key(axis_spec, "labels_color") ||
|
1213
|
+
Hash_Has_Key(axis_spec, "color")) {
|
1214
|
+
OBJ_PTR color = (Hash_Has_Key(axis_spec, "labels_color") ?
|
1215
|
+
Hash_Get_Obj(axis_spec, "labels_color") :
|
1216
|
+
Hash_Get_Obj(axis_spec, "color") );
|
1217
|
+
int err;
|
1218
|
+
axis->labels_color_R = Array_Entry_double(color, 0, &err);
|
1219
|
+
axis->labels_color_G = Array_Entry_double(color, 1, &err);
|
1220
|
+
axis->labels_color_B = Array_Entry_double(color, 2, &err);
|
1221
|
+
}
|
1222
|
+
|
1223
|
+
/* Log scale: */
|
1224
|
+
if(Hash_Has_Key(axis_spec, "log")) {
|
1225
|
+
OBJ_PTR val = Hash_Get_Obj(axis_spec, "log");
|
1226
|
+
if(val == OBJ_NIL || val == OBJ_FALSE)
|
1227
|
+
axis->log_vals = 0;
|
1228
|
+
else
|
1229
|
+
axis->log_vals = 1;
|
1230
|
+
}
|
1231
|
+
|
1232
|
+
|
1171
1233
|
return 1;
|
1172
1234
|
}
|
1173
1235
|
|
@@ -1193,7 +1255,8 @@ void c_show_axis_generic(OBJ_PTR fmkr, FM *p, OBJ_PTR axis_spec, int *ierr)
|
|
1193
1255
|
/*
|
1194
1256
|
This function takes an axis specification (either integer or
|
1195
1257
|
hash) and returns a hash containing the following keys:
|
1196
|
-
* '
|
1258
|
+
* 'major_ticks' : position of all major ticks
|
1259
|
+
* 'minor_ticks' : position of all major ticks
|
1197
1260
|
* 'labels' : the names of all labels
|
1198
1261
|
* 'vertical' : if the axis is vertical or horizontal
|
1199
1262
|
* 'line_width' : the line width
|
@@ -1202,8 +1265,9 @@ void c_show_axis_generic(OBJ_PTR fmkr, FM *p, OBJ_PTR axis_spec, int *ierr)
|
|
1202
1265
|
* 'scale', 'shift' and 'angle': the scale, shift and angle of numeric
|
1203
1266
|
labels
|
1204
1267
|
* 'x0', 'y0', 'x1', 'y1': the position of the axis in figure coordinates
|
1205
|
-
|
1206
|
-
|
1268
|
+
* 'stroke_color': the color to use for drawing lines.
|
1269
|
+
* 'labels_color': the color to use for drawing tick labels.
|
1270
|
+
*/
|
1207
1271
|
OBJ_PTR c_axis_get_information(OBJ_PTR fmkr, FM *p, OBJ_PTR axis_spec,
|
1208
1272
|
int *ierr)
|
1209
1273
|
{
|
@@ -1219,14 +1283,15 @@ OBJ_PTR c_axis_get_information(OBJ_PTR fmkr, FM *p, OBJ_PTR axis_spec,
|
|
1219
1283
|
/* First, major ticks positions */
|
1220
1284
|
prepare_axis_coordinates(fmkr, p, axis.location, &axis, ierr);
|
1221
1285
|
compute_major_ticks(fmkr, p, &axis, ierr);
|
1222
|
-
Hash_Set_Obj(hash, "
|
1286
|
+
Hash_Set_Obj(hash, "major_ticks", Vector_New(axis.nmajors, axis.majors));
|
1223
1287
|
|
1224
1288
|
/* Then, minor ticks positions */
|
1225
1289
|
double * minor;
|
1226
1290
|
long count;
|
1291
|
+
OBJ_PTR color;
|
1227
1292
|
minor = get_minor_ticks_location(fmkr, p, &axis, &count);
|
1228
1293
|
if(minor) {
|
1229
|
-
Hash_Set_Obj(hash, "
|
1294
|
+
Hash_Set_Obj(hash, "minor_ticks", Vector_New(count, minor));
|
1230
1295
|
free(minor);
|
1231
1296
|
}
|
1232
1297
|
|
@@ -1259,6 +1324,25 @@ OBJ_PTR c_axis_get_information(OBJ_PTR fmkr, FM *p, OBJ_PTR axis_spec,
|
|
1259
1324
|
Hash_Set_Double(hash, "y0", axis.y0);
|
1260
1325
|
Hash_Set_Double(hash, "y1", axis.y1);
|
1261
1326
|
|
1327
|
+
/* Log values */
|
1328
|
+
Hash_Set_Obj(hash, "log", axis.log_vals ? OBJ_TRUE : OBJ_FALSE);
|
1329
|
+
|
1330
|
+
/* Stroke color */
|
1331
|
+
color = Array_New(3);
|
1332
|
+
Array_Store(color, 0, Float_New(axis.stroke_color_R),ierr);
|
1333
|
+
Array_Store(color, 1, Float_New(axis.stroke_color_G),ierr);
|
1334
|
+
Array_Store(color, 2, Float_New(axis.stroke_color_B),ierr);
|
1335
|
+
Hash_Set_Obj(hash, "stroke_color", color);
|
1336
|
+
|
1337
|
+
/* Tick labels color */
|
1338
|
+
color = Array_New(3);
|
1339
|
+
Array_Store(color, 0, Float_New(axis.labels_color_R),ierr);
|
1340
|
+
Array_Store(color, 1, Float_New(axis.labels_color_G),ierr);
|
1341
|
+
Array_Store(color, 2, Float_New(axis.labels_color_B),ierr);
|
1342
|
+
Hash_Set_Obj(hash, "labels_color", color);
|
1343
|
+
|
1344
|
+
|
1345
|
+
|
1262
1346
|
free_allocated_memory(&axis);
|
1263
1347
|
return hash;
|
1264
1348
|
}
|