Message Boards Message Boards

0
|
3120 Views
|
6 Replies
|
5 Total Likes
View groups...
Share
Share this post:

Avoid conflict between a local variable in the definition of two functions?

Anonymous User
Anonymous User
Posted 7 years ago

(Sorry for the non-descriptive title, but I'm brand new to Mathematica, and the only way I can show the issue is with an example.)

Attached is a Notebook demonstrating the issue, and here's a link to the same: https://drive.google.com/open?id=0Bzxpw7yVqcD3NHpJcVgtXzNEcDg

Here's copy/paste of the that Notebook's contents:

Definitions

myFunction[a_] := E^(-a^2)

myPlot[b_] := Plot[b[c], {c, -5, +5}]

I intend these two functions to produce identical results:

myTransformA[d_] := FourierTransform[myFunction[e], e, d]

myTransformB[d_] := FourierTransform[myFunction[c], c, d]

Tests

myPlot[myFunction]

myTransformA[x]

myTransformB[x]

myPlot[myTransformA]

I'm expecting the same results from this next line, but instead I get an error:

myPlot[myTransformB]

I infer that the error is due to some conflict between the "c" in the definition of "myPlot" and the "c" in the definition of "myTransformB". But I don't don't understand why the dual-use of "c" creates any conflict. In each of the definitions, isn't the use of "c" local to the definition? Why does it affect what's happening outside the definition? (I'm thinking of local variables in other languages like LISP and C++, but I must be making the wrong conclusion.)
Attachments:
POSTED BY: Anonymous User
6 Replies

I think that those were basic design decision that were made at the very early stages of the prehistory of Mathematica, three decades ago. Some functions protected their internal variables:

x = 1;
Plot[x^2, {x, 0, 1}]

and some others didn't:

x = 1;
D[x^2, x]

I am so used to how it works that I can't quite foresee the ramifications of doing otherwise. It is easier for a user to protect an unprotected variable when needed, than undoing a built-in protection. Perhaps some expert can comment?

POSTED BY: Gianluca Gorni

You define operators myPlot,myTransformB, which internally involve iterator variables, and then make a composition of them, which is tricky. When you call myPlot[myTransformB] there is a clash between the variable c in FourierTransform (which is somehow an integration variable) and the variable c in Plot. During the evaluation I suspect an occurrence of something meaningless like

FourierTransform[E^(-(-5.)^2), -5.`, -5.`]

that triggers a numeric integration where the integration variable is a number. Someone more expert can comment on this?

A simpler clash of variables happens if you evaluate Plot[D[x^2, x], {x, 0, 1}] for example.

Your fix localizes one of the two variables, and this is appropriate in this situation.

As to why the localization of the variables in FourierTransform is not built-in, I don't know for sure. Maybe what you are doing was not foreseen as the typical basic use for FourierTransform.

POSTED BY: Gianluca Gorni
Anonymous User
Anonymous User
Posted 7 years ago

Thanks. In my attempts to use debugging functions, I did see something like the code you wrote as an example of how it went wrong.

I'm too new at Mathematica to be sure of my opinion, but it seems to me it would be better if the program automatically added Module's functionality to D, Integrate, FourierTransform, and similar function-operators. Because in math outside Mathematica, "D[x^2, x]" has a definite meaning -- it means 2x -- and nothing going on outside that expression can change that expression's meaning.

POSTED BY: Anonymous User

What result would you expect from the brief dust-up below?

x = 5;
D[x^2, x]

(* During evaluation of In[89]:= General::ivar: 5 is not a valid variable. *)

(* Out[90]= D[25, 5] *)

No magic of localizing variables is going to salvage this. It's user error, or is some cases what the user intended, but regardless it is definitely as designed.

There are gray areas to all this. For example, antiderivatives (aka indefinite integrals) will have exactly the same issue as derivatives. But definite integrals do not. Should the variable of integration be scoped for definite integrals? What if one does Integrate[f[x], {x,0,x}]? (Sounds contrived? I have received an endless slew of bug reports arising from just that scenario. I believe most are fixed.)

FourierTransform is to some extent based on Integrate. Should it scope locally, given that Integrate does not? (Answer: I'm not certain, other than to say I don't foresee this changing.)

In contrast, NIntegrate does scope its variable of integration, sort of, to the extent that the HoldAll attribute prevents "premature evaluation" and allows the innards to do localized substitution. But it does not face a situation where the bounds of integration might not evaluate to numbers, let alone might evaluate to something depending on the integration variable. Well, they can do all that, but then it will issue an error and fail.

POSTED BY: Daniel Lichtblau
Anonymous User
Anonymous User
Posted 7 years ago

What result would you expect from the brief dust-up below?

x = 5;
D[x^2, x]

(* During evaluation of In[89]:= General::ivar: 5 is not a valid variable. *)

(* Out[90]= D[25, 5] *)

I'd naively expect it give this result:

In[1]:= x = 5

Out[1]= 5

In[2]:= Module[{x}, D[x^2, x]]

Out[2]= 2 x$811

Despite my earlier, wording, my concern isn't so much that Mathematica's design has a flaw; my concern is that Mathematica's design in this respect offers some flexibility that's over my head, and I'm trying to grasp why this design-decision was made, so that I can better utilize this aspect of Mathematica. I don't expect Wolfram to alter their design because of comments; I'm just trying to get oriented. I'm coming to Mathematica as a LISP programmer, and I've also programmed (in Java) my own LISP interpreter with a complete kernel. When Mathematica works similar to LISP, it makes sense to me; when Mathematica does something different from LISP, I wonder what benefits are there to Mathematica's way. Of course LISP doesn't include primitives for FourierTransform, but if I were to make a LISP that did (I'm not planning to), I'd instinctively implement default lexical scoping like I naively expected here.

Thanks for your valuable insight and clarification.

POSTED BY: Anonymous User
Anonymous User
Anonymous User
Posted 7 years ago

I found a fix:

myTransformB[d_] := Module[{c}, FourierTransform[myFunction[c], c, d]]

Why is the "Module" functionality not implicit in the "FourierTransform" operator? Are there other work-arounds I should consider, as I try to learn the Mathematica system? This seems to me to be a flaw in Mathematica. If it's actually feature, please enlighten me?

POSTED BY: Anonymous User
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