Commit 66568dc2 authored by Jiri (George) Lebl's avatar Jiri (George) Lebl Committed by George Lebl

Some more simplification special casing, doing several tan derivatives is


Fri Jun 24 17:21:22 2005  George Lebl <jirka@5z.com>

	* src/symbolic.c, src/eval.c, src/geniustests.txt: Some more
	  simplification special casing, doing several tan derivatives is
	  now much faster and results in shorter answers, yay.  Also run
	  the evalnode hook so that we can interrupt a symbolic derivation
	  which is taking too long.
parent f8ee5a1b
Fri Jun 24 17:21:22 2005 George Lebl <jirka@5z.com>
* src/symbolic.c, src/eval.c, src/geniustests.txt: Some more
simplification special casing, doing several tan derivatives is
now much faster and results in shorter answers, yay. Also run
the evalnode hook so that we can interrupt a symbolic derivation
which is taking too long.
Fri Jun 24 16:23:01 2005 George Lebl <jirka@5z.com>
* src/longtest.gel: add many derivative tests
......
......@@ -7520,6 +7520,7 @@ gel_is_tree_same (GelETree *l, GelETree *r)
return FALSE;
}
/* FIXME: this is incomplete and stupid! */
static gboolean
oper_reshufle (GelETree *n, int oper)
{
......@@ -7544,28 +7545,69 @@ oper_reshufle (GelETree *n, int oper)
}
/* make into (a*b)*c, "*" is * or + (oper) */
/* unless a is a value and b and c are not */
if (r->type == OPERATOR_NODE &&
r->op.oper == oper) {
GelETree *a, *b, *c;
a = l;
b = r->op.args;
c = r->op.args->any.next;
r->op.args = NULL;
gel_freetree (r);
GET_NEW_NODE (l);
l->type = OPERATOR_NODE;
l->op.oper = oper;
l->op.nargs = 2;
l->op.args = a;
a->any.next = b;
b->any.next = NULL;
if ( ! (a->type == VALUE_NODE &&
b->type != VALUE_NODE &&
c->type != VALUE_NODE)) {
r->op.args = NULL;
gel_freetree (r);
n->op.args = l;
l->any.next = c;
c->any.next = NULL;
GET_NEW_NODE (l);
l->type = OPERATOR_NODE;
l->op.oper = oper;
l->op.nargs = 2;
l->op.args = a;
a->any.next = b;
b->any.next = NULL;
shuffled = TRUE;
n->op.args = l;
l->any.next = c;
c->any.next = NULL;
shuffled = TRUE;
GET_LR (n, l, r);
}
}
/* if (a*b)*c and a is a value and b and c are not
make into a*(b*c) */
if (l->type == OPERATOR_NODE &&
l->op.oper == oper) {
GelETree *a, *b, *c;
a = l->op.args;
b = l->op.args->any.next;
c = r;
if (a->type == VALUE_NODE &&
b->type != VALUE_NODE &&
c->type != VALUE_NODE) {
l->op.args = NULL;
gel_freetree (l);
GET_NEW_NODE (r);
r->type = OPERATOR_NODE;
r->op.oper = oper;
r->op.nargs = 2;
r->op.args = b;
b->any.next = c;
c->any.next = NULL;
n->op.args = a;
a->any.next = r;
r->any.next = NULL;
shuffled = TRUE;
/* GET_LR (n, l, r); */
}
}
}
return shuffled;
......@@ -7628,7 +7670,6 @@ resimplify:
/* Now try to put together multiplications and exponents */
/* FIXME: this is too specific be more general!, though maybe if we sort out all
multiplication and addition as above, things will work nicely */
/* FIXME: have problems with things like (3*(x^2))*(x^a) */
if (n->op.oper == E_MUL) {
GelETree *l, *r;
GelETree *ll, *rr;
......@@ -7650,6 +7691,17 @@ resimplify:
if (gel_is_tree_same (ll, rr)) {
GelETree *nn, *e;
n->op.args = NULL;
gel_freetree (rr);
if (re != NULL) {
r->op.args = NULL;
gel_freetree (r);
}
if (l != ll) {
l->op.args = NULL;
gel_freetree (l);
}
GET_NEW_NODE (e);
e->type = OPERATOR_NODE;
e->op.oper = E_PLUS;
......@@ -7658,16 +7710,11 @@ resimplify:
e->op.args = gel_makenum_ui (1);
} else {
e->op.args = le;
l->op.args = NULL;
}
if (re == NULL) {
e->op.args->any.next = gel_makenum_ui (1);
} else {
e->op.args->any.next = re;
r->op.args = NULL;
/* must whack rr as we NULLed the r
args here */
gel_freetree (rr);
}
e->op.args->any.next->any.next = NULL;
......@@ -7680,11 +7727,6 @@ resimplify:
ll->any.next = e;
e->any.next = NULL;
/* whack ll from the list if it was on there
as n will get whacked in the next step */
if (n->op.args == ll)
n->op.args = n->op.args->any.next;
replacenode (n, nn);
goto resimplify;
......@@ -7714,6 +7756,17 @@ resimplify:
if (gel_is_tree_same (ll, rr)) {
GelETree *nn, *e;
n->op.args = NULL;
gel_freetree (rr);
if (re != NULL) {
r->op.args = NULL;
gel_freetree (r);
}
if (l != ll) {
l->op.args = NULL;
gel_freetree (l);
}
GET_NEW_NODE (e);
e->type = OPERATOR_NODE;
e->op.oper = E_PLUS;
......@@ -7722,16 +7775,11 @@ resimplify:
e->op.args = gel_makenum_ui (1);
} else {
e->op.args = le;
l->op.args = NULL;
}
if (re == NULL) {
e->op.args->any.next = gel_makenum_ui (1);
} else {
e->op.args->any.next = re;
r->op.args = NULL;
/* must whack rr as we NULLed the r
args here */
gel_freetree (rr);
}
e->op.args->any.next->any.next = NULL;
......@@ -7744,11 +7792,6 @@ resimplify:
e->any.next = ll;
ll->any.next = NULL;
/* whack ll from the list if it was on there
as n will get whacked in the next step */
if (n->op.args->any.next == ll)
n->op.args->any.next = NULL;
replacenode (n, nn);
goto resimplify;
......
......@@ -676,8 +676,9 @@ RungeKutta (`(x,y) = 2*x+3,0,0,8,10) 88
EulersMethod (`(x,y) = 2*x+3,0,0,8,100) 88.88
SymbolicDerivative(sin) (`(x)=cos(x))
SymbolicDerivative(cos) (`(x)=(-sin(x)))
SymbolicDerivative(`(x)=10*x^3+x^2+88*x+100) (`(x)=((88+(30*(x^2)))+(2*x)))
SymbolicDerivative(`(x)=10*x^3+x^2+88*x+100) (`(x)=(88+((30*(x^2))+(2*x))))
SymbolicDerivative(`(x)=10*x^2 + 20*x^2*9) (`(x)=(380*x))
SymbolicDerivative(`(x)=x^2*x^3) (`(x)=(5*(x^4)))
function foo(f) = SymbolicDerivative(f) ; foo (sin) (`(x)=cos(x))
function foo(f) = SymbolicDerivative(f) ; foo (`(x)=x^2) (`(x)=(2*x))
SymbolicDerivative(f:=sin) (`(x)=cos(x))
......
......@@ -583,6 +583,16 @@ differentiate_oper (GelETree *expr, GelToken *xtok)
static GelETree *
differentiate_expr (GelETree *expr, GelToken *xtok)
{
if (evalnode_hook != NULL) {
static int i = 0;
if G_UNLIKELY ((i++ & RUN_HOOK_EVERY_MASK) == RUN_HOOK_EVERY_MASK) {
(*evalnode_hook)();
i = 0;
if G_UNLIKELY (interrupted)
return NULL;
}
}
if (expr == NULL) {
return NULL;
} else if (expr->type == VALUE_NODE) {
......@@ -665,7 +675,8 @@ gel_differentiate_func (GelEFunc *f)
}
if (rf == NULL &&
gel_derivative_silent <= 0) {
gel_derivative_silent <= 0 &&
! interrupted) {
gel_errorout (_("%s: Cannot differentiate the '%s' function"),
"SymbolicDerivative",
f->id ? f->id->token : "anonymous");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment