0
|
7338 Views
|
17 Replies
|
1 Total Likes
View groups...
Share

# Why does Part[list, n] work in one place, but not work consequently?

Posted 10 years ago
 As a new Mathematica user I am puzzled by the following, where the Part[list, n] function - or more accurately list[] - doesn't seem to have consequent results. For example, in MM 9 on Windows 7 if I say:f[x_, y_] := (x + y)^2curves = Expand[Thread[f[{1, 2, 3}, {x, y, z}]]]bounds = {{x, -10, 10}, {y, -10, 10}, {z, -10, 10}}Plot[curves[], {x, -10, 10}]this works, but Plot[curves[], bounds[]] returns an error even though bounds[] returns {x,-10,10}. Anbody know why this is?
17 Replies
Sort By:
Posted 10 years ago
 With is used to inject a value into an expression, then releases it. Handy for building up arguments inside HoldAll functions like Plot.plotCurves[n_] := With[{b = bounds[[n]]}, Plot[curves[[n]], b]]This version inserts both values, similar to Plot[Evaulate@curves[], Evaluate@bounds[] ]plotCurves[n_] := With[{c = curves[[n]], b = bounds[[n]]}, Plot[c, b]]plotCurves /@ Range
Posted 10 years ago
 To produce any plot, clearly the function to be plotted needs to be evaluated numerically at the different sampling points. This is why something like Plot[curves[], {x, -10, 10}] works, but note it needs to perform the part taking operation repeatedly for each numerical value of x. It hardly impacts this example, but there are cases where it is more efficient to wrap Evaluate around the first argument.Another place where evaluation semantics are relevant is the difference between the following two plots Plot[Table[x^k, {k, 2, 3}], {x, 4, 5}]Plot[Evaluate[Table[x^k, {k, 2, 3}]], {x, 4, 5}] In the second one, the curves are colored differently because the symbolic evaluation allows Plot to see it has been given a list.
Posted 10 years ago
 In other words: it is like it is. LOL! Thanks for the time and trouble guys.
Posted 10 years ago
 The first argument has Hold because of this:x = 2Plot[x + x^2, {x, 0, 2}]If it was first evaluated, it would just say Plot[6,{x,0,2}]  which would be constant.Also read: http://library.wolfram.com/conferences/devconf99/villegas/UnevaluatedExpressions/ (a long read but maybe worth it).The problem is very complicated as there are many similar/related commands: Defer, Unevaluated, Hold, HoldForm, HoldComplete, HoldAllComplete, HoldPattern, SequenceHold...
Posted 10 years ago
 Perhaps I should have emphasized this -- HoldAll only controls what happens with the arguments before Plot is called. What may take place inside of Plot is a different story, but does not contradict the HoldAll documentation in any way.There can be, of course, further questions about the design and implementation, for example why does Plot need to be HoldAll. Other people are better qualified to answer that, but I believe it makes some of the advanced visualization machinery much easier to implement.
Posted 10 years ago
 Thanks Karl - my problem is not with the head of the arguments, it's with the logic being followed. If HoldAll applies to ALL arguments, why is curves[] evaluated by Plot[ ] and not bounds[]? That's what seems illogical to me. I though that Plus might be something that needed less(?) evaluation than List and that's what's causing the problem? Does the list have to be flattend first before being evaluated and this is what's causing the 'problem'?
Posted 10 years ago
 It might be more clear to you what is happening if you wrapped FullForm around the results:FullForm[curves[]]FullForm[bounds[]]bounds[] has curly braces around it, indicating it is a list.  curves[] is just 3 terms added together, so it will have the head Plus (indicating addition).
Posted 10 years ago
Posted 10 years ago
 I looked up HoldAll in the documentation, where it's defined as: an attribute which specifies that all arguments to a function are to be maintained in an unevaluated form. Simple enough, but that doesn't explain why Plot[ ] then evaluates curves[] but not bounds[].
Posted 10 years ago
 Sorry Ilian, I think I'm expressing myself badly. Why does Plot[ ] evaluate the result of curves[] and not of bounds[]?
Posted 10 years ago
 Plot needs a valid plot range specification, which {x, -10, 10} is, but bounds[] --- in its unevaluated form --- is not.
Posted 10 years ago
 That makes sense, but in what way is the simple list {x, -10, 10} passed to Plot[ ] when the list is provided as a literal instead of the result of a function call? If both are unevaluated, wha'ts the difference between the literal and the result of bounds[]? Sorry about all the questions, but I'd lke to get a proper handle on how MM does things..
Posted 10 years ago
 HoldAll does affect all arguments. The evaluator passes the first argument to Plot unevaluated, which is then free to use it in any way, including evaluation at each sample point.
Posted 10 years ago
 OK - why does HoldAll only affect the second argument to Plot[ ] and not the first?
Posted 10 years ago
 This is an order of operations issue - you need to make sure that the second argument to Plot (bounds[]) is evaluated at the appropriate time. One way of doing this is to use the Evaluate function:http://reference.wolfram.com/mathematica/ref/Evaluate.htmlFor example, this should work:Plot[curves[], Evaluate@bounds[]]Note that the reason for this special behavior is that the Plot function has the attribute HoldAll:Attributes[Plot]which means that the arguments to Plot are maintained in an unevaluated form.EDIT: Oh well, Ilian already answered this.
Posted 10 years ago
 OK - I get it, that solves it. Thanks very much!
Posted 10 years ago
 That is because Plot is HoldAll, however one can do Plot[curves[], Evaluate[bounds[]]]