Re: MultiLinear and Linear function
- To: mathgroup at smc.vnet.net
- Subject: [mg25573] Re: [mg25540] MultiLinear and Linear function
- From: Daniel Lichtblau <danl at wolfram.com>
- Date: Sun, 8 Oct 2000 00:41:59 -0400 (EDT)
- References: <200010070735.DAA01824@smc.vnet.net>
- Sender: owner-wri-mathgroup at wolfram.com
Arturas Acus wrote:
>
> Dear group,
>
> Here was a question how to make a function linear. Below is the
> solution
> from (I think Noncommutative Algebra package, but not sure):
>
> SetLinear[a__] := (Function[x, x[0] := 0;
> x[y_ + z_] := x[y] + x[z];
> x[c_ y_] := c x[y] /; NumberQ[c];
> x[y_/c_] := (1/c) x[y] /; NumberQ[c];
> x[c_] := c x[1] /; NumberQ[c] && Not[TrueQ[c == 1]];
> x[-y_] := -x[y];
> LinearQ[x] = True;] /@ {a});
>
> It works fine, but is only applied to function of multiple variables.
> Bolow is my solution for MultiLinear function. It works, but is not
> so
> elegant as example bekow. Probably anybody knows a better approach?
>
> makePattern[x_, y_, {n_Integer, {m_Integer}}] :=
> Module[{z, p1, p2}, p1 = Table[Unique[], {n - 1}];
> p2 = Table[Unique[], {z, n + 1, m}];
> ReplaceAll[
> Function[y,
> x[Sequence @@ Flatten[Pattern[#, Blank[]] & /@ p1], y,
> Sequence @@ Flatten[Pattern[#, Blank[]] & /@ p2]]],
> Pattern -> myPattern]]
>
> SetMultiLinear[
> s__Symbol, {i_Integer, {l_Integer}}] := (Function[x,
> Module[{pureF, locvar},
> pureF = makePattern[x, locvar, {i, {l}}];
> SetDelayed @@ {ReplaceAll[
> Evaluate[pureF[y_ + z_], myPattern -> Pattern]],
> ReplaceAll[Evaluate[pureF[y] + pureF[z]],
> myPattern[a_, Blank[]] :> a]};
>
> SetDelayed @@ {ReplaceAll[
> Evaluate[pureF[c_*y_], myPattern -> Pattern]],
> ReplaceAll[Evaluate[c*pureF[y]],
> myPattern[a_, Blank[]] :> a] /; NumberQ[c]};
>
> SetDelayed @@ {ReplaceAll[
> Evaluate[pureF[y_/c_], myPattern -> Pattern]],
> ReplaceAll[Evaluate[(1/c)*pureF[y]],
> myPattern[a_, Blank[]] :> a] /; NumberQ[c]};
>
> SetDelayed @@ {ReplaceAll[
> Evaluate[pureF[c_], myPattern -> Pattern]],
> ReplaceAll[Evaluate[c*pureF[1]],
> myPattern[a_, Blank[]] :> a] /;
> NumberQ[c] && Not[TrueQ[c === 1]]};
> LinearQ[x, {i, {l}}] = True;
> ];
> ] /@ {s}) /; Greater[l, 1]
>
>
> SetMultiLinear[s__Symbol, {All, {l_Integer}}] :=
> Map[SetMultiLinear[s, {#, {l}}] &, Range[l]]
>
>
> Example of usage: Make Commutator and AntiCommutator linear
> functions of both variables:
> SetMultiLinear[Commutator,AntiCommutator,{All,{2}}].
>
> Make f be linear in 3-th its argument of total 5:
> SetMultiLinear[f,{3,{5}}].
>
>
> Better solution welcome
>
>
> Dr. Arturas Acus
> Institute of Theoretical
> Physics and Astronomy
> Gostauto 12, 2600,Vilnius
> Lithuania
>
> E-mail: acus at itpa.lt
> Fax: 370-2-225361
> Tel: 370-2-612906
Could emulate SetLinear. Below is simple code to do this (SetLinear is
overly complicated re handling of numeric scalars).
SetMultilinear[heds_] := (
Function[x, x[___,0,___] := 0;
x[a___, y_ + z_, b___] := x[a,y,b] + x[a,z,b];
x[a___,c_?NumericQ*y_,b___] := c*x[a,y,b];
x[a___,c_?NumericQ,b___] := c*x[a,1,b] /; c =!= 1;
MiltilinearQ[x] = True;] /@ {heds});
Example:
In[14]:= SetMultilinear[y];
In[15]:= ??y
Global`y
y[___, 0, ___] := 0
y[a$___, y$_ + z$_, b$___] := y[a$, y$, b$] + y[a$, z$, b$]
y[a$___, y$_*(c$_)?NumericQ, b$___] := c$*y[a$, y$, b$]
y[a$___, (c$_)?NumericQ, b$___] := c$*y[a$, 1, b$] /; c$ =!= 1
Example:
In[16]:= y[3, 2+4*Pi*a, x+7*z]
Out[16]= 6 y[1, 1, x] + 42 y[1, 1, z] + 12 Pi y[1, a, x] + 84 Pi y[1, a,
z]
Daniel Lichtblau
Wolfram Research
- References:
- MultiLinear and Linear function
- From: "Arturas Acus" <acus@itpa.lt>
- MultiLinear and Linear function