[genius] Mon Dec 17 13:45:21 2012 Jiri (George) Lebl <jirka 5z com>
- From: George Lebl <jirka src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [genius] Mon Dec 17 13:45:21 2012 Jiri (George) Lebl <jirka 5z com>
- Date: Mon, 17 Dec 2012 19:45:54 +0000 (UTC)
commit 4dea9c7044955d4f23b5b3072e5588cc86cd74ec
Author: Jiri (George) Lebl <jirka 5z com>
Date: Mon Dec 17 13:45:31 2012 -0600
Mon Dec 17 13:45:21 2012 Jiri (George) Lebl <jirka 5z com>
* src/eval.c: when forloop (sum/prod/for) is with floats then check
for overrun, and if within 2^-20 times the step size, then still
execute the last body (assume things were because of roundoff
error), this makes things like for n=0 to 1 by 0.1 actually work
as expected.
* src/mpwrap.[ch], src/eval.c, src/funclib.c, src/matop.c: minor
optimization in make_float and new macro to check real part for
being floating point
* src/geniustests.txt, src/testfourier.gel: update testsuite
ChangeLog | 14 ++++++++++
NEWS | 3 ++
src/eval.c | 68 ++++++++++++++++++++++++++++++++++++++++++++------
src/funclib.c | 2 +-
src/geniustests.txt | 8 ++++++
src/matop.c | 2 +-
src/mpwrap.c | 10 +++---
src/mpwrap.h | 4 ++-
src/testfourier.gel | 4 +-
9 files changed, 96 insertions(+), 19 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 1749356..620cd37 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+Mon Dec 17 13:45:21 2012 Jiri (George) Lebl <jirka 5z com>
+
+ * src/eval.c: when forloop (sum/prod/for) is with floats then check
+ for overrun, and if within 2^-20 times the step size, then still
+ execute the last body (assume things were because of roundoff
+ error), this makes things like for n=0 to 1 by 0.1 actually work
+ as expected.
+
+ * src/mpwrap.[ch], src/eval.c, src/funclib.c, src/matop.c: minor
+ optimization in make_float and new macro to check real part for
+ being floating point
+
+ * src/geniustests.txt, src/testfourier.gel: update testsuite
+
Tue Dec 11 00:10:02 2012 Jiri (George) Lebl <jirka 5z com>
* configure.in, src/Makefile.am: exorcise last vestiges of the
diff --git a/NEWS b/NEWS
index a9d39b0..541f29b 100644
--- a/NEWS
+++ b/NEWS
@@ -17,6 +17,9 @@ Changes to 1.0.16
color is more useful when zoomed out.
* Simpler output when typing "help foo" when foo is neither defined nor
documented.
+* When for/sum/prod loops are in terms of floating point numbers and
+ the final number is within 2^-20 times the step size of the goal,
+ assume there were roundoff errors and still execute the body
* Handle wider matrices than 2^15 columns in expansion
* Fix flicker when plotting surfaces to allow animations with 3d plots
* Fix possible uninitialized crash when reading badly formed standard library
diff --git a/src/eval.c b/src/eval.c
index 6a3d1a3..81384ec 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -4099,12 +4099,47 @@ iter_pop_stack(GelCtx *ctx)
case GE_FOR:
{
GelEvalFor *evf = data;
- if(evf->by)
- mpw_add(evf->x,evf->x,evf->by);
+ gboolean done = FALSE;
+ if (evf->by)
+ mpw_add (evf->x, evf->x, evf->by);
else
- mpw_add_ui(evf->x,evf->x,1);
- /*if done*/
- if(mpw_cmp(evf->x,evf->to) == -evf->init_cmp) {
+ mpw_add_ui (evf->x, evf->x, 1);
+ /* we know we aren't dealing with complexes */
+ if (mpw_is_real_part_float (evf->x)) {
+ int thecmp = mpw_cmp (evf->x, evf->to);
+ if (mpw_cmp (evf->x, evf->to) == -evf->init_cmp) {
+ /* maybe we just missed it, let's look back within 2^-20 of the by and see */
+ mpw_t tmp;
+ if (evf->by != NULL) {
+ mpfr_ptr f;
+ /* by is definitely mpfr */
+ mpw_init_set (tmp, evf->by);
+ f = mpw_peek_real_mpf (tmp);
+ mpfr_mul_2si (f, f, -20, GMP_RNDN);
+ } else {
+ mpw_init (tmp);
+ mpw_set_d (tmp, 1.0/1048576.0 /* 2^-20 */);
+ }
+
+ mpw_sub (tmp, evf->x, tmp);
+
+ done = (mpw_cmp(tmp,evf->to) == -evf->init_cmp);
+
+ /* don't use x, but use the to, x might be too far */
+ if ( ! done) {
+ mpw_set (evf->x, evf->to);
+ }
+
+ mpw_clear (tmp);
+ } else {
+ done = FALSE;
+ }
+ } else {
+ /*if done*/
+ done = (mpw_cmp(evf->x,evf->to) == -evf->init_cmp);
+ }
+
+ if (done) {
GelETree *res;
GE_POP_STACK(ctx,data,flag);
g_assert ((flag & GE_MASK) == GE_POST);
@@ -4990,8 +5025,8 @@ iter_forloop (GelCtx *ctx, GelETree *n, gboolean *repushed)
init_cmp = mpw_cmp(from->val.value,to->val.value);
- /*if no iterations*/
if(!by) {
+ /*if no iterations*/
if(init_cmp>0) {
d_addfunc(d_makevfunc(ident->id.id,gel_copynode(from)));
freetree_full(n,TRUE,FALSE);
@@ -5007,10 +5042,17 @@ iter_forloop (GelCtx *ctx, GelETree *n, gboolean *repushed)
} else if(init_cmp==0) {
init_cmp = -1;
}
+ if (mpw_is_real_part_float (from->val.value) ||
+ mpw_is_real_part_float (to->val.value)) {
+ /* ensure all float */
+ mpw_make_float (to->val.value);
+ mpw_make_float (from->val.value);
+ }
evf = evf_new(type, from->val.value,to->val.value,NULL,init_cmp,
gel_copynode(body),body,ident->id.id);
} else {
int sgn = mpw_sgn(by->val.value);
+ /*if no iterations*/
if((sgn>0 && init_cmp>0) || (sgn<0 && init_cmp<0)) {
d_addfunc(d_makevfunc(ident->id.id,gel_copynode(from)));
freetree_full(n,TRUE,FALSE);
@@ -5026,6 +5068,14 @@ iter_forloop (GelCtx *ctx, GelETree *n, gboolean *repushed)
}
if(init_cmp == 0)
init_cmp = -sgn;
+ if (mpw_is_real_part_float (from->val.value) ||
+ mpw_is_real_part_float (to->val.value) ||
+ mpw_is_real_part_float (by->val.value)) {
+ /* ensure all float */
+ mpw_make_float (to->val.value);
+ mpw_make_float (from->val.value);
+ mpw_make_float (by->val.value);
+ }
evf = evf_new(type, from->val.value,to->val.value,by->val.value,
init_cmp,gel_copynode(body),body,ident->id.id);
}
@@ -8213,7 +8263,7 @@ op_precalc_1 (GelETree *n,
if (l->type != GEL_VALUE_NODE ||
(respect_type &&
(mpw_is_complex (l->val.value) ||
- mpw_is_float (l->val.value))))
+ mpw_is_real_part_float (l->val.value))))
return;
mpw_init(res);
(*func)(res,l->val.value);
@@ -8239,8 +8289,8 @@ op_precalc_2 (GelETree *n,
(respect_type &&
(mpw_is_complex (l->val.value) ||
mpw_is_complex (r->val.value) ||
- mpw_is_float (l->val.value) ||
- mpw_is_float (r->val.value))))
+ mpw_is_real_part_float (l->val.value) ||
+ mpw_is_real_part_float (r->val.value))))
return;
mpw_init(res);
(*func)(res,l->val.value,r->val.value);
diff --git a/src/funclib.c b/src/funclib.c
index 845ff7a..6bfc0f9 100644
--- a/src/funclib.c
+++ b/src/funclib.c
@@ -2006,7 +2006,7 @@ IsFloat_op(GelCtx *ctx, GelETree * * a, gboolean *exception)
if(a[0]->type!=GEL_VALUE_NODE ||
mpw_is_complex(a[0]->val.value))
return gel_makenum_bool (0);
- else if(mpw_is_float(a[0]->val.value))
+ else if(mpw_is_real_part_float(a[0]->val.value))
return gel_makenum_bool (1);
else
return gel_makenum_bool (0);
diff --git a/src/geniustests.txt b/src/geniustests.txt
index 6fe0e47..ec00e7f 100644
--- a/src/geniustests.txt
+++ b/src/geniustests.txt
@@ -1112,6 +1112,14 @@ sinc(5)==sin(5)/5 true
A=[1;2];B=[3;4;5;6;7];[A,B,0,null,4]+"" "[1,3,0,4;2,4,0,4;1,5,0,4;2,6,0,4;1,7,0,4]"
A=[1,2;3,4];B=[5;6;7];[A,B]+"" "[1,2,5;3,4,6;1,2,7]"
[[1;[1,2]],[3,[7;4]]]+"" "[1,1,3,7;1,2,3,4]"
+sum n=0 to 1 by 0.100000001 do n 5.500000045
+sum n=0 to 0.95 by 0.1 do n 4.5
+sum n=0 to 0.9 by 0.1 do n 4.5
+sum n=0 to 1 by 0.1 do n 5.5
+for n=0 to 1 by 0.1 do n 1.0
+for n=0 to 1 by 0.100000001 do n 1.0
+for n=0 to 1 by 0.10000001 do n 0.90000009
+for n=1 to 9.99999999999 do n 9.99999999999
load "nullspacetest.gel" true
load "longtest.gel" true
load "testprec.gel" true
diff --git a/src/matop.c b/src/matop.c
index 5d99471..f33a702 100644
--- a/src/matop.c
+++ b/src/matop.c
@@ -151,7 +151,7 @@ gel_is_matrix_value_only_rational (GelMatrixW *m)
if (n != NULL &&
(n->type != GEL_VALUE_NODE ||
mpw_is_complex (n->val.value) ||
- mpw_is_float (n->val.value))) {
+ mpw_is_real_part_float (n->val.value))) {
m->cached_value_only_rational = 1;
m->value_only_rational = 0;
return FALSE;
diff --git a/src/mpwrap.c b/src/mpwrap.c
index c1c5563..8e234e4 100644
--- a/src/mpwrap.c
+++ b/src/mpwrap.c
@@ -1,5 +1,5 @@
/* GENIUS Calculator
- * Copyright (C) 1997-2011 Jiri (George) Lebl
+ * Copyright (C) 1997-2012 Jiri (George) Lebl
*
* Author: Jiri (George) Lebl
*
@@ -5120,13 +5120,13 @@ mpw_make_int(mpw_ptr rop)
void
mpw_make_float(mpw_ptr rop)
{
- if (MPW_IS_REAL (rop)) {
+ if (rop->r->type != MPW_FLOAT) {
MAKE_COPY(rop->r);
mpwl_make_float(rop->r);
- } else {
- MAKE_COPY(rop->r);
+ }
+ if ( ! MPW_IS_REAL (rop) &&
+ rop->i->type != MPW_FLOAT) {
MAKE_COPY(rop->i);
- mpwl_make_float(rop->r);
mpwl_make_float(rop->i);
}
}
diff --git a/src/mpwrap.h b/src/mpwrap.h
index 9ebbf09..7afb57b 100644
--- a/src/mpwrap.h
+++ b/src/mpwrap.h
@@ -1,5 +1,5 @@
/* GENIUS Calculator
- * Copyright (C) 1997-2008 Jiri (George) Lebl
+ * Copyright (C) 1997-2012 Jiri (George) Lebl
*
* Author: Jiri (George) Lebl
*
@@ -303,6 +303,8 @@ gboolean mpw_is_integer(mpw_ptr op);
gboolean mpw_is_rational(mpw_ptr op);
gboolean mpw_is_float(mpw_ptr op);
+#define mpw_is_real_part_float(op) ((op)->r->type == MPW_FLOAT)
+
#define mpw_is_complex_float(op) \
( ((op)->r->type == MPW_FLOAT) || \
(MPW_IS_COMPLEX (op) && ((op)->i->type == MPW_FLOAT)) )
diff --git a/src/testfourier.gel b/src/testfourier.gel
index 2dc567b..2654c65 100644
--- a/src/testfourier.gel
+++ b/src/testfourier.gel
@@ -14,10 +14,10 @@ for x=-0.7 to 0.7 by 0.1 do (
function ff(x) = x^3+x^2;
f = NumericalFourierSineSeriesFunction(ff,1,30);
for x=0.3 to 0.7 by 0.1 do (
- if |f(x)-ff(x)| >= 0.03 then (error("Fourier test 7 fail at x=" + x);exit());
+ if |f(x)-ff(x)| >= x/15 then (error("Fourier test 7 fail at x=" + x);exit());
);
for x=0.3 to 0.7 by 0.1 do (
- if |-f(-x)-ff(x)| >= 0.03 then (error("Fourier test 8 fail at x=" + x);exit());
+ if |-f(-x)-ff(x)| >= x/15 then (error("Fourier test 8 fail at x=" + x);exit());
);
function ff(x) = x^3+x^2;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]