functions as arguments to functions.
- To: mathgroup at smc.vnet.net
- Subject: [mg13962] functions as arguments to functions.
- From: sean_ross_at_pl-04m3 at smtpgw1.plk.af.mil
- Date: Fri, 11 Sep 1998 15:06:51 -0400
- Sender: owner-wri-mathgroup at wolfram.com
Lets consider a function 'newfunction' which takes an expression as an argument. If I wish to work with the expression as a function inside newfunction, I have some options as to what syntax to use as illustrated below in the private functions g,g2,g3,g4. Note that I wish to shield the user of the function from pure function constructs like most built-in mathematica functions do. newfunction[f_,x_,x1_]:=Module[{g,g2,g3,g4}, g=(f/.x->#)&; g2[xx_]=Hold[f]/.x->xx; g3=Function[x,f]; g4[xx_]:=f/.x->xx; {g[x1],ReleaseHold[g2[x1]],g3[x1],g4[x1]}] Here is the expected behavior: All of the above forms are equivalent to each other and to the original function when evaluated numerically as illustrated below. It turns out that the syntaxes evaluate with different speeds, but they all arrive at the same place. In[2]:= newfunction[Sin[x]^3-x,x,2.5] Out[2]= {-2.28565,-2.28565,-2.28565,-2.28565} In[9]:= Sin[2.5]^3-2.5 Out[9]= -2.28565 I am currently working with a function which itself calls functions which use Solve and other things. For some reason, this complicated function does not behave as expected when given to newfunction as an argument. In[7]:= newfunction[DkKTPsfgII[63 Degree,0. Degree,1.064,x],x,1.32] Out[7]= {-0.0466874,-0.0466874,-0.0466874,-0.0466874} In[8]:= DkKTPsfgII[63 Degree,0. Degree,1.064,1.32] Out[8]= -0.00034538 Notice that here, the four syntaxes agree with each other, but they are all wrong in the sense that they don't evaluate to the same number the original function did. The really weird thing is that the syntaxes for g2 and g3 work correctly when not placed inside a Module construct. The syntaxes for g1 and g4 don't work correctly at all. I am attaching a notebook which contains the definition of the DkKTPsfgII function. I would appreciate any suggestions to: --alternate syntaxes for passing functions as arguments. --any insights as to why this particular function(DkKTPsfgII) is pathological to mathematica and how I might change it. --any workarounds. Please respond directly to me: rosss at plk.af.mil or seanross at worldnet.att.net as I don't subscribe to the mathgroup any more. Also, please bear in mind that simple examples are irrelevant to this issue. All four syntaxes work for simple functions. They don't work for really complicated ones. I have a dozen more similarly pathological functions, but am not including them so as not to clutter up the issue. Thanks, Sean Ross
(*********************************************************************** Mathematica-Compatible Notebook This notebook can be used on any computer system with Mathematica 3.0, MathReader 3.0, or any compatible application. The data for the notebook starts with the line of stars above. To get the notebook into a Mathematica-compatible application, do one of the following: * Save the data starting with the line of stars above into a file with a name ending in .nb, then open the file inside the application; * Copy the data starting with the line of stars above to the clipboard, then use the Paste menu command inside the application. Data for notebooks contains only printable 7-bit ASCII and can be sent directly in email or through ftp in text mode. Newlines can be CR, LF or CRLF (Unix, Macintosh or MS-DOS style). NOTE: If you modify the data for this notebook not in a Mathematica- compatible application, you must delete the line below containing the word CacheID, otherwise Mathematica-compatible applications may try to use invalid cache data. For more information on notebooks and Mathematica-compatible applications, contact Wolfram Research: web: http://www.wolfram.com email: info at wolfram.com phone: +1-217-398-0700 (U.S.) Notebook reader applications are available free of charge from Wolfram Research. ***********************************************************************) (*CacheID: 232*) (*NotebookFileLineBreakTest NotebookFileLineBreakTest*) (*NotebookOptionsPosition[ 7945, 172]*) (*NotebookOutlinePosition[ 8594, 195]*) (* CellTagsIndexPosition[ 8550, 191]*) (*WindowFrame->Normal*) Notebook[{ Cell[TextData[{ "KTP is a biaxial crystal, so I first must work out the general form for \ the percieved index of refraction in a biaxial crystal. I start with Yariv, \ chapter 4. First, we solve the vector equation ", Cell[BoxData[ \(TraditionalForm \`\(k\&\[RightVector]\) x\ \(k\&\[RightVector]\) x\ E\&\[RightVector] = \(-\[Omega]\^2\) \(\[Mu]\_0\) D\&\[RightVector]\)]], " (1). It can be written as a sort of eigenvector problem and a quadratic \ solution for the effective index of refraction obtained. This is contained \ in the nextKTP function, which calls on the next function for the algebraic \ form of the determinant of (1) and on nxKTP etc for the indices along the \ principle axes. The solution of the determinant of (1) is quadratic in ", Cell[BoxData[ \(TraditionalForm\`n\^2\)]], ", so there are always two answers returned. These correspond to preferred \ orthogonal axes for the polarization direction." }], "Text"], Cell[CellGroupData[{ Cell["\<\ index of refraction as a function of propagation direction in a biaxial \ crystal (KTP)\ \>", "Section"], Cell[BoxData[ RowBox[{ RowBox[{ \(Clear[kmatrix, nmatrix, nextKTP, nxKTP, nyKTP, nzKTP, abs, unitv]\), ";", "\n", \(abs[v : {__}] := Sqrt[v . v]\), ";", "\n", \(unitv[v : {__}] := v/abs[v]\), ";", "\n", RowBox[{\(kmatrix[\[Theta]_, \[Phi]_, \[Lambda]_]\), ":=", RowBox[{"(", TagBox[ RowBox[{ RowBox[{"(", GridBox[{ { \(\(-n\^2\)\ \((Cos[\[Theta]]\^2 + Sin[\[Theta]]\^2\ Sin[\[Phi]]\^2)\) + n\_x\%2\), \(n\^2\ Cos[\[Phi]]\ Sin[\[Theta]]\^2\ Sin[\[Phi]]\), \(n\^2\ Cos[\[Theta]]\ Cos[\[Phi]]\ Sin[\[Theta]]\)}, {\(n\^2\ Cos[\[Phi]]\ Sin[\[Theta]]\^2\ Sin[\[Phi]]\), \(\(-n\^2\)\ \((Cos[\[Theta]]\^2 + Cos[\[Phi]]\^2\ Sin[\[Theta]]\^2)\) + n\_y\%2\), \(n\^2\ Cos[\[Theta]]\ Sin[\[Theta]]\ Sin[\[Phi]]\)}, {\(n\^2\ Cos[\[Theta]]\ Cos[\[Phi]]\ Sin[\[Theta]]\), \(n\^2\ Cos[\[Theta]]\ Sin[\[Theta]]\ Sin[\[Phi]]\), \(\(-n\^2\)\ Sin[\[Theta]]\^2 + n\_z\%2\)} }], ")"}], "/.", \({n\^2 -> nn, n\^4 -> nn\^2, n\_x -> nxKTP[\[Lambda]], n\_y -> nyKTP[\[Lambda]], n\_z -> nzKTP[\[Lambda]]}\)}], (MatrixForm[ #]&)], ")"}]}], ";", "\n", \( (*a\ symbolic\ determinant\ is\ needed\ here . \ \ If\ you\ take\ a \ numerical\ one, \ small\ cubic\ terms\ creep\ in\ for\ values\ of\ \[Theta]\ and\ \[Phi]\ near, \ but\ on\ on\ the\ principle\ axes\ and\ give\ bad\ \(answers . \)*) \), "\n", "\n", \(kdeterminant[\[Theta]_, \[Phi]_, \[Lambda]_] := \((n\_x\%2\ n\_y\%2\ n\_z\%2 + n\^4\ \(( Cos[\[Theta]]\^2\ Cos[\[Phi]]\^2\ Sin[\[Theta]]\^2\ n\_x\%2 + Cos[\[Phi]]\^4\ Sin[\[Theta]]\^4\ n\_x\%2 + Cos[\[Phi]]\^2\ Sin[\[Theta]]\^4\ Sin[\[Phi]]\^2\ n\_x\%2 + Cos[\[Theta]]\^2\ Sin[\[Theta]]\^2\ Sin[\[Phi]]\^2\ n\_y\%2 + Cos[\[Phi]]\^2\ Sin[\[Theta]]\^4\ Sin[\[Phi]]\^2\ n\_y\%2 + Sin[\[Theta]]\^4\ Sin[\[Phi]]\^4\ n\_y\%2 + Cos[\[Theta]]\^4\ n\_z\%2 + Cos[\[Theta]]\^2\ Cos[\[Phi]]\^2\ Sin[\[Theta]]\^2\ n\_z\%2 + Cos[\[Theta]]\^2\ Sin[\[Theta]]\^2\ Sin[\[Phi]]\^2\ n\_z\%2)\) + n\^2\ \(( \(-Cos[\[Phi]]\^2\)\ Sin[\[Theta]]\^2\ n\_x\%2\ n\_y\%2 - Sin[\[Theta]]\^2\ Sin[\[Phi]]\^2\ n\_x\%2\ n\_y\%2 - Cos[\[Theta]]\^2\ n\_x\%2\ n\_z\%2 - Cos[\[Phi]]\^2\ Sin[\[Theta]]\^2\ n\_x\%2\ n\_z\%2 - Cos[\[Theta]]\^2\ n\_y\%2\ n\_z\%2 - Sin[\[Theta]]\^2\ Sin[\[Phi]]\^2\ n\_y\%2\ n\_z\%2)\)) \) /. {n\^2 -> nn, n\^4 -> nn\^2, n\_x -> nxKTP[\[Lambda]], n\_y -> nyKTP[\[Lambda]], n\_z -> nzKTP[\[Lambda]]}\), ";", "\n", "\n", \(nmatrix[\[Theta]_, \[Phi]_, \[Lambda]_, j_: 1] := Module[{mat}, mat = kmatrix[\[Theta], \[Phi], \[Lambda]] /. nn -> \(nextKTP[\[Theta], \[Phi], \[Lambda]]\)[\([j]\)]^2; \n \tChop[mat/Max[Chop[mat]]]]\), ";", "\n", "\n", "\n", \(nextKTP[\[Theta]_, \[Phi]_, \[Lambda]_] := \t\t\n\t\t Sqrt[Flatten[ nn /. Solve[ kdeterminant[\[Theta], \[Phi], \[Lambda]] == 0, {nn}]]]\), ";", "\n", "\n", \(nxKTP[\[Lambda]_] := Module[{aa = 2.11460, bb = 0.89188, cc = 0.20861, dd = 0.01320}, Sqrt[aa + bb\/\(1 - \((cc/\[Lambda])\)\^2\) - dd\ \[Lambda]\^2]] \), ";", "\n", \(nyKTP[\[Lambda]_] := Module[{aa = 2.15180, bb = 0.87862, cc = 0.21801, dd = 0.01327}, Sqrt[aa + bb\/\(1 - \((cc/\[Lambda])\)\^2\) - dd\ \[Lambda]\^2]] \), ";", "\n", \(nzKTP[\[Lambda]_] := Module[{aa = 2.31360, bb = 1.00012, cc = 0.23831, dd = 0.01679}, Sqrt[aa + bb\/\(1 - \((cc/\[Lambda])\)\^2\) - dd\ \[Lambda]\^2]] \), ";"}], "\n"}]], "Input"] }, Open ]], Cell[BoxData[ \(\(\[CapitalDelta]kKTPsfgII[\[Theta]_, \[Phi]_, \[Lambda]1_, \[Lambda]2_] := Module[{\[Lambda]sum}, \[Lambda]sum = \((1\/\[Lambda]1 + 1\/\[Lambda]2)\)\^\(-1\); \(nextKTP[\[Theta], \[Phi], \[Lambda]sum]\)[\([1]\)]\/\[Lambda]sum - \(nextKTP[\[Theta], \[Phi], \[Lambda]1]\)[\([2]\)]\/\[Lambda]1 - \(nextKTP[\[Theta], \[Phi], \[Lambda]2]\)[\([1]\)]\/\[Lambda]2]; \)\)], "Input"] }, FrontEndVersion->"Microsoft Windows 3.0", ScreenRectangle->{{0, 800}, {0, 572}}, WindowSize->{651, 434}, WindowMargins->{{Automatic, 46}, {Automatic, 5}} ] (*********************************************************************** Cached data follows. If you edit this Notebook file directly, not using Mathematica, you must remove the line containing CacheID at the top of the file. The cache data will then be recreated when you save this file from within Mathematica. ***********************************************************************) (*CellTagsOutline CellTagsIndex->{} *) (*CellTagsIndex CellTagsIndex->{} *) (*NotebookFileOutline Notebook[{ Cell[1709, 49, 980, 17, 128, "Text"], Cell[CellGroupData[{ Cell[2714, 70, 114, 3, 74, "Section"], Cell[2831, 75, 4641, 84, 890, "Input"] }, Open ]], Cell[7487, 162, 454, 8, 77, "Input"] } ] *) (*********************************************************************** End of Mathematica Notebook file. ***********************************************************************)