Message Boards Message Boards

Generating variables and assigning them values?


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

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;


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:

POSTED BY: Sean Clarke

Thanks Sean for the quick reply. I actually already use the list method to store values. My problem is that over the course of the next year or two, I will be greatly expanding my program. With this current method, I will have to redefine my lists with every addition or subtraction of nuclides.

Additionally, my code is set up to run and compare evaluations utilizing different constants:

 \[CapitalGamma]Co60[[1]]=100 (*Constant from ENDF library*)
 \[CapitalGamma]Co60[[2]]=98.8 (*Constant from JEFF 3.1 library*)
 \[Lambda]Co60[[1]]=0.53 (*Constant from ENDF library*)
 \[Lambda]Co60[[2]]=0.44 (*Constant from JEFF 3.1 library*)

And I am afraid that if I can't do this dynamically, my code may get a little messy utilizing lists with my array based method:


Except the length of each row of Co60Constants is going to be incredibly long and dependent on the other variables introduced into the system. With the "standard" way of creating and declaring variables, I will be editing hundreds of matrices with each addition of nuclides into my system. And if I change variables (i.e. instead of Co60 I use Sr90), I will have to redefine everything. Plus, it's going to be very difficult to keep track of which position in the list represents what constant. I'm not sure if what I've written here makes my problem more clear, I can expand on it if I need to.

Maybe the short answer (and the one you've already given) is that I can't generate variables. I guess I don't really want to accept how inefficient the process is going to be, but maybe that is the only way to do it.

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

Group Abstract Group Abstract