2
$\begingroup$

Struggled for a while on this problem and hopefully you can help... I have a mathematical expression that currently has a symbol where I used to have a function variable. How do I make the symbol back into a variable, so that my expression becomes a function again? My function became an expression when I saved it in a matrix, and so now I'm trying to make the different matrix elements back into functions after having constructed the matrix. Thanks in advance.

INCLUDING SOME CODE (my first time contributing on this website...)

Imagine a For loop sum (I've removed a substantial amount of code that's irrelevant for now)

Pstatesalpha[λ_]=0;
RankMatrix={};
elecdipole (*some vector of numbers delem*)
SumPstatesalpha[λ_, Alpharank_]  (*a predefined function of λ, Alpharank*)

For[Alpharank = 1, Alpharank <= 3, Alpharank++,(
   For[jsum = 1, jsum <=Length[elecdipole], jsum++,(
Pstatesalpha[λ_] = (delem*a0)^2*SumPstatesalpha[λ,Alpharank] + Pstatesalpha[λ];
   )]
AppendTo[RankMatrix, {Alpharank,Pstatesalpha[λ]}]
)]

Note that I've saved Pstatesalpha[λ] as a function into RankMatrix. When I want to access (for instance)

RankMatrix[[1,2]]

Mathematica returns an expression that includes $\lambda$, but I can't use it as a function anymore.

$\endgroup$
5
  • $\begingroup$ This is definitely a job for a substitution rule, but care to give us more info about the said expression? $\endgroup$
    – Spawn1701D
    Commented Apr 16, 2013 at 23:09
  • $\begingroup$ By the way, thank you @Spawn1701D and Mr.Wizard for your quick responses. I should have included an example from the beginning to guide your help better... $\endgroup$
    – Verde
    Commented Apr 16, 2013 at 23:47
  • $\begingroup$ Is SumPstatesalpha intended to be a separate function from Pstatesalpha or is that a typo? You say "I can't use it as a function anymore" -- could you give an example how you would like to use it? $\endgroup$
    – Mr.Wizard
    Commented Apr 17, 2013 at 0:13
  • $\begingroup$ FYI: comments in Mathematica are delimited like this: (* comment *) $\endgroup$
    – Mr.Wizard
    Commented Apr 17, 2013 at 0:22
  • $\begingroup$ I added an example to my answer. Can you confirm that it is what you want? $\endgroup$
    – Mr.Wizard
    Commented Apr 17, 2013 at 0:26

2 Answers 2

2
$\begingroup$

Second try.

In the comments below Spawn's answer you said that you are trying to construct a table of functions. Does this do what you want?:

Pstatesalpha[λ_] = 0;

RankMatrix = {};

For[jsum = 1, jsum <= 3, jsum++,
 Pstatesalpha[λ_] = (delem*a0)^2*SumPstatesalpha[λ] + Pstatesalpha[λ];
 AppendTo[RankMatrix, {Alpharank, Function @@ {λ, Pstatesalpha[λ]}}]
]

The key detail is appending Function @@ {λ, Pstatesalpha[λ]} which will build a function with the evaluated expression Pstatesalpha[λ] as the body and the parameter λ.

Now:

RankMatrix[[1, 2]][17]
a0^2 delem^2 SumPstatesalpha[17]

Since the above was Accepted (thanks) let me explain a bit better.

I use the method fn @@ {args} to evaluate args and pass them to a function fn (using Apply) that otherwise holds its arguments (has a Hold attribute).

In the code above, copied from the question, there is a global symbol λ which if assigned a value will break the code. One method to avoid this is to use a Formal Symbol, entered Esc$xEsc where x is any a-z letter. These symbols exist specifically for cases like this. Another method is to use Slot as in the syntax # + 2 & (the FullForm of # is Slot[1]). That might look like this (in context):

AppendTo[RankMatrix, {Alpharank, Evaluate[Pstatesalpha[#]] &}]

Evaluate is used instead of Apply and List, but many methods are possible:

Evaluate[Pstatesalpha[#]] &

Function @@ {Pstatesalpha[#]}

With[{body = Pstatesalpha[#]}, body &]

Pstatesalpha[#] /. x_ :> (x &)

With each of these Pstatesalpha[#] is evaluated outside of Function and then inserted into it.

$\endgroup$
3
  • $\begingroup$ You know, I think that did it! I'd been using Function for a good 3+ hours but it never seemed to work correctly. Thank you very much! $\endgroup$
    – Verde
    Commented Apr 17, 2013 at 0:34
  • $\begingroup$ @Verde I'm glad this helped. Function works properly, just not the way that you anticipated. It is often important that the body of a function not evaluate until the parameters are filled, therefore Function has the HoldAll attribute. (See this for another example where that gets in the way.) Since List does not have HoldAll, and is syntactically concise, fn @@ {args} is a common method to evaluate args and pass them to a function fn (using Apply) that otherwise holds its arguments. $\endgroup$
    – Mr.Wizard
    Commented Apr 17, 2013 at 1:07
  • $\begingroup$ @Verde I added a few more details and methods to my answer. $\endgroup$
    – Mr.Wizard
    Commented Apr 17, 2013 at 1:28
0
$\begingroup$

Ok if I understand correctly you want to create a list of functions for example

RankMatrix={}

For[jsum = 1, jsum <= 3, jsum++,
       Pstatesalpha[jsum][x_] = (delem*a0)^2*SumPstatesalpha[x] + Pstatesalpha[x];
       AppendTo[RankMatrix, {Alpharank,Pstatesalpha[jsum]}]
    ]

Now on RankMatrix you have a matrix including a set of functions and to access one of them : RankMatrix[[1,2]][λ]

In Mathematica we often don't use the procedural methods employed in the usual programming languages, like for, do etc. I give you an equivalent solution using Mathematica's command for matrix creation:

RankMatrix= Array[Function[Pstatesalpha[#][x_] = (delem*a0)^2*SumPstatesalpha[x] + 
                  Pstatesalpha[x];{Alpharank, Pstatesalpha[#]}], 
                  3]
$\endgroup$
4
  • $\begingroup$ Yes - what I intended to create with AppendTo was a matrix of functions. However, when I ask for a matrix element outside of the For loop, it's not a function anymore, but an expression... $\endgroup$
    – Verde
    Commented Apr 16, 2013 at 23:50
  • $\begingroup$ @Verde In this way inside the loop you define the function and on the matrix you get its ... Head. I assume that in your specific problem the formula and Alpharank changes for different values of jsum ... $\endgroup$
    – Spawn1701D
    Commented Apr 17, 2013 at 0:06
  • $\begingroup$ I'm going to try to work with your suggestion, but the thing is, there's actually a For loop inside a For loop because of the different variables I have to sum over. I would rather not get rid of the For loops, to be honest. What I'm creating with these For loops is a function whose variable is $\lambda$ that I can calculate things with, plot, etc. I don't have a pre-defined list of values to calculate the function for. $\endgroup$
    – Verde
    Commented Apr 17, 2013 at 0:09
  • $\begingroup$ Thanks a lot, Spawn1701D. I'm going to have to learn how to use your comments in my code. It'll simplify it, I bet... $\endgroup$
    – Verde
    Commented Apr 17, 2013 at 0:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.