Re: Pattern in immediate definition
- To: mathgroup at smc.vnet.net
- Subject: [mg120768] Re: Pattern in immediate definition
- From: Peter Pein <petsie at dordos.net>
- Date: Tue, 9 Aug 2011 07:21:16 -0400 (EDT)
- Delivered-to: l-mathgroup@mail-archive0.wolfram.com
- References: <j1o6dl$4i4$1@smc.vnet.net>
Am 08.08.2011 10:23, schrieb eLVa:
> Hi,
>
> I want to write more clearly the following definition :
> TestFunction[{{a_, b_, c_}, {d_, e_, f_}, {g_, h_, k_}}] =
> (* immediate definition with = *)
> Module[{F, det},
> F = {{a, b, c}, {d, e, f}, {g, h, k}};
> det = Det[F];
> Flatten[Table[D[det, F[[i, j]]], {i, 1, 3}, {j, 1, 3}]]
> ]
>
> After that, I can pass any 3x3 matrix to the function and get the
> result directly replaced, without having to evaluate the derivatives
> again , i.e I don't want it to be written :
>
> TestFunction[F_] :=
> (* delayed definition with := *)
> Module[{det},
> det = Det[F];
> Flatten[Table[D[det, F[[i, j]]], {i, 1, 3}, {j, 1, 3}]]
> ]
>
> for it will compute everything every time I get to call the function
> (which will be inefficient since I will call it often).
>
> However, I find the trick with the temporary F that gets to be
> assigned the matrix of {{a,b,c},{d,e,f},{g,h,i}} ugly and potentially
> dangerous since it uses the value of the variables (a,b,...,k) if they
> are defined.
>
> I would like something close to :
> TestFunction[F_<....>] = Module[<...>] where in the first <..> I get
> to specify that the argument is a 3x3 matrix and so I can have access
> to F[[i,j]] (Mathematica complains about this part since F is
> obviously just a symbol and not a matrix). This way I just have to
> worry about F not being defined elsewhere. It will also be a cleaner
> definition in my opinion.
>
> Is that possible in any way ??
> Thanks
>
>
Hi,
for the purpose of writing a new version of TestFunction let's evaluate:
In[1]:= Block[{mat = {{a, b, c}, {d, e, f}, {g, h, k}}, det},
det = Det@mat;
D[det, #]& /@ Flatten[mat]
]
Out[1]= {-f h + e k, f g - d k, -e g + d h,
c h - b k, -c g + a k, b g - a h,
-c e + b f, c d - a f,-b d + a e}
Now you're ready to define (I'm tired of reformatting the copy/paste -
sorry):
TestFunction[m_]:=Block[{a,b,c,d,e,f,g,h,k},
{{a,b,c},{d,e,f},{g,h,k}}=m;
{-f h+e k,f g-d k,-e g+d h,c h-b k,-c g+a k,b g-a h,-c e+b f,c d-a f,-b
d+a e}]/;Dimensions[m]=={3,3}
In[3]:= testMat=Array[If[#1==#2,{x,y,z}[[#1]],1/(#1+#2-1)]&,{3,3}]
Out[3]= {{x,1/2,1/3},{1/2,y,1/4},{1/3,1/4,z}}
In[4]:= TestFunction[testMat]
Out[4]= {-(1/16)+y z,1/12-z/2,1/8-y/3,1/12-z/2,-(1/9)+x
z,1/6-x/4,1/8-y/3,1/6-x/4,-(1/4)+x y}
If you want the entries corresponding to numeric values of the input
matrix to be zero:
In[5]:=
TestFunc2[m_]:=Block[{a,b,c,d,e,f,g,h,k,pos},{{a,b,c},{d,e,f},{g,h,k}}=m;
pos=Position[Flatten[m],_?NumericQ]//Flatten;
ReplacePart[{-f h+e k,f g-d k,-e g+d h,c h-b k,-c g+a k,b g-a h,-c e+b
f,c d-a f,-b d+a e},Thread[pos->0]]]/;Dimensions[m]=={3,3}
In[6]:= TestFunc2[testMat]
Out[6]= {-(1/16)+y z,0,0,0,-(1/9)+x z,0,0,0,-(1/4)+x y}
I hope I didn't misunderstand your intention,
Peter