How to "soft-code" a Block?
- To: mathgroup at smc.vnet.net
- Subject: [mg113302] How to "soft-code" a Block?
- From: dr DanW <dmaxwarren at gmail.com>
- Date: Sat, 23 Oct 2010 07:03:48 -0400 (EDT)
Hard coding a Block is easy:
In[1]:= Block[{a = b, b = c, c = 3},
{a, b, c}
]
Out[1]= {3, 3, 3}
But what if my variable list and expression are themselves values, as
in:
In[1]:= vals = {a = b, c = 3, b = c};
expr = {a, b, c};
Block[vals, expr]
During evaluation of In[1]:= Block::lvlist: Local variable
specification vals is not a List. >>
Out[3]= Block[vals, expr]
Which fails for many obvious reasons. However, is there a way to do
this, as in:
In[1]:= vals = {a -> b, c -> 3, b -> c};
expr = {a, b, c};
RuleBlock[vals, expr]
Out[3]= {3, 3, 3}
How can I write RuleBlock[], which functions as a scoping construct
and Set's the left hand sides to the right hand sides of all the Rules
in the list?
Why do I need this? I am writing a modeling program which builds up a
complicated compound expression in terms of some parameters. The
expression can be evaluated quickly once numerical values of the
parameters are supplied. I also want to be able to evaluate the
expression for different sets of parameters.
The obvious solution, using expr //. vals, does not always work for
several reasons:
* The expression contains several SparseArray's, and Replace does not
work within SparseArray's.
* The expression may contain other scoping structures or functions
which do not respond to Replace unless wrapped with Evaluate every
place it is used
* This is a complicated, programmatically generated expression, and
finding every instance where Replace would have to be Evaluate'd would
be tedious (meaning: error prone)
This would be so much easier with a scoping structure I could soft-
code. I have attempted this with:
RuleBlock[r_?OptionQ, exp_] :=
Block[
Evaluate[r[[All, 1]]],
Evaluate[r /. Rule -> Set];
exp
]];
Which seems to work most of the time, but has failed me for reasons
that I cannot explain on some occasions. I can't come up with a
simple example that demonstrates this failure.
Whenever I work this hard on something this low-level in Mathematica,
it usually means that there is an obvious solution I missed, or a
feature in Mathematica I am unaware of. I have struggled with this
one for many years and have used various band-aids, but I am tired of
it and want to have a robust solution that works all the time.
Any suggestions?
Regards,
Daniel