Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I have a set of PDE's that depend on parameters. They depend on many parameters, but for simplicity we can here assume that they depend only on one, say a.

I want to solve them for many parameter sets, using something of the form

With[{a=1},NDSolve[...]]

But since I have many sets of parameters, and it is very inconvenient to enter them each time, I want to have something like

p1 = {a=1};
p2 = {a=Pi+4};
...
With[p1,NDSolve[...]]
With[p2,NDSolve[...]]

This clearly doesn't work because evaluating p1={a=1} assigns a value for a, and I don't want that (because I want to continue doing symbolic manipulations in other parts of the notebook). SetDelayed and RuleDelayed don't seem to work neither. Any ideas?

EDIT

I was asked to improve the description of my problem, so I try (and, on the way, thank all the people who tried to help).

The situation is this. I have a notebook that contains many formulas, which depend on many parameters. For example, I have

 f[x_]:= Sin[a x^b];
 g[x_]:= a/x +Exp[-b]x;
 diffEq={x'[t]==f[x[t]] x[t]^2-x/g[x[t]], x[0]==123};

I want to do symbolic manipulations on the formulas, so I don't want to assign numerical values to a,b. At the same time, I want to to solve the differential equation diffEq, and for this I want numerical values, and I want to solve it for different sets of paramters a,b. So I want to have variables which are assignments, something like

ass1={a->1,b->3};
ass2={a->123,b->Pi};
ass3={a->-32,b->1241203853};
...

So that I could easily do

With[ass1,NDSolve[...]]
With[ass2,NDSolve[...]]
....

and play around with the variables. I hope this better describes what I want to do.

share|improve this question
1  
Not sure I quite understand what you want. Would nested With be acceptable? For example, With[{p1 := {a = 1}, p2 := {a = Pi + 4}}, With[p1, Print[a]]; With[p2, Print[a]];]; –  Oleksandr R. Apr 3 '12 at 12:40
    
@OleksandrR. But then I have to retype each time the assignments (a=1, etc.). I have around 12 parameters to type each time and I seek a way to circumvent it. –  yohbs Apr 3 '12 at 13:28
    
I guess the problem is that I don't understand what "each time" means in this context, i.e. what your broader use case is. How about this: withp1 = Function[Null, With[{a = 1}, #1], HoldAll]. This lets you write withp1[...], e.g. withp1@Print[a] gives 1. I think this might be closer to what you want, assuming you can specify your parameter sets fully in advance? –  Oleksandr R. Apr 3 '12 at 14:07
    
I think you should really give us a larger context (larger, but not too large, self-contained example), and explain what you are really after and why the suggested methods (e.g. local rules, or the method suggested by @Oleksandr) don't work for you, if you want better -targeted answers. –  Leonid Shifrin Apr 3 '12 at 21:47
    
@LeonidShifrin I expanded my post. Thanks. –  yohbs Apr 4 '12 at 20:48
add comment

3 Answers

up vote 2 down vote accepted

I think this does what you want, it is like a Block that accepts the local variables given as rules. Using Block instead of With should solve the problem that some of your parameters are "hidden in complicated functions":

ClearAll@blockrules

SetAttributes[blockrules, HoldAll]

blockrules[rules_, expr_] := Block @@ Join[
   Hold @@ {rules} /. Rule -> Set,
   Hold[expr]
   ]

use it like e.g.:

blockrules[ass1, NDSolve[diffEq, {x}, {t, 0, 1}]]

While I think this should solve the problem you were describing, you probably should think about rearranging your code so that it does not use global symbols hidden deeply in complicated functions as parameters but rather make those parameters explicit arguments to those functions. You are asking for all kind of hard to detect errors with those "hidden" parameters...

share|improve this answer
add comment

Perhaps something like this:

NDSolve @@ (f[arg, p2] /. {p2 :> (Pi + 4)})

where f is a dummy variable that should have the exact arguments NDSolve needs. Then, after the replacement of p2, f is replaced by NDSolve and evaluation commences.

share|improve this answer
add comment

Just use rule replacement normally on your list of equations, instead of on the NDSolve expression as a whole. For convenience, I recommend assigning the equations to a variable. For example:

In[23]:= eqns = {x'[t] == a y[t], y'[t] == -b y[t], x[0] == 1, y[0] == 0};

In[24]:= NDSolve[eqns /. {a -> 1, b -> 2}, {x, y}, {t, 0, 10}]
Out[24]= {{x -> InterpolatingFunction[{{0.,10.}},<>],
           y -> InterpolatingFunction[{{0.,10.}},<>]}}
share|improve this answer
    
Thanks for the suggestion. This will not work because the parameters are hidden in complicated functions. For example, f[a]=Sin[a]; eqns={x'[t]=f[a] x[t],...} –  yohbs Apr 3 '12 at 12:53
    
@yohbs, that does not work because it is not correct syntax. Try: f[a] = Sin[a]; eqns = {x'[t] == f[a] x[t]} /. {a :> (Pi + 4)} –  user21 Apr 3 '12 at 13:41
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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