Message Boards Message Boards

Generating variables and assigning them values?

All,

I am working on making a program very dynamic. I have a system where the variables (in my case, chemical elements) could change. Each of these elements has a large number of constants associated with them. I want to set all of the constants to zero unless the user actually specifies the value. For example:

\[CapitalGamma]Co60 = 100;
Ns = {"Co60", "Co61", "Co62", "Co63"};
\[CapitalGamma]Vals = 
 MapThread[ToExpression[StringJoin[{"\[CapitalGamma]", #1}]] &, {Ns}]

Now I would like to allow the code to assign [CapitalGamma]Co61 through Co63 to zero without having to directly specify that. This is obviously very simplified, the actual system and code could have hundreds of constants and I want to be able to exchange variables at will. If somebody has a better way to do this, I am open to suggestions.

POSTED BY: Robbie Haffner
5 Replies

Wouldn't "indexed variables" work well here? See the section "True Dictionaries in Mathematica (5)" at http://kodu.ut.ee/~kkannike/english/prog/mathematica/

The topic of "indexed variables" (aka "indexed objects" or "subscripted variables") may be somewhat difficult to locate in the current Mathematica documentation (the link in the webpage above is dead). Here is what I can find on my Mathematica 10.1 installation in the Help system: tutorial/MakingDefinitionsForIndexedObjects under tutorial/TransformationRulesAndDefinitionsOverview

It is possible that the more recent Wolfram Language constructs such as Association may supplant implementing dictionaries (sets, hashmaps) this old way, but the old way is what I know.

POSTED BY: Frank Iannarilli

I think I way over-analyzed this. The easiest way to do what I want is with a simple MapThread:

Ns = {"Co60", "Co61", "Co62", "Co63"};
(*Set the array of constants up*)
\[CapitalGamma]Vals = 
 MapThread[ToExpression[StringJoin[{"\[CapitalGamma]", #1}]] &, {Ns}]
(*Set them all to 0*)
MapThread[{#1 = 0} &, {\[CapitalGamma]Vals}]
(*Define the useful constants*)
\[CapitalGamma]Co60 = 20

But I can see how it would be useful to use indexed variables here. It certainly looks quite a bit cleaner:

indexedVariable[var_, indicesValues__] := 
  With[{dict = List[indicesValues]}, 
   Scan[(var[#[[1]]] = #[[2]]) &, dict]];

indexedVariable[dict, MapThread[{#1, 0} &, {Ns}]]

Thanks for the suggestion!

POSTED BY: Robbie Haffner

Maybe you can use Symbolize somehow?

POSTED BY: Gianluca Gorni

Programmatically generating variable names is almost never a good idea in basically any language. The function "ToExpression" and its cousins in other programming languages (usually called eval or something similar) are the source of many sins and much suffering. If you find yourself using it, you likely want to restructure how you are approaching the problem.

  1. You want to use a list to store the values. Instead of:

    example1 = 0; example2 = 0; example 3 = 1; example4 = 0;

Use:

example = {0, 0, 1, 0};

The values can be accessed as:

example[[1]], example[[2]] ....
  1. If most of the values of your list are zero, use SparseArray:

http://reference.wolfram.com/language/ref/SparseArray.html?q=SparseArray

POSTED BY: Sean Clarke
POSTED BY: Robbie Haffner
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract