Open Isomorph70 opened 4 years ago
Ops, an error in coping the examples. The correct ones is.
Verify(MapSingle({{node},D({x,y}) node},{9*x^8,0}),{D({x,y}) 9*x^8,D({x,y}) 0});
Verify(MapSingle(Lambda({{node},D({x,y}) node}),{9*x^8,0}),{D({x,y}) 9*x^8,D({x,y}) 0});
Seem like githubs text rendering remove multiplication signs.
Hi,
I agree that this is a bit disappointing result. But it is actually for a reason, even though not a very important one. The D() operator is a macro, so it's application is a bit more convoluted. Fortunately, it's built around much simpler Deriv() operator, which in your case can be used like
In> MapSingle(Lambda({node},{Deriv(x) node, Deriv(y) node}),{9*x^8,0})
Out> {{72*x^7,0},{0,0}}
It this what you're actually after? Does the workaround lokk acceptable?
Cheers, Grzesiek
I am basically trying to make a rule that take in a list of variables vl with n elements and a list of expressions el with m elements and then derive on each expression. Like {{Deriv(vl[1]) el[1],,,Derive(vl[n]) el[1]},.........,{Deriv(vl[1]) el[m],...,Deriv(vl[n]) el[m]}}.
OK, then how about
derivs(vars_IsList, exprs_IsList) <--
MapSingle(Lambda({e}, MapSingle(Lambda({v}, Deriv(v) e), vars)), exprs);
Would this work for you?
Alternatively, risking the wrath of functional programming Gods
derivs(vars_IsList, exprs_IsList) <-- [
Local(e, v, row, result);
result := {};
ForEach(e, exprs) [
row := {};
ForEach(v, vars)
DestructiveAppend(row, Deriv(v) e);
DestructiveAppend(result, row);
];
result;
];
Something more like this will be optimal. 10 # derivs(vars_IsList, expr)\(Not IsList(expr)) <-- MapSingle(Lambda({v}, Deriv(v) expr), vars); 20 # derivs(vars_IsList, exprs_IsList) <-- MapSingle(Lambda({e}, derivs(vars,e)), exprs);
Or in full functional mode. 10 # derivs(_vars, exprs_IsList) <-- If(Length(exprs)=0,{},derivs(vars,Head(exprs)):derivs(vars,Tail(exprs))); 20 # derivs(vars_IsList, _expr) <-- If(Length(vars)=0,{},(derivs(Head(vars),expr)):derivs(Tail(vars),expr)); 30 # derivs(_var,_expr) <-- Deriv(var) expr;
Also, I have been working on a multidimensional Taylor expansion, that I can contribute to the project.
That's awesome, thanks! :)
And obviously the code you suggest is better then mine. The only possible improvement I can see is providing additional rules instead of using If(), like
5 # derivs(_vars, {}) <-- {};
10 # derivs(_vars, exprs_IsList) <-- derivs(vars,Head(exprs)):derivs(vars,Tail(exprs));
15 # derivs({}, _expr) <-- {};
20 # derivs(vars_IsList, _expr) <-- derivs(Head(vars),expr):derivs(Tail(vars),expr);
30 # derivs(_var,_expr) <-- Deriv(var) expr;
but I admit that it's a minor change and based more on personal preference than anything else.
Cheers, Grzesiek
Perfect... Here are some tests, that our new derivs can do, but D can't.
Verify([Local(vl);vl :={x,y};derivs(vl, x+c);],derivs({x,y}, x+c)); Verify(MapSingle(Lambda({node},derivs({x,y},node)),{9*x^8,0}),{derivs({x,y}, 9*x^8),derivs({x,y},0)});
Verify([Local(vl);vl :={x,y};D(vl) x+c;],D({x,y}) x+c); Verify(MapSingle(Lambda({node},D({x,y}) node),{9*x^8,0}),{D({x,y}) 9*x^8,D({x,y}) 0});
The basic issue with D() is that it has shady semantics, definitely to complex for its own good. It's easy to use for some basic operations, but for anything more involved it fails miserably. If ever, it should be used only by an end user to do something simple ad hoc. Definitely it has no place in any implementation of other mechanisms.
On the other hand the semantics you suggest for what is now called derivs() looks good. I think it'd be reasonable to incorporate it into Derivs(), which till now has only basic capabilities, but does them reasonably well.
What do you think about it?
Yes, We better integrate it into Deriv(), so everyone can use it.
Following test show the problem. D({x,y} will be applied to node instead of 9*x^8.
Verify(MapSingle({{node},D({x,y}) node},{9x^8,0}),{D({x,y}) 9x^8,D({x,y}) 0});
Verify(MapSingle(Lambda({{node},D({x,y}) node}),{9x^8,0}),{D({x,y}) 9x^8,D({x,y}) 0});