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