[genius] Thu Jul 23 18:35:28 2009 Jiri (George) Lebl <jirka 5z com>
- From: George Lebl <jirka src gnome org>
- To: svn-commits-list gnome org
- Subject: [genius] Thu Jul 23 18:35:28 2009 Jiri (George) Lebl <jirka 5z com>
- Date: Thu, 23 Jul 2009 23:37:23 +0000 (UTC)
commit 094e9ebf94ad32dbf63c773386d45758c5182aa9
Author: Jiri (George) Lebl <jirka 5z com>
Date: Thu Jul 23 18:36:57 2009 -0500
Thu Jul 23 18:35:28 2009 Jiri (George) Lebl <jirka 5z com>
* src/parse.y, src/eval.c, src/dict.c, src/structs.h: Add an optional
list of extra_dict parameters to function definition. In this
case the subst dance never happens and those variables are added to
extra dict at function definition time.
* lib/*/*.gel: Use local where appropriate and the [] extra dict
definition where appropriate
* src/testscope.gel, src/geniustests.txt: update test suite
* src/geniustest.pl: fix colors
ChangeLog | 14 +++++++
NEWS | 4 ++
lib/calculus/differentiation.gel | 9 ++++
lib/calculus/fourier.gel | 52 +++++++++++++-------------
lib/calculus/integration.gel | 4 +-
lib/calculus/limits.gel | 9 +++-
lib/calculus/sums_products.gel | 4 ++
lib/equation_solving/diffeqs.gel | 2 +
lib/equation_solving/find_root.gel | 4 ++
lib/library-strings.c | 16 ++++----
lib/linear_algebra/misc.gel | 3 +
lib/misc/misc.gel | 3 +-
lib/symbolic/differentiation.gel | 3 +
src/eval.c | 60 ++++++++++++++++++++++++++---
src/geniustest.pl | 4 +-
src/geniustests.txt | 3 +
src/parse.y | 63 +++++++++++++++++++++++++++++--
src/parseutil.c | 73 ++++++++++++++++++++++++++----------
src/parseutil.h | 5 ++-
src/structs.h | 4 ++
src/testscope.gel | 17 ++++++++
21 files changed, 285 insertions(+), 71 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 5fc2172..94093c8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+Thu Jul 23 18:35:28 2009 Jiri (George) Lebl <jirka 5z com>
+
+ * src/parse.y, src/eval.c, src/dict.c, src/structs.h: Add an optional
+ list of extra_dict parameters to function definition. In this
+ case the subst dance never happens and those variables are added to
+ extra dict at function definition time.
+
+ * lib/*/*.gel: Use local where appropriate and the [] extra dict
+ definition where appropriate
+
+ * src/testscope.gel, src/geniustests.txt: update test suite
+
+ * src/geniustest.pl: fix colors
+
Thu Jul 23 16:28:59 2009 Jiri (George) Lebl <jirka 5z com>
* src/dict.c, src/eval.c: remove some forgotten debug prints
diff --git a/NEWS b/NEWS
index d2581e1..1c3f825 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,7 @@
+Changes to 1.0.7
+
+FIXME
+
Changes to 1.0.6
* Draw grid and x/y axis on lineplots in gray, much better readability
diff --git a/lib/calculus/differentiation.gel b/lib/calculus/differentiation.gel
index 37730f3..10b934f 100644
--- a/lib/calculus/differentiation.gel
+++ b/lib/calculus/differentiation.gel
@@ -30,6 +30,7 @@
function OneSidedThreePointFormula(f,x0,h) =
# This has error term max(f''')h^2/3
(
+ local *;
# check arguments
## check types
if not IsFunctionOrIdentifier(f) then
@@ -49,6 +50,7 @@ SetHelp("OneSidedThreePointFormula","calculus","Compute one-sided derivative usi
function TwoSidedThreePointFormula(f,x0,h) =
# This has error term max(f''')h^2/6
(
+ local *;
# check arguments
## check types
if not IsFunctionOrIdentifier(f) then
@@ -67,6 +69,7 @@ SetHelp("TwoSidedThreePointFormula","calculus","Compute two-sided derivative usi
function OneSidedFivePointFormula(f,x0,h) =
# This has error term max(f''''')h^4/5
(
+ local *;
# check arguments
## check types
if not IsFunctionOrIdentifier(f) then
@@ -85,6 +88,7 @@ SetHelp("OneSidedFivePointFormula","calculus","Compute one-sided derivative usin
function TwoSidedFivePointFormula(f,x0,h) =
# This has error term max(f''''')h^4/30
(
+ local *;
# check arguments
## check types
if(not IsFunctionOrIdentifier(f)) then
@@ -109,6 +113,7 @@ parameter DerivativeNumberOfTries=100;
# Simple test for differentiability
function IsDifferentiable(f,x0) =
(
+ local *;
# differentiable functions have to be continuous and left and right derivatives must
# be equal
IsContinuous (f, x0) and
@@ -121,6 +126,7 @@ SetHelp("IsDifferentiable","calculus","Test for differentiability by approximati
function NumericalDerivative(f,x0) =
# returns f'(x0)
(
+ local *;
# FIXME: perhaps check differentiability first, but then we're doing so many limits already
NumericalLimitAtInfinity (`(n)=(TwoSidedFivePointFormula(f,x0,2.0^(-n))),
Identity,
@@ -134,6 +140,7 @@ NDerivative = NumericalDerivative
function NumericalLeftDerivative(f,x0) =
(
+ local *;
NumericalLimitAtInfinity (`(n)=(OneSidedFivePointFormula(f,x0,-(2.0^(-n)))),
Identity,
DerivativeTolerance,
@@ -144,6 +151,7 @@ SetHelp("NumericalLeftDerivative","calculus","Attempt to calculate numerical lef
function NumericalRightDerivative(f,x0) =
(
+ local *;
NumericalLimitAtInfinity (`(n)=(OneSidedFivePointFormula(f,x0,2.0^(-n))),
Identity,
DerivativeTolerance,
@@ -154,6 +162,7 @@ SetHelp("NumericalRightDerivative","calculus","Attempt to calculate numerical ri
function Derivative(f,x0) =
(
+ local *;
df = SymbolicDerivativeTry (f);
if IsNull(df) then
NumericalDerivative (f, x0)
diff --git a/lib/calculus/fourier.gel b/lib/calculus/fourier.gel
index f65a15f..c15a3aa 100644
--- a/lib/calculus/fourier.gel
+++ b/lib/calculus/fourier.gel
@@ -2,6 +2,7 @@
#
function NumericalFourierSeriesFunction(f,L,N) =
(
+ local *;
# check arguments
if not IsFunctionOrIdentifier(f) then
(error("NumericalFourierSeriesFunction: argument f must be a function");bailout)
@@ -14,7 +15,7 @@ function NumericalFourierSeriesFunction(f,L,N) =
FourierSeriesFunction(c@(1),c@(2),L)
)
-SetHelp("NumericalFourierSeriesFunction","calculus","FIXME");
+SetHelp("NumericalFourierSeriesFunction","calculus","Return a function which is the fourier series of f with half-period L with coefficients up to N computed numerically");
function FourierSeriesFunction(a,b,L) =
(
@@ -24,7 +25,7 @@ function FourierSeriesFunction(a,b,L) =
else if not (IsReal(L) and L > 0) then
(error("FourierSeriesFunction: argument L must be a positive real value");bailout);
- `(x) = (
+ `(x)[a,b,L] = (
if not IsNull(a) then (
val = a@(1)/2 + sum n = 2 to elements(a) do
a@(n) * cos(x*(n-1)*pi/L)
@@ -40,10 +41,11 @@ function FourierSeriesFunction(a,b,L) =
val
)
)
-SetHelp("FourierSeries","calculus","FIXME");
+SetHelp("FourierSeriesFunction","calculus","Return a function which is a Fourier series with the coefficients given by the vectors a (sines) and b (cosines). Note that a@(1) is the constant coefficient!");
function NumericalFourierSeriesCoefficients(f,L,N) =
(
+ local *;
# check arguments
if not IsFunctionOrIdentifier(f) then
(error("NumericalFourierSeriesCoefficients: argument f must be a function");bailout)
@@ -56,18 +58,17 @@ function NumericalFourierSeriesCoefficients(f,L,N) =
b = .;
a@(1) = (1/L)*NumericalIntegral(f,-L,L);
- __fs_L = L;
- __fs_f = f;
- for __fs_n = 1 to N do (
- a@(__fs_n+1) = (1/L)*NumericalIntegral(`(x)=((__fs_f call (x))*cos(x*__fs_n*pi/__fs_L)),-L,L);
- b@(__fs_n) = (1/L)*NumericalIntegral(`(x)=((__fs_f call (x))*sin(x*__fs_n*pi/__fs_L)),-L,L)
+ for n = 1 to N do (
+ a@(n+1) = (1/L)*NumericalIntegral(`(x)[f,L,n]=(local *;(f call (x))*cos(x*n*pi/L)),-L,L);
+ b@(n) = (1/L)*NumericalIntegral(`(x)[f,L,n]=(local *;(f call (x))*sin(x*n*pi/L)),-L,L)
);
`[a,b]
)
-SetHelp("NumericalFourierSeriesCoefficients","calculus","FIXME");
+SetHelp("NumericalFourierSeriesCoefficients","calculus","Numerically compute the coefficients for a Fourier series with half-period L up to the Nth coefficient.");
function NumericalFourierSineSeriesCoefficients(f,L,N) =
(
+ local *;
# check arguments
if not IsFunctionOrIdentifier(f) then
(error("NumericalFourierSineSeriesCoefficients: argument f must be a function");bailout)
@@ -78,17 +79,16 @@ function NumericalFourierSineSeriesCoefficients(f,L,N) =
b = .;
- __fs_L = L;
- __fs_f = f;
- for __fs_n = 1 to N do (
- b@(__fs_n) = (2/L)*NumericalIntegral(`(x)=((__fs_f call (x))*sin(x*__fs_n*pi/__fs_L)),0,L)
+ for n = 1 to N do (
+ b@(n) = (2/L)*NumericalIntegral(`(x)[f,L,n]=(local *;(f call (x))*sin(x*n*pi/L)),0,L)
);
b
)
-SetHelp("NumericalFourierSineSeriesCoefficients","calculus","FIXME");
+SetHelp("NumericalFourierSineSeriesCoefficients","calculus","Numerically compute the coefficients for a sine Fourier series for a function on [0,L] up to the Nth coefficient.");
function NumericalFourierCosineSeriesCoefficients(f,L,N) =
(
+ local *;
# check arguments
if not IsFunctionOrIdentifier(f) then
(error("NumericalFourierCosineSeriesCoefficients: argument f must be a function");bailout)
@@ -99,16 +99,13 @@ function NumericalFourierCosineSeriesCoefficients(f,L,N) =
a = .;
- __fs_L = L;
- __fs_f = f;
-
a@(1) = (1/L)*NumericalIntegral(f,-L,L);
- for __fs_n = 1 to N do (
- a@(__fs_n+1) = (1/L)*NumericalIntegral(`(x)=((__fs_f call (x))*cos(x*__fs_n*pi/__fs_L)),-L,L)
+ for n = 1 to N do (
+ a@(n+1) = (1/L)*NumericalIntegral(`(x)[f,L,n]=(local *;(f call (x))*cos(x*n*pi/L)),-L,L)
);
a
)
-SetHelp("NumericalFourierCosineSeriesCoefficients","calculus","FIXME");
+SetHelp("NumericalFourierCosineSeriesCoefficients","calculus","Numerically compute the coefficients for a cosine Fourier series for a function on [0,L] up to the Nth coefficient.");
function PeriodicExtension(f,a,b) =
(
@@ -118,14 +115,15 @@ function PeriodicExtension(f,a,b) =
else if not (IsReal(a) and IsReal(b) and b > a) then
(error("PeriodicExtension: arguments a, b must be a real, b > a");bailout);
- `(x) = (
+ `(x)[f,a,b] = (
+ local *;
#This is pretty stupid, but simplest way to do this
while x > b do x = x-(b-a);
while x < a do x = x+(b-a);
(f call (x))
)
)
-SetHelp("PeriodicExtension","calculus","FIXME");
+SetHelp("PeriodicExtension","calculus","Return a function which is the periodic extension of f defined on the interval [a,b]");
function EvenPeriodicExtension(f,L) =
(
@@ -135,7 +133,8 @@ function EvenPeriodicExtension(f,L) =
else if not (IsReal(L) and L > 0) then
(error("EvenPeriodicExtension: argument L must be a positive real value");bailout);
- `(x) = (
+ `(x)[f,L] = (
+ local *;
#This is pretty stupid, but simplest way to do this
while x > L do x = x-2*L;
while x < -L do x = x+2*L;
@@ -143,7 +142,7 @@ function EvenPeriodicExtension(f,L) =
if x >= 0 then (f call (x)) else (f call (-x))
)
)
-SetHelp("EvenPeriodicExtension","calculus","FIXME");
+SetHelp("EvenPeriodicExtension","calculus","Return a function which is the even periodic extension of f defined on the interval [0,L]");
function OddPeriodicExtension(f,L) =
(
@@ -153,7 +152,8 @@ function OddPeriodicExtension(f,L) =
else if not (IsReal(L) and L > 0) then
(error("OddPeriodicExtension: argument L must be a positive real value");bailout);
- `(x) = (
+ `(x)[f,L] = (
+ local *;
#This is pretty stupid, but simplest way to do this
while x > L do x = x-2*L;
while x < -L do x = x+2*L;
@@ -161,4 +161,4 @@ function OddPeriodicExtension(f,L) =
if x >= 0 then (f call (x)) else -(f call (-x))
)
)
-SetHelp("OddPeriodicExtension","calculus","FIXME");
+SetHelp("OddPeriodicExtension","calculus","Return a function which is the odd periodic extension of f defined on the interval [0,L]");
diff --git a/lib/calculus/integration.gel b/lib/calculus/integration.gel
index abcc489..39cf3e6 100644
--- a/lib/calculus/integration.gel
+++ b/lib/calculus/integration.gel
@@ -26,6 +26,7 @@
SetHelp ("CompositeSimpsonsRuleTolerance", "calculus", "Integration of f by Composite Simpson's Rule on the interval [a,b] with the number of steps calculated by the fourth derivative bound and the desired tolerance")
function CompositeSimpsonsRuleTolerance(f,a,b,FourthDerivativeBound,Tolerance) =
(
+ local *;
# Error term = max(f'''')*h^4*(b-a)/180,
# where h=(b-a)/n
n = ceil(|FourthDerivativeBound*(b-a)^5 / (180*Tolerance)|^(1/4));
@@ -41,6 +42,7 @@ function CompositeSimpsonsRuleTolerance(f,a,b,FourthDerivativeBound,Tolerance) =
SetHelp ("MidpointRule", "calculus", "Integration by midpoint rule")
function MidpointRule(f,a,b,n) =
(
+ local *;
if(not IsFunction(f)) then
(error("MidpointRule: argument 1 must be a function");bailout)
else if(not IsReal(a) or not IsReal(b)) then
@@ -63,4 +65,4 @@ SetHelp ("NumericalIntegralFunction", "parameters", "The function used for numer
parameter NumericalIntegralFunction = `CompositeSimpsonsRule
SetHelp ("NumericalIntegral", "calculus", "Integration by rule set in NumericalIntegralFunction of f from a to b using NumericalIntegralSteps steps")
-function NumericalIntegral(f,a,b) = (NumericalIntegralFunction call (f,a,b,NumericalIntegralSteps))
+function NumericalIntegral(f,a,b) = (local *;NumericalIntegralFunction call (f,a,b,NumericalIntegralSteps))
diff --git a/lib/calculus/limits.gel b/lib/calculus/limits.gel
index 899d024..9f717bc 100644
--- a/lib/calculus/limits.gel
+++ b/lib/calculus/limits.gel
@@ -29,6 +29,7 @@ function NumericalLimitAtInfinity(_f,step_fun,tolerance,successive_for_success,N
#FIXME: should have a way of dealing with +infinity, -infinity, and
# bounded oscillation (like sin(x))
(
+ local *;
current_limit = _f(step_fun(1));
number_of_consecutive_differences_within_tolerance = 0;
for i = 2 to N do (
@@ -62,8 +63,9 @@ parameter ContinuousNumberOfTries=100;
SetHelp ("LeftLimit", "calculus", "Calculate the left limit of a real-valued function at x0")
function LeftLimit(f,x0) =
(
+ local *;
NumericalLimitAtInfinity (f,
- `(n)=(x0-2.0^(-n)),
+ `(n)[x0]=(x0-2.0^(-n)),
ContinuousTolerance,
ContinuousSFS,
ContinuousNumberOfTries)
@@ -72,8 +74,9 @@ function LeftLimit(f,x0) =
SetHelp ("RightLimit", "calculus", "Calculate the right limit of a real-valued function at x0")
function RightLimit(f,x0) =
(
+ local *;
NumericalLimitAtInfinity (f,
- `(n)=(x0+2.0^(-n)),
+ `(n)[x0]=(x0+2.0^(-n)),
ContinuousTolerance,
ContinuousSFS,
ContinuousNumberOfTries)
@@ -82,6 +85,7 @@ function RightLimit(f,x0) =
SetHelp ("Limit", "calculus", "Calculate the limit of a real-valued function at x0. Tries to calculate both left and right limits.")
function Limit(f,x0) =
(
+ local *;
LeftLim = LeftLimit(f,x0);
RightLim = RightLimit(f,x0);
if ( not IsNull(LeftLim) and
@@ -93,6 +97,7 @@ function Limit(f,x0) =
SetHelp ("IsContinuous", "calculus", "Try and see if a real-valued function is continuous at x0 by calculating the limit there")
function IsContinuous(f,x0) =
(
+ local *;
l = Limit(f,x0);
not IsNull(l) and |l-f(x0)| < ContinuousTolerance
)
diff --git a/lib/calculus/sums_products.gel b/lib/calculus/sums_products.gel
index 0fc1844..6fec783 100644
--- a/lib/calculus/sums_products.gel
+++ b/lib/calculus/sums_products.gel
@@ -11,6 +11,7 @@ parameter SumProductNumberOfTries=10000;
#calculate an infinite sum until the new terms stop making a difference
SetHelp("InfiniteSum","calculus","Try to calculate an infinite sum for a single parameter function");
function InfiniteSum (func, start, inc) = (
+ local *;
if not IsValue(start) or not IsValue(inc) then
(error("InfiniteSum: start,inc arguments not values");bailout)
else if not IsFunction(func) then
@@ -36,6 +37,7 @@ function InfiniteSum (func, start, inc) = (
#calculate an infinite sum until the new terms stop making a difference
SetHelp("InfiniteSum2","calculus","Try to calculate an infinite sum for a double parameter function with func(arg,n)");
function InfiniteSum2(func,arg,start,inc) = (
+ local *;
if not IsValue(start) or not IsValue(inc) then
(error("InfiniteSum2: start,inc arguments not values");bailout)
else if not IsFunction(func) then
@@ -61,6 +63,7 @@ function InfiniteSum2(func,arg,start,inc) = (
#calculate an infinite product until the new terms stop making a difference
SetHelp("InfiniteProduct","calculus","Try to calculate an infinite product for a single parameter function");
function InfiniteProduct (func, start, inc) = (
+ local *;
if not IsValue(start) or not IsValue(inc) then
(error("InfiniteProduct: start,inc arguments not values");bailout)
else if not IsFunction(func) then
@@ -86,6 +89,7 @@ function InfiniteProduct (func, start, inc) = (
#calculate an infinite product until the new terms stop making a difference
SetHelp("InfiniteProduct2","calculus","Try to calculate an infinite product for a double parameter function with func(arg,n)");
function InfiniteProduct2(func,arg,start,inc) = (
+ local *;
if not IsValue(start) or not IsValue(inc) then
(error("InfiniteProduct2: start,inc arguments not values");bailout)
else if not IsFunction(func) then
diff --git a/lib/equation_solving/diffeqs.gel b/lib/equation_solving/diffeqs.gel
index 2e65089..40bbabb 100644
--- a/lib/equation_solving/diffeqs.gel
+++ b/lib/equation_solving/diffeqs.gel
@@ -5,6 +5,7 @@
SetHelp ("EulersMethod", "equation_solving",
"Use classical Euler's method to numerically solve y'=f(x,y) for initial x0,y0 going to x1 with n increments, returns y at x1")
function EulersMethod(f,x0,y0,x1,n) = (
+ local *;
# Note we can't check the 2 arguments, FIXME
if not IsFunction(f) then
(error("EulersMethod: f must be a function of two arguments");bailout)
@@ -27,6 +28,7 @@ function EulersMethod(f,x0,y0,x1,n) = (
SetHelp ("RungeKutta", "equation_solving",
"Use classical non-adaptive Runge-Kutta of fourth order method to numerically solve y'=f(x,y) for initial x0,y0 going to x1 with n increments, returns y at x1")
function RungeKutta(f,x0,y0,x1,n) = (
+ local *;
# Note we can't check the 2 arguments, FIXME
if not IsFunction(f) then
(error("RungeKutta: f must be a function of two arguments");bailout)
diff --git a/lib/equation_solving/find_root.gel b/lib/equation_solving/find_root.gel
index 8e59bf9..b78dfcb 100644
--- a/lib/equation_solving/find_root.gel
+++ b/lib/equation_solving/find_root.gel
@@ -24,6 +24,7 @@ SetHelp ("FindRootBisection", "equation_solving",
"Find root of a function using the bisection method")
function FindRootBisection(f,a,b,TOL,N) =
(
+ local *;
# check arguments
## check types
if(not IsFunction(f)) then
@@ -59,6 +60,7 @@ SetHelp ("FindRootSecant", "equation_solving",
"Find root of a function using the secant method")
function FindRootSecant(f,a,b,TOL,N) =
(
+ local *;
# check arguments
## check types
if(not IsFunction(f)) then
@@ -94,6 +96,7 @@ SetHelp ("FindRootFalsePosition", "equation_solving",
"Find root of a function using the method of false position")
function FindRootFalsePosition(f,a,b,TOL,N) =
(
+ local *;
# check arguments
## check types
if(not IsFunction(f)) then
@@ -131,6 +134,7 @@ SetHelp ("FindRootMullersMethod", "equation_solving",
"Find root of a function using the Muller's method")
function FindRootMullersMethod(f,x1,x2,x3,TOL,N) =
(
+ local *;
# check arguments
## check types
if(not IsFunction(f)) then
diff --git a/lib/library-strings.c b/lib/library-strings.c
index 533eda0..f28b39b 100644
--- a/lib/library-strings.c
+++ b/lib/library-strings.c
@@ -180,8 +180,8 @@ char *fake = N_("Calculate the nth triangular number");
char *fake = N_("Calculate permutations");
char *fake = N_("Integration of f by Composite Simpson's Rule on the interval [a,b] with the number of steps calculated by the fourth derivative bound and the desired tolerance");
char *fake = N_("Attempt to calculate derivative by trying first symbolically and then numerically");
-char *fake = N_("FIXME");
-char *fake = N_("FIXME");
+char *fake = N_("Return a function which is the even periodic extension of f defined on the interval [0,L]");
+char *fake = N_("Return a function which is a Fourier series with the coefficients given by the vectors a (sines) and b (cosines). Note that a@(1) is the constant coefficient!");
char *fake = N_("Try to calculate an infinite product for a single parameter function");
char *fake = N_("Try to calculate an infinite product for a double parameter function with func(arg,n)");
char *fake = N_("Try to calculate an infinite sum for a single parameter function");
@@ -192,18 +192,18 @@ char *fake = N_("Calculate the left limit of a real-valued function at x0");
char *fake = N_("Calculate the limit of a real-valued function at x0. Tries to calculate both left and right limits.");
char *fake = N_("Integration by midpoint rule");
char *fake = N_("Attempt to calculate numerical derivative");
-char *fake = N_("FIXME");
-char *fake = N_("FIXME");
-char *fake = N_("FIXME");
-char *fake = N_("FIXME");
+char *fake = N_("Numerically compute the coefficients for a cosine Fourier series for a function on [0,L] up to the Nth coefficient.");
+char *fake = N_("Numerically compute the coefficients for a Fourier series with half-period L up to the Nth coefficient.");
+char *fake = N_("Return a function which is the fourier series of f with half-period L with coefficients up to N computed numerically");
+char *fake = N_("Numerically compute the coefficients for a sine Fourier series for a function on [0,L] up to the Nth coefficient.");
char *fake = N_("Integration by rule set in NumericalIntegralFunction of f from a to b using NumericalIntegralSteps steps");
char *fake = N_("Attempt to calculate numerical left derivative");
char *fake = N_("Attempt to calculate the limit of f(step_fun(i)) as i goes from 1 to N");
char *fake = N_("Attempt to calculate numerical right derivative");
-char *fake = N_("FIXME");
+char *fake = N_("Return a function which is the odd periodic extension of f defined on the interval [0,L]");
char *fake = N_("Compute one-sided derivative using five point formula");
char *fake = N_("Compute one-sided derivative using three-point formula");
-char *fake = N_("FIXME");
+char *fake = N_("Return a function which is the periodic extension of f defined on the interval [a,b]");
char *fake = N_("Calculate the right limit of a real-valued function at x0");
char *fake = N_("Compute two-sided derivative using five-point formula");
char *fake = N_("Compute two-sided derivative using three-point formula");
diff --git a/lib/linear_algebra/misc.gel b/lib/linear_algebra/misc.gel
index 8386143..7697cfc 100644
--- a/lib/linear_algebra/misc.gel
+++ b/lib/linear_algebra/misc.gel
@@ -1,5 +1,6 @@
SetHelp("ApplyOverMatrix", "matrix", "Apply a function over all entries of a matrix and return a matrix of the results")
function ApplyOverMatrix(a,func) = (
+ local *;
if(not IsMatrix(a)) then
(error("ApplyOverMatrix: argument 1 must be a matrix");bailout)
else if(not IsFunction(func)) then
@@ -15,6 +16,7 @@ function ApplyOverMatrix(a,func) = (
SetHelp("ApplyOverMatrix2", "matrix", "Apply a function over all entries of 2 matrices (or 1 value and 1 matrix) and return a matrix of the results")
function ApplyOverMatrix2(a,b,func) = (
+ local *;
if(not IsMatrix(a) and not IsMatrix(b)) then
(error("ApplyOverMatrix2: argument 1 or 2 must be a matrix");bailout)
else if(not IsFunction(func)) then
@@ -151,6 +153,7 @@ Adjugate = adj
SetHelp("MinimizeFunction","functions","Find the first value where f(x)=0");
function MinimizeFunction(func,x,incr) = (
+ local *;
if(not IsValue(x) or not IsValue(incr)) then
(error("MinimizeFunction: x,incr arguments not values");bailout)
else if(not IsFunction(func)) then
diff --git a/lib/misc/misc.gel b/lib/misc/misc.gel
index 4064d36..194ca5a 100644
--- a/lib/misc/misc.gel
+++ b/lib/misc/misc.gel
@@ -5,10 +5,11 @@ SetHelp("string","basic","Make a string");
function string(s) = s + ""
SetHelp("Compose","basic","Compose two functions")
-function Compose(f,g) = `(x)=f(g(x))
+function Compose(f,g) = (`(x)[f,g]=(local *;f(g(x))))
SetHelp("ComposePower","basic","Compose a function with itself n times, passing x as argument, and returning x if n == 0")
function ComposePower(f,n,x) = (
+ local *;
for k=1 to n do
x = f call (x);
x
diff --git a/lib/symbolic/differentiation.gel b/lib/symbolic/differentiation.gel
index 9c5f0df..d928e7c 100644
--- a/lib/symbolic/differentiation.gel
+++ b/lib/symbolic/differentiation.gel
@@ -1,5 +1,6 @@
function SymbolicNthDerivative(f,n) =
(
+ local *;
if not IsFunction(f) then
(error("SymbolicNthDerivative: argument 1 must be a function");bailout)
else if not IsNonNegativeInteger(n) then
@@ -18,6 +19,7 @@ SetHelp("SymbolicNthDerivative","symbolic","Attempt to symbolically differentiat
function SymbolicNthDerivativeTry(f,n) =
(
+ local *;
if not IsFunction(f) then
(error("SymbolicNthDerivativeTry: argument 1 must be a function");bailout)
else if not IsNonNegativeInteger(n) then
@@ -36,6 +38,7 @@ SetHelp("SymbolicNthDerivativeTry","symbolic","Attempt to symbolically different
function SymbolicTaylorApproximationFunction(f,x0,n) =
(
+ local f,df,c,n,k;
if not IsFunction(f) then
(error("SymbolicTaylorApproximationFunction: argument 1 must be a function");bailout)
else if not IsValue(x0) then
diff --git a/src/eval.c b/src/eval.c
index fd5c92d..aca3f90 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -2646,6 +2646,8 @@ function_finish_bin_op (GelCtx *ctx, GelETree *n, int nargs, GelETree *la, GelET
n->func.func = f;
n->func.func->context = -1;
+ /* FIXME: never on subst list maybe? but only when not adding random expression! */
+
return TRUE;
}
@@ -2761,6 +2763,8 @@ function_uni_op (GelCtx *ctx, GelETree *n, GelETree *l)
n->func.func = f;
n->func.func->context = -1;
+ n->func.func->never_on_subst_list = 1;
+
return TRUE;
}
@@ -2819,6 +2823,8 @@ gel_function_from_function (GelEFunc *func, GelETree *l)
n->func.func = f;
n->func.func->context = -1;
+ n->func.func->never_on_subst_list = 1;
+
return n;
}
@@ -3311,7 +3317,8 @@ iter_do_var(GelCtx *ctx, GelETree *n, GelEFunc *f)
f->extra_dict);
n->func.func->context = -1;
n->func.func->vararg = f->vararg;
- if (f->on_subst_list &&
+ if ( ! f->never_on_subst_list &&
+ f->on_subst_list &&
d_curcontext () != 0)
d_put_on_subst_list (n->func.func);
} else if(f->type == GEL_BUILTIN_FUNC) {
@@ -6662,7 +6669,9 @@ gel_get_ids_for_extradict (GSList *toklist, GSList *args, GSList *locals, GelETr
if (g_slist_find (args, n->id.id) == NULL &&
g_slist_find (locals, n->id.id) == NULL &&
g_slist_find (toklist, n->id.id) == NULL) {
- toklist = g_slist_prepend (toklist, n->id.id);
+ GelEFunc *f = d_lookup_global (n->id.id);
+ if (f != NULL && f->context > 0)
+ toklist = g_slist_prepend (toklist, n->id.id);
}
} else if (n->type == GEL_SPACER_NODE) {
toklist = gel_get_ids_for_extradict (toklist, args, locals, n->sp.arg);
@@ -6740,6 +6749,37 @@ gel_subst_local_vars (GSList *funclist, GSList **toklist)
return funclist;
}
+static GSList *
+build_extradict (GSList *funclist, GSList *toklist)
+{
+ GSList *li;
+
+ for (li = toklist; li != NULL; li = li->next) {
+ GelToken *id = li->data;
+ GelEFunc *func = d_lookup_global (id);
+ if G_LIKELY (func != NULL) {
+ GelEFunc *f = d_copyfunc (func);
+ if ( ! f->on_subst_list)
+ f->context = -1;
+ funclist = g_slist_prepend (funclist, f);
+ } else {
+ char *similar = gel_similar_possible_ids (id->token);
+ if (similar != NULL) {
+ gel_errorout (_("Variable '%s' used uninitialized, "
+ "perhaps you meant %s."),
+ id->token,
+ similar);
+
+ g_free (similar);
+ } else {
+ gel_errorout (_("Variable '%s' used uninitialized"),
+ id->token);
+ }
+ }
+ }
+ return funclist;
+}
+
static gboolean
iter_eval_etree(GelCtx *ctx)
{
@@ -6860,10 +6900,18 @@ iter_eval_etree(GelCtx *ctx)
case GEL_FUNCTION_NODE:
EDEBUG(" FUNCTION NODE");
- if (n->func.func != NULL &&
- (n->func.func->type == GEL_USER_FUNC ||
- n->func.func->type == GEL_VARIABLE_FUNC) &&
- d_curcontext () != 0) {
+ if (n->func.func->never_on_subst_list) {
+ if (n->func.func->built_subst_dict) {
+ n->func.func->extra_dict = build_extradict (n->func.func->extra_dict,
+ n->func.func->subst_dict);
+ n->func.func->built_subst_dict = 0;
+ g_slist_free (n->func.func->subst_dict);
+ n->func.func->subst_dict = NULL;
+ }
+ } else if (n->func.func != NULL &&
+ (n->func.func->type == GEL_USER_FUNC ||
+ n->func.func->type == GEL_VARIABLE_FUNC) &&
+ d_curcontext () != 0) {
d_put_on_subst_list (n->func.func);
}
WHACK_SAVEDN_POP;
diff --git a/src/geniustest.pl b/src/geniustest.pl
index 1e8b88e..a52f468 100755
--- a/src/geniustest.pl
+++ b/src/geniustest.pl
@@ -38,7 +38,7 @@ while(<TESTS>) {
print " (should be)=$shd\n";
print " (reported)=$rep\n";
if($rep ne $shd) {
- print "\e[01:31mERROR!\e[0m\n";
+ print "\e[01;31mERROR!\e[0m\n";
$errors++;
$errorinputs = $errorinputs . "\n$command";
}
@@ -47,7 +47,7 @@ while(<TESTS>) {
print " (should be)=$shd\n";
print " (reported)=\n";
if($shd ne "") {
- print "\e[01:31mERROR! NO OUTPUT\e[0m\n";
+ print "\e[01;31mERROR! NO OUTPUT\e[0m\n";
$errors++;
$errorinputs = $errorinputs . "\n$command";
}
diff --git a/src/geniustests.txt b/src/geniustests.txt
index bebcb3c..3b420c6 100644
--- a/src/geniustests.txt
+++ b/src/geniustests.txt
@@ -466,6 +466,8 @@ ones(2,2).-1 [0,0;0,0]
sum n in ColumnsOf([1,2;3,4]) do n [3;7]
sum n in RowsOf([1,2;3,4]) do n [4,6]
function f(x) = `(l) = x+l; k=f(2);k(11) 13
+function f(x) = `(l)[x] = x+l; k=f(2);k(11) 13
+function f(x) = `(l)[] = x+l; k=f(2);k(11) (x+11)
function f(a,b,c...) = c ; f() f()
function f(a,b,c...) = c ; f(1) f(1)
function f(a,b,c...) = c ; f(1,2)+1 ((null)+1)
@@ -941,6 +943,7 @@ a=7;(function f(x)=(b=9));f(8);UserVariables() [f,a]
a=7;(function f(x)=(b=9));f(8);UndefineAll();UserVariables()+0 ((null)+0)
parameter FloatPrecision = 888 (parameter FloatPrecision = 888)
parameter foo = 888 888
+y=9;(function g(x)[y]=(y+1));y=0;g(0) 10
load "nullspacetest.gel" true
load "longtest.gel" true
load "testprec.gel" true
diff --git a/src/parse.y b/src/parse.y
index dfe26a9..5f54e8d 100644
--- a/src/parse.y
+++ b/src/parse.y
@@ -286,20 +286,75 @@ anyequals: EQUALS
;
funcdef: '(' identlist ')' anyequals expr %prec FUNCTION {
- if ( ! gp_push_func (FALSE /* vararg */)) {
+ if ( ! gp_push_func (FALSE /* vararg */,
+ TRUE /* arguments */,
+ FALSE /* extradict */,
+ FALSE /* never_subst */)) {
SYNTAX_ERROR;
}
}
| '(' identlist THREEDOTS ')' anyequals expr %prec FUNCTION {
- if ( ! gp_push_func (TRUE /* vararg */)) {
+ if ( ! gp_push_func (TRUE /* vararg */,
+ TRUE /* arguments */,
+ FALSE /* extradict */,
+ FALSE /* never_subst */)) {
SYNTAX_ERROR;
}
}
| '(' ')' anyequals expr %prec FUNCTION {
- if ( ! gp_push_marker (GEL_EXPRLIST_START_NODE)) {
+ if ( ! gp_push_func (FALSE /* vararg */,
+ FALSE /* arguments */,
+ FALSE /* extradict */,
+ FALSE /* never_subst */)) {
SYNTAX_ERROR;
}
- if ( ! gp_push_func (FALSE /* vararg */)) {
+ }
+ | '(' identlist ')' '[' identlist ']' anyequals expr %prec FUNCTION {
+ if ( ! gp_push_func (FALSE /* vararg */,
+ TRUE /* arguments */,
+ TRUE /* extradict */,
+ TRUE /* never_subst */)) {
+ SYNTAX_ERROR;
+ }
+ }
+ | '(' identlist THREEDOTS ')' '[' identlist ']' anyequals expr %prec FUNCTION {
+ if ( ! gp_push_func (TRUE /* vararg */,
+ TRUE /* arguments */,
+ TRUE /* extradict */,
+ TRUE /* never_subst */)) {
+ SYNTAX_ERROR;
+ }
+ }
+ | '(' ')' '[' identlist ']' anyequals expr %prec FUNCTION {
+ if ( ! gp_push_func (FALSE /* vararg */,
+ FALSE /* arguments */,
+ TRUE /* extradict */,
+ TRUE /* never_subst */)) {
+ SYNTAX_ERROR;
+ }
+ }
+ ;
+ | '(' identlist ')' '[' ']' anyequals expr %prec FUNCTION {
+ if ( ! gp_push_func (FALSE /* vararg */,
+ TRUE /* arguments */,
+ FALSE /* extradict */,
+ TRUE /* never_subst */)) {
+ SYNTAX_ERROR;
+ }
+ }
+ | '(' identlist THREEDOTS ')' '[' ']' anyequals expr %prec FUNCTION {
+ if ( ! gp_push_func (TRUE /* vararg */,
+ TRUE /* arguments */,
+ FALSE /* extradict */,
+ TRUE /* never_subst */)) {
+ SYNTAX_ERROR;
+ }
+ }
+ | '(' ')' '[' ']' anyequals expr %prec FUNCTION {
+ if ( ! gp_push_func (FALSE /* vararg */,
+ FALSE /* arguments */,
+ FALSE /* extradict */,
+ TRUE /* never_subst */)) {
SYNTAX_ERROR;
}
}
diff --git a/src/parseutil.c b/src/parseutil.c
index 5d2ad7f..b6ddc70 100644
--- a/src/parseutil.c
+++ b/src/parseutil.c
@@ -38,12 +38,13 @@ extern GSList *gel_parsestack;
gboolean
-gp_push_func (gboolean vararg)
+gp_push_func (gboolean vararg, gboolean arguments, gboolean extradict, gboolean never_subst)
{
GelETree * tree;
GelETree * val;
GSList * list = NULL;
- int i = 0;
+ GSList * elist = NULL;
+ int argnum = 0;
gboolean local_all = FALSE;
GSList *local_idents = NULL;
@@ -59,34 +60,66 @@ gp_push_func (gboolean vararg)
return FALSE;
}
- for(;;) {
- tree = gel_stack_pop(&gel_parsestack);
- if(tree && tree->type==GEL_EXPRLIST_START_NODE) {
- gel_freetree(tree);
- break;
+ if (extradict) {
+ for (;;) {
+ tree = gel_stack_pop (&gel_parsestack);
+ if (tree != NULL &&
+ tree->type == GEL_EXPRLIST_START_NODE) {
+ gel_freetree (tree);
+ break;
+ }
+ /*we have gone all the way to the top and haven't found a
+ marker or tree is not an ident node*/
+ if G_UNLIKELY (tree == NULL ||
+ tree->type != GEL_IDENTIFIER_NODE) {
+ if (tree != NULL) gel_freetree(tree);
+ g_slist_free (elist);
+ g_slist_free (local_idents);
+ return FALSE;
+ }
+ elist = g_slist_prepend (elist, tree->id.id);
+ gel_freetree (tree);
}
- /*we have gone all the way to the top and haven't found a
- marker or tree is not an ident node*/
- if G_UNLIKELY (tree == NULL ||
- tree->type != GEL_IDENTIFIER_NODE) {
- if(tree) gel_freetree(tree);
- g_slist_free(list);
- g_slist_free (local_idents);
- return FALSE;
+ }
+
+ if (arguments) {
+ for (;;) {
+ tree = gel_stack_pop (&gel_parsestack);
+ if (tree != NULL &&
+ tree->type == GEL_EXPRLIST_START_NODE) {
+ gel_freetree (tree);
+ break;
+ }
+ /*we have gone all the way to the top and haven't found a
+ marker or tree is not an ident node*/
+ if G_UNLIKELY (tree == NULL ||
+ tree->type != GEL_IDENTIFIER_NODE) {
+ if (tree != NULL) gel_freetree(tree);
+ g_slist_free (list);
+ g_slist_free (elist);
+ g_slist_free (local_idents);
+ return FALSE;
+ }
+ list = g_slist_prepend (list, tree->id.id);
+ gel_freetree (tree);
+ argnum++;
}
- list = g_slist_prepend(list,tree->id.id);
- gel_freetree(tree);
- i++;
}
-
+
GEL_GET_NEW_NODE(tree);
tree->type = GEL_FUNCTION_NODE;
- tree->func.func = d_makeufunc(NULL,val,list,i, NULL);
+ tree->func.func = d_makeufunc(NULL,val,list,argnum, NULL);
tree->func.func->context = -1;
tree->func.func->vararg = vararg;
tree->func.func->local_all = local_all ? 1 : 0;
tree->func.func->local_idents = local_idents;
+ tree->func.func->never_on_subst_list = never_subst ? 1 : 0;
+
+ if (never_subst) {
+ tree->func.func->built_subst_dict = 1;
+ tree->func.func->subst_dict = elist;
+ }
gel_stack_push(&gel_parsestack,tree);
diff --git a/src/parseutil.h b/src/parseutil.h
index f753790..1d035e2 100644
--- a/src/parseutil.h
+++ b/src/parseutil.h
@@ -23,7 +23,10 @@
#include "extra.h"
-gboolean gp_push_func (gboolean vararg) GEL_WEAK_FUNC;
+gboolean gp_push_func (gboolean vararg,
+ gboolean arguments,
+ gboolean extradict,
+ gboolean never_subst) GEL_WEAK_FUNC;
gboolean gp_prepare_push_param (gboolean setfunc) GEL_WEAK_FUNC;
gboolean gp_prepare_push_region_sep (void) GEL_WEAK_FUNC;
diff --git a/src/structs.h b/src/structs.h
index 2ef214b..fee271d 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -121,6 +121,10 @@ struct _GelEFunc {
/* if true, we must take this off the subst list for a context pop,
* before we free the function */
guint32 on_subst_list:1;
+
+ /* never put on a substlist, have a set extradict */
+ guint32 never_on_subst_list:1;
+
guint32 vararg:1;
guint32 propagate_mod:1;
guint32 no_mod_all_args:1;
diff --git a/src/testscope.gel b/src/testscope.gel
index 829ab89..8c29e8c 100644
--- a/src/testscope.gel
+++ b/src/testscope.gel
@@ -139,5 +139,22 @@ function ff() = (
);
ff();
+A = 1;
+function f(x) = (
+ A = 8;
+ function g(y)[A] = A+5;
+ g
+);
+h = f(0);
+if h(0) != 8+5 then (error("single explicit subst lookup failed");exit());
+
+A = 1;
+function f(x) = (
+ A = 8;
+ function g(y)[] = A+5;
+ g
+);
+h = f(0);
+if h(0) != 1+5 then (error("single explicit non-subst lookup failed");exit());
print("true");
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]