Message Boards Message Boards

0
|
2144 Views
|
12 Replies
|
5 Total Likes
View groups...
Share
Share this post:

Problem assigning to nested lists in nested For loops?

Posted 1 year ago

DM = { { {0, 0}, {0, 0} }, { {0, 0}, {0, 0} } }

Why does the following NOT work "correctly"

For[i1 = 1, i1 < 3, i1++,  For[i2 = 1, i2 < 3, i2++, For[i3 = 1, i3 < 3, i3++, \
       If[ i3 == 1,   DM[[i1]] [[i2]] [[13]] = A,    DM[[i1]] [[i2]] [[i3]] = B  ] ]]]

DM is {{{B, B}, {B, B}}, {{B, B}, {B, B}}}

while the following DOES work "correctly" (replace i3 by 1 or 2 in indexing DM)

For[i1 = 1, i1 < 3, i1++,  For[i2 = 1, i2 < 3, i2++, For[i3 = 1, i3 < 3, i3++, \
       If[ i3 == 1,  DM[[i1]] [[i2]] [[1]] = A,    DM[[i1]] [[i2]] [[2]] = B  ] ]]]

DM is {{{A, B}, {A, B}}, {{A, B}, {A, B}}}

I'm having trouble feeling comfortable with Mathematica because of things like this. Presumably, this makes "Mathematica sense," somehow.

POSTED BY: Steven Brawer
12 Replies
Posted 1 year ago

I see, so equations can written with special characters, and even using actual sub/superscripts, so the notebook (or whatever) almost is self-documenting.

I think I'll hold off on that for a while. Right now I'm documenting calculations with Latex text cells.

Thanks again. You've been very helpful.

POSTED BY: Steven Brawer
Posted 1 year ago

You can go a long way toward self-documenting, but better function and variable names go a long way toward self-documenting in any language, so I don't know that it's an inherent advantage of Mathematica. And you end up paying for the expressiveness of special characters in the tedium of repeatedly having to enter the special characters. The notebook interface itself is an inherent advantage, I suppose.

When I want to add additional documentation, I just use text cells adjacent to Input cells. I also organize my notebook with sections (which allows for groups of cells to be selected/evaluated as a group or even hidden as a group).

And this might be a bit abstruse right now, but it's easiest if you don't use sub/superscripts in names.

POSTED BY: Eric Rimbey
Posted 1 year ago

Not to beat a dead horse, but since you're new to Mathematica, maybe there are still some misconceptions. You referenced this documentation, https://reference.wolfram.com/language/ref/character/Continuation.html, but what is documented there is not the backslash. To use named characters in Mathematica, you typically use this syntax: \[NameOfCharacter]. So, the continuation character (which I actually didn't know had any syntactic meaning until now) is \[Continuation]. You can also get most special, named characters with the escape shortcut mechanism.

And to clarify my comment above, "you would only need a continuation character in a string", I was referring to the backslash. You can write this,

"abc\
def"

and the result will be just "abcdef".

POSTED BY: Eric Rimbey
Posted 1 year ago

If anyone is still interested, I have uploaded a very small notebook with these tests. (I believe there are NO typos.) I would very much like to know what I am doing wrong. (The Do loops approach, which is included, is obviously highly superior.)

==========================================

POSTED BY: Steven Brawer
Posted 1 year ago

I had originally assumed that the backslashes were some sort of copy/paste issue, but they are there, explicitly, in your notebook. I don't know why they aren't causing syntax errors, but they are definitely the cause of the "bad" behavior. Just remove the backslashes.

POSTED BY: Eric Rimbey
Posted 1 year ago

Agreed. They definitely are the problem.

Backslashes are supposed to be continuation lines. Sometimes they seem to be OK and sometimes not. It could be that they should only be used in the middle of actual expressions, rather than where I put them. Anyway I will definitely avoid them.

https://reference.wolfram.com/language/ref/character/Continuation.html

Thanks very much for your help.

BTW, since you asked, I am doing calculations for explicit coordinate transformations - such as, for example, might be used in General Relativity or Differential Geometry in general. (I'm taking a purely algebraic approach.) I know there are packages, but to get started I want to roll my own, to get familiar with the language and see what problems (such as this one) I could encounter. I am definitely not an expert either in the math or with Mathematica (obviously). I can do simple stuff by hand so I can check what I am doing.

POSTED BY: Steven Brawer
Posted 1 year ago

Ah, I see. No, you would only need a continuation character in a string. Generally, whitespace has no syntactic meaning in Mathematica expressions, so you can just use newlines to continue on the next line.

There are exceptions. Space(s) between two expressions can be interpreted as multiplication (but that's just syntactic sugar). Also, multiple outputs can be generated by separating expressions with newlines, but that style makes my eyes twitch.

POSTED BY: Eric Rimbey
Posted 1 year ago

Regarding Eric's comment, the "i3" is not 13 in my notebook (perhaps I copied incorrectly to my note here). To make sure, I replaced the "i3" index with "xx" as an index in my notebook and the result does not change. I agree that if it were "13", it would be a typo, but that is not the case.I have also switched notation to DM[[i1,i2,xx]] , as suggested, but no change.

I still have to understand the other two comments, which I will now proceed to do.

I have just this Friday started with Mathematica and I am sure there are many ways to solve this problem. (The nature of my mathematical problem is not relevant to this discussion.) This most obvious brute-force programming approach is (for me at this point) the simplest, and your comment does not seem to resolve the problem (though thank you for pointing out a possible typo). In any event, even though my code is not elegant (I tend to avoid elegance), presumably it should still work "correctly" (unless it IS working correctly and there is a subtlety in using Mathematica which I'm not aware of).

At this stage, the following is all I can think of

  1. I am using the notebook incorrectly,
  2. There is something fundamentally wrong with my code (assuming the i3 is not 13),
  3. There is a bug in the Mathematica-ARM compiler, or
  4. There is a bug in the ARM software somewhere (I am on an Apple silicon MacBook Pro).

Did you get what I called the correct result using the i3 index directly (not replacing with "1" and "2")? If so, it will be important to know what hardware you are using and which version of Mathematica and of OS? My Mathematica is 13.1.0.0, my MacOS is Monterey 12.6, up to date.

I have checked these results in a completely fresh Mathematica notebook, with different indices of the loops. Maybe I have a property switch thrown that should be unthrown, I don't know. I have occasionally encountered these kind of bugs in compilers years ago, but not recently.

POSTED BY: Steven Brawer
Posted 1 year ago

Okay, I'll be very explicit. I ran this code:

DM = {{{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}};
For[i1 = 1, i1 < 3, i1++,
  For[i2 = 1, i2 < 3, i2++,
   For[i3 = 1, i3 < 3, i3++,
    If[i3 == 1, DM[[i1]][[i2]][[i3]] = A, DM[[i1]][[i2]][[i3]] = B]]]];
DM

The result was {{{A, B}, {A, B}}, {{A, B}, {A, B}}}.

Then I ran this code:

DM = {{{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}};
For[i1 = 1, i1 < 3, i1++,
  For[i2 = 1, i2 < 3, i2++,
   For[i3 = 1, i3 < 3, i3++,
    If[i3 == 1, DM[[i1]][[i2]][[xx]] = A, DM[[i1]][[i2]][[xx]] = B]]]];
DM

The result was {{{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}} along with messages that xx is not a valid part specification.

I would be astonished if it mattered, but I'm running Mathematica 13.1.0.0 on a (non-silicon) MacBook Pro running Monterey 12.5.1

As for this

The nature of my mathematical problem is not relevant to this discussion

yes, I agree. Please don't send us the full domain description that you're working in. But surely you can describe the specific programming problem this code is intended to solve. Like, are you trying to create DM from scratch? If so, something like the ConstantArray suggestion from Sander would be better. Does DM come from some external source? Then it further depends on the semantics, but ReplacePart, MapIndexed, or even something like SubsetMap might be better. At the very least, the Do loop suggestion would be cleaner.

Of course, you may respond by reiterating that the

most obvious brute-force programming approach is (for me at this point) the simplest

and of course that is fine and natural. But why pick up a new language if you're not going to try to understand its strengths or at least become comfortable with its standard idioms? My hope is not just to help you get your code to work, my hope is that you'll learn better ways to program in Mathematica.

POSTED BY: Eric Rimbey
Posted 1 year ago

It's difficult to answer because the data you presented doesn't really make sense. In your first batch of nested For loops, you have an expression like this

DM[[i1]] [[i2]] [[13]]

and that 13 will cause index errors. I would have thought that that was your problem, but you reported that the result was that DM was set to {{{B, B}, {B, B}}, {{B, B}, {B, B}}}, but in fact, running the code with that 13 index produces a DM set to {{{0, B}, {0, B}}, {{0, B}, {0, B}}} (in addition to the index errors). So, I'm not sure whether your typo was the 13 or whether it was the {B, B}.

If you change the 13 to i3, then DM will be {{{A, B}, {A, B}}, {{A, B}, {A, B}}}, which seems to be what you want. Make of that what you will.

Having said all of that, it would be nice to know a bit more about the context here and what you're trying to achieve. It is unlikely that nesting three For loops is the best way to do this.

POSTED BY: Eric Rimbey

This is because you wrote 13 rather than i3.

A better way of coding this would be to use Do loop which can do multiple ones nested automatically:

DM = {{{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}};
Do[
 DM[[i1, i2, i3]] = If[i3 == 1, A, B]
 ,
 {i1, 1, 2},
 {i2, 1, 2},
 {i3, 1, 2}
 ]
DM

Also Part ( denoted with [[ and ]] ) can be done [[a]][[b]][[c]] or just [[a,b,c]] to simplify notation.

POSTED BY: Sander Huisman

It can also be done in other ways:

DM = {{{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}};
DM = MapIndexed[If[#2[[3]] == 1, A, B] &, DM, {3}];
DM

or just:

DM = ConstantArray[{A, B}, {2, 2}]
POSTED BY: Sander Huisman
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