Mathematica Asked by Jo Mo on July 7, 2021
Here’s my basic setup:
Say I have a list of specific symbols and a function noSymbol
, which accepts a mathematica expression and checks whether any symbol from my list is contained in it, for example:
symbols = {basisElement};
noSymbol[x_] := And @@ ( Length[Position[x, #]] === 0 & /@ symbols );
An examle use-case could be that basisElement
is a function enumerating basis vectors of some n
-dimensional algebra, so that I could define the multiplication of the algebra as
mult[basisElement[i_], basisElement[j_]] := Sum[strucConst[i, j, k] * basisElement[k], {k, 1, n}];
with structConst
the structure constants of the algebra.
Of course in this situation it is natural to define linear functions, and what I would often find myself doing is
Clear[f];
f[0] := 0;
f[v_ + w_] := f[v] + f[w];
f[a_ * v_] := a * f[v] /; noSymbol[a];
f[v_ * a_] := a * f[v] /; noSymbol[a];
(* actual function definition *)
at the beginning of every definition of a linear function.
This adds a lot of repetition to my code, so I wanted to ask if using a "linearizing function" like
linearize[f_] := (
f[0] := 0;
f[v_ + w_] := f[v] + f[w];
f[a_ * v_] := a * f[v] /; noSymbol[a];
f[v_ * a_] := a * f[v] /; noSymbol[a];
);
Clear[f];
linearize[f];
(* actual function definition *)
is considered good practices and makes sense, or if it could lead to any serious issues.
EDIT:
Additionally, if this is good practice, how can I extend my linearize
function so that it can "multilinearize"? For example, my multiplication from above would have to be linear in each argument.
First, a note regarding noSymbol
: You can more easily implement it using FreeQ
:
symbols = Alternatives[basisElement];
noSymbol := FreeQ[symbols]
Also, you don't need to define both f[a_ * v_]
and f[v_ * a_]
, since Times
is Orderless
.
As for the actual question: I don't see any reason why this shouldn't be done, in fact, I've used very similar functions in the past.
Finally, for multi-linearization: You can do something like the following:
linearize[f_] := (
f[___, 0, ___] := 0;
f[pre___, v_ + w_, post___] := f[pre, v, post] + f[pre, w, post];
f[pre___, a_ * v_, post___] := a*f[pre, v, post] /; noSymbol[a];
);
Clear[f];
linearize[f];
f[a basisElement, c + d]
(* a f[basisElement, c] + a f[basisElement, d] *)
The rules simply apply the linearity properties to any argument, while keeping all the others (if any exist) unmodified
Correct answer by Lukas Lang on July 7, 2021
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP