I don’t think this is a feasible, but a thought that came in my head is to make a slope value using a point and the derivative of a function.
foo:
eval "
foo_slope_derivative(a)=derivative(sin(a));
foo_slope_derivative(2); # Returns -0.41614683653772788
"
Not sure how to do this yet without making it by hand, but I think this is kind of a interesting idea. Probably not possible to do it at JIT time either. I’m thinking of getting the slope at arbitrary point. Basically, that is what this is doing here.
This is the closest I can get it to work:
foo:
eval "
slope_derivative(macro_a,macro_b,variable)=(
a=variable-.00001;
b=variable+.00001;
(macro_b-macro_a)/(b-a);
);
slope_derivative(sqr(a),sqr(b),2);
"
Maybe the ‘@’ could be useful as a new char available? Which tells the compiler to substitute with a variable that you assign with macro boundary?
foo:
eval "
slope_derivative(macro,variable)=(
a=variable-.00001;
b=variable+.00001;
((@1,b)-(@1,a))/(b-a);
);
slope_derivative(sqr(@),2);
(@n,a,b…) n is the nth argument of macro, a,b,c and so forth are substituted with variable within the scope of macro. That’s the idea.
You can do a trick like this, using the #
operator in macros (raw copy substitution).
foo :
eval "
# Macro to etimate the derivative of function 'func()' according to variable 'var', at value 'value'.
# Beware: A variable named 'var' will be overwritten.
derivative(func,var,value) = (
eps = 1e-8;
ref(value - eps,var#);
func_left = func#;
ref(value + eps,var#);
func_right = func#;
(func_right - func_left)/(2*eps);
);
a = derivative(3*x + 4,x,1000); # Slope=3 everywhere
b = derivative(sin(x),x,pi); # Slope=-1 at pi
c = derivative(3*x + 4*y,y,0); # Slope=4 (works with functions of multiple variables)
print(a,b,c);
"
EDIT: Writing this example makes me realize how cool is this math evaluator
1 Like
I see what you mean by the warning. Is this the safe version?
derivative(func,var,value) = (
eps = 1e-8;
t_var=var#;
ref(value - eps,var#);
func_left = func#;
ref(value + eps,var#);
func_right = func#;
var#=t_var;
(func_right - func_left)/(2*eps);
);
Even better would be:
derivative(func,var,value) = (
eps = 1e-8;
ref(var#,t_var);
ref(value - eps,var#);
func_left = func#;
ref(value + eps,var#);
func_right = func#;
ref(t_var,var#);
(func_right - func_left)/(2*eps);
);
because var
could be of any type (vector or scalar).