TransWikia.com

A function that modifies functions - well-defined operation?

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.

One Answer

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

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP