5

The accepted Answer to this similar Question can only be used one time, so it's not suitable for my problem.

I do high-dimensional calculations for which I need to make lists of variables, like so:

aa = Table[a[j], {j, 0, 12}];

This allows me to use the list as arguments for derivatives, like so:

D[p,{aa}]

But I need to be able to assign values to the variables in the list. The following was offered as a solution to this in a different Question:

MapThread[Set, {aa, RandomReal[1, 13]}];
Print[a[0], " ", a[1], " ", a[2]];

(* 0.211593 0.467789 0.572727 *)

If you use that command again, it tries to assign the value to the values instead of the variable.

MapThread[Set, {aa, RandomReal[1, 13]}];

(* Set::setraw: Cannot assign to raw object 0.21159339034304447`. *)

So how can I change I reassign those values?

Jerry Guern
  • 4,602
  • 18
  • 47
  • 1
    It's a pretty bad setup that you have, but if you insist on using it, here is one way: Hold[aa] /. OwnValues[aa] /. Hold[elems_List] :> With[{vals = RandomReal[1, 13]}, Set @@@ Thread[Hold[elems, vals], List]]. The complexity of this construction should be a convincing enough argument to avoid the setup like that. Things would totally simplify if you simply assign to a[i] in a loop. Not to mention that having one and the same variable stand for symbolic entity in differentiation and also be a variable storing a numerical value, doesn't sound like the best thing to do. – Leonid Shifrin Nov 15 '15 at 02:36
  • A slightly simpler and more elegant solution would be this: Hold[aa] /. OwnValues[aa] /. Hold[elems_List] :> Function[Null, Set[##], {HoldFirst, Listable}][elems,RandomReal[1, 13]]. – Leonid Shifrin Nov 15 '15 at 02:45
  • @LeonidShifrin If I knew a better setup, I'd use it. The key thing is, when I calculate gradients and Hessians, I want to be able to just use D[p,{aa}] instead of writing out a huge variable list. – Jerry Guern Nov 15 '15 at 03:13
  • Alternatively, if you insist on using a[j] as both a variable of integration and a variable to store numeric values, clear the values between the alternate assignments, i.e., Clear[a,aa]. – bill s Nov 15 '15 at 03:34
  • @bills I truly don't insist on anything. Is there some way I can a[j] as a variable of integration but then substitute numerical values, without having to write out /.{a[0]->value, a[1]->value, a[2]->value}? – Jerry Guern Nov 15 '15 at 03:41
  • @Karsten7. Because then aa would be a list of numbers instead of a list of variables that have values. – Jerry Guern Nov 15 '15 at 05:07
  • In that case one could use Evaluate[aa] = RandomReal[1, 13] and something like MapIndexed[(a[First@#2 - 1] = #1) &, RandomReal[1, 13]]. – Karsten7 Nov 15 '15 at 05:53
  • (a[# - 1] =.) & /@ Range[Length@aa]; can be used to Unset the individual indexed variables before re-setting them. – Karsten7 Nov 15 '15 at 05:57
  • Maybe using Thread[aa -> RandomReal[1, 13]] together with /. instead of setting and re-setting values makes thinks easier overall. – Karsten7 Nov 15 '15 at 06:23
  • 1
    Well, given your clarification: " Is there some way I can a[j] as a variable of integration but then substitute numerical values, without having to write out /.{a[0]->value, a[1]->value, a[2]->value}? ", all you have to do is this: do not assign the values on the top level, keeping a[i] symbolic. Instead, compute with numerical values as Block[{a}, Evaluate[aa] = RandomReal[1, 13]; your-code]. This way you localize the numerical substitutions to the body of the Block. – Leonid Shifrin Nov 15 '15 at 20:52

1 Answers1

1

It's hard to tell exactly what you want to do, so I will take a stab. Here are your variablesaa and I"ve made up a function p[aa] for concreteness.

aa = Table[a[j], {j, 5}];
p[aa_] := aa^Range[Length[aa]] + Reverse[aa]  Range[Length[aa]]^3;

This allows you to take derivatives as desired:

sol = D[p[aa], {aa}]

To now plug-in values for the a[j], you can do:

sol //. Thread[aa -> Range[5]]

which gives the derivative evaluated at the desired points.

bill s
  • 68,936
  • 4
  • 101
  • 191