Group Abstract Group Abstract

Message Boards Message Boards

0
|
3.8K Views
|
5 Replies
|
2 Total Likes
View groups...
Share
Share this post:

Track down what is happening in a code?

Posted 4 years ago

The situation is that I have a loop that generates a sequence of numbers. But the numbers are odd, likely wrong. But what really boggles the mind is if I remove the loop and just run the body of the loop once, it's all fine! This happens both inside a Do and inside a Table.

I tried to reduce the problem as much as possible into a working example but couldn't do much. Honestly I'm not hoping for someone to help me with my specific code but how to deal with these problems in general. If I had some way to know what the code is doing that would be nice. Trace and TracePrint generate so much output that it usually freezes and crashes before it's done. Anyway, here's the bit of code:

therm = 50;
iters = 100;
AllEs = Table[
  conf = Hotconf;
  Do[conf = MCStep[conf, b], {therm}];
  es = Table[conf = MCStep[conf, b]; CalcE[conf], {iters}];
  Total[es]/(iters*L*L)
  , {b, 0, 1, 0.1}]

Not shown here are the functions Hotconf, MCStep and CalcE. But they were thoroughly tested and work as intended. Hotconf and MCStep returns an LxL matrix, while CalcE returns a number. The output of the code above is something like {1., 1., 1., 1., 1., 1., 1., 0.6, 0.6, 1., 1.}. There is a randomness involved (this is monte carlo) but it's always very near one. So, what happens if you run the body of the loop separately? For example

conf = Hotconf;
Do[conf = MCStep[conf, 0.1], {50}];
es = Table[conf = MCStep[conf, 0.1]; CalcE[conf], {100}];
Total[es]/(100*L*L)

This is equivalent to b=0.1 from the previous code, the second number from the previous output. The output now is 0.0784 (it oscillates randomly but it's always below 0.1).

My gut tells me this is a problem of evaluation so I sprinkled "Evaluate" all over the place, but that made no difference.

I could really use some help. Not because of this code specifically, but I have a lot of work relying on thousands of Mathematica lines of code running complex algorithms. Now I just noticed how easy it is for something wrong to go under the radar with no error messages or anything, and it's quite scary! I'm glad I didn't publish anything based on that yet because I am having difficulty trusting the code now.

POSTED BY: Diego Floor
5 Replies
Posted 4 years ago

You are right, that's not quite what happened. The functions were altering b! The real problem is that I think like a C# programmer and that will get me in trouble working with Mathematica every now and then. The way I work, functions communicate with the outside environment through arguments and return values only because I avoid global variables. I avoid them exactly because of this kind of situation. It's hard to predict when variables will clash when the code starts getting complex.

POSTED BY: Diego Floor

It is fine, you just need to manage scope (i.e. namespace) using constructs like Block, Module, DynamicModule, or use Begin/End to manage contexts... slightly more verbose, but nicely explicit. "side effects" happen in all languages if you are not careful about your scoping. I work in JavaScript a lot lately which auto-scopes all variables in a function definition and separately auto-scopes all variables in separate files. It is maddening to me, but it is to save people side effects, but makes some things quite awkward.

POSTED BY: Kyle Keane
Posted 4 years ago

Hi Diego,

Could you please explain what you mean by

You would think the Do loop would overwrite the previous value of b with its own numbers, right?

In your code sample, b is scoped within Table, so that is the value used in the Do irrespective of the value of b in the outer scope. e.g.

b = 1234
Table[Do[Print[b], {2}], {b, 1, 4}]
b
(* 1234 *}
POSTED BY: Rohit Namjoshi
Posted 4 years ago

Today I got back to this problem. No more inconsistencies.

What am I to make of this? I don't know if it makes me trust Mathematica more or less! Did I do something that fixed it? Was it some kind of memory thing that went away by closing and opening the program?

EDIT: Found it. The iteration variable 'b' was defined somewhere else in the code. You would think the Do loop would overwrite the previous value of b with its own numbers, right? that would make sense. But it does not. So instead of iterating over the specified range it was simply running using the same arbitrary value for b.

POSTED BY: Diego Floor

I understand the frustration of switching languages... oh I know the frustration all too well. You can always use Clear/ClearAll to ensure you have clean variables before running a chunk of code or use the scoping mechanics Block/Module or context management Begin/End I mentioned elsewhere in this thread. Wolfram Language does not do any of this for you. You can write your own functions that could behave as you expect if you want, but you might need to use HoldAll attributes.

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