Why won't this work? Dynamic in a Select - wolfram-mathematica

Ok, I do this:
Select[Range[1, 20], # > Dynamic[q] &]
And then I create the slider:
Slider[Dynamic[q], {1, 20}]
And it'll always return an empty set! Why!
Update
The goal of this is to have the set change as I move the slider.

The key is to
remember that Dynamic does not control anything about evaluation directly. What it does is to create a spot on the screen which has evaluation properties.
If, for example, you were to evaluate the following in a fresh Mathematica
session...
b=5;
Dynamic[a=b];
b=6;
Print[a];
...then what will be printed? Instead of evaluating it immediately, think about
it before you try it. Hint...it's a trick question, but understanding the trick
will open your mind to exactly what Dynamic is doing.
The answer, which I will not reveal here (because you should really try it for
yourself!) can be explained by the fact that the Dynamic never did anything
because it never showed up onscreen. The semicolon inhibited the onscreen
appearance of Dynamic, and without appearing onscreen, the evaluation of Dynamic
accomplishes nothing.
More subtly, if you remove all of the semicolons, the Print[] statement (at
least on my machine) still remains unchanged, but now for a completely
different reason. That's because the onscreen placement of a Dynamic guarantees
that its contents will be evaluated, but not when they'll be evaluated. My
example sets up a race condition which, at least on my machine in v7, the
Shift+Enter evaluation wins.
To go back to your example,
Select[Range[1, 20], # > Dynamic[q] &]
This doesn't work the way you think it does because the Dynamic in this case
isn't evaluating to something which is displayed onscreen.
You could trivially demonstrate the result by doing...
Dynamic[Select[Range[1, 20], # > q &]]
but I'll assume you weren't just interested in displaying it on the screen, but
in setting some kind of side effect. Perhaps you were assigning Select to a variable.
There are two ways to make these side effects happen. One is to put them in the
second argument of Dynamic. For example...
findset[x_] := (myset = Select[Range[1, 20], # > x &])
Slider[Dynamic[q, (q=#; myset = findset[q])&], {1, 20}]
The second is to produce a Dynamic which does have an onscreen appearance, but one
which is not noticeable. For example,
Row[{
Slider[Dynamic[q], {1, 20}],
Dynamic[myset = Select[Range[1, 20], # > q &]; ""]
}]
In this case, the Dynamic actually is displaying. It displays right next to the
Slider. But you don't see it because what it's displaying is an empty string.
Nonetheless, it has all of the automatic updating properties that any Dynamic has.
For more information, you should read the beginning and advanced Dynamic tutorials
in the Mathematica documentation. You can also see my post on comp.soft-sys.math.mathematica here (which I partly reformulated for this response).

I think you want to leave "Dynamic" out of the select. This seems to work when I play with it:
In[20]:= x = 5
Out[20]= 5
In[21]:= Slider[Dynamic[x], {1, 20}]
Out[21]= \!\(\*
SliderBox[Dynamic[$CellContext`x], {1, 20}]\)
In[26]:= (*manually move the slider a bit to the right *)
In[23]:= x
Out[23]= 9.36
In[24]:= Select[Range[1, 20], # > x &]
Out[24]= {10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}
x = 2 (*slider moves left when I set this*)
Out[25]= 2
EDIT: Your actual question was, "why doesn't this work" instead of "how do I get this to work". Here's the problem:
In[12]:= q = 3
Out[12]= 3
In[13]:= (# > q) &[10]
Out[13]= True
In[14]:= (# > Dynamic[q]) &[10]
(* what you see on the screen looks like an evaluation that is held or something *)
Out[14] = 10 > 3
(* but the full form, which is conveniently what gets copied to the clipboard for
pasting into this answer, is actually this! *)
Out[14]= 10 > \!\(\*
DynamicBox[ToBoxes[$CellContext`q, StandardForm],
ImageSizeCache->{7., {1., 8.}}]\)
So if you say 'Dynamic[1]' you do get a '3' on the screen, but it's not really a '3' -- it's some kind of notebook element that actually displays a '3'.
The result of the comparison function is an expression like the above, which does not evaluate to True, so select does not accept any elements, so you get an empty set.

You want the entirety of the initial Select expression to be dynamic, because you want to update the selected subset whenever the value of q changes. You can do this by moving the Dynamic outside. Try this:
Slider[Dynamic[q], {1, 20}]
Dynamic[Select[Range[1, 20], # > q &]]

Related

Dynamic in Mathematica without duplication of code

I'm trying to create three separate graphs, this code will give you the idea:
f[t_] := Sin[10 t] + Cos[15 t];
Slider[Dynamic[dx], {0.01, 1}]
var = Dynamic[Fourier[Table[f[t], {t, 0, 100, dx}]]];
ListLinePlot[Abs[var]]
ListLinePlot[Re[var]]
ListLinePlot[Im[var]]
This won't work because var hasn't been evaluated an so ListLinePlot/Abs/Re/Im does not recognize it as a list of numbers. Dynamic has to wrap ListLinePlot.
Wrapping ListLinePlot and everything else with Dynamic works. But then I would have to calculate Fourier[Table[... once for each graph. Per principle, I don't want to have this duplication of code.
This is a way that avoids duplication of code but is not as semantic as my proposed not working example above, plus it puts all series in one graph and not in three separate:
Dynamic[
ListLinePlot[
(#[Fourier[
Table[f[t], {t, 0, 100, dx}]
]]) & /# {Abs,Re,Min}, DataRange -> {0, 100}
]
]
Hopefully you can see now what I am trying to achieve. Something like my first piece of code except it should work. How can I do that?
In most cases you only need to wrap Dynamic around the expression that needs to be recomputed. As you noticed, if you wrap Dynamic around the contents of var, it will not work because ListPlot will see a Dynamic head, not the list, when you pass var to it. What needs to be recomputed in this case is the complete ListPlot.
The correct solution is to use a delayed definition for var (i.e. := instead of =) and wrap Dynamic around ListPlot:
f[t_] := Sin[10 t] + Cos[15 t];
Slider[Dynamic[dx], {0.01, 1}]
var := Fourier[Table[f[t], {t, 0, 100, dx}]];
Dynamic#ListLinePlot[Abs[var]]
Dynamic#ListLinePlot[Re[var]]
Dynamic#ListLinePlot[Im[var]]
People often get confused with Dynamic because it sometimes shows up deep within in expression, e.g. in your Slider example. But there Dynamic has a different function: setting a value.
Generally, unless used to set a value, Dynamic always needs to be the outermost head in an expression. (There are some exceptions, notably when we're handling expressions that directly correspond to what is shown on screen, and are handled by the front end, such as graphics primitives: Slider[Dynamic[x], {0, 5}], Graphics[{Disk[], Dynamic#Disk[{x, 0}]}] will work.)
Dynamic affects only the way expressions are displayed in the front end, not how the kernel sees them. Here's an example:
x=1
arr = {Dynamic[x], 2, 3}
The Front End will display arr as {1, 2, 3}, but the kernel still sees it as {Dynamic[x], 2, 3}. So if we calculate Total[arr], the front end will display it as 1 + 5 but the kernel will see if as Dynamic[x] + 5. I hope this clarifies the situation a bit.
Note: I did not want to use Manipulate in this solution because the OP didn't use it either. Manipulate is just a high level convenience function and everything it does can be achieved with Dynamic and some controls such as Slider.
You probably want something like this:
f[t_] := Sin[10 t] + Cos[15 t]
DynamicModule[{var},
Manipulate[
var = Fourier[Table[f[t], {t, 0, 100, dx}]];
{ListLinePlot[Abs[var]],
ListLinePlot[Re[var]],
ListLinePlot[Im[var]]},
{dx, 0.01, 1}
]]
Untested:
f[t_] := Sin[10 t] + Cos[15 t];
Slider[Dynamic[dx], {0.01, 1}]
Dynamic[var = Fourier[Table[f[t], {t, 0, 100, dx}]]];
Dynamic[ListLinePlot[Abs[var]]]
Dynamic[ListLinePlot[Re[var]]]
Dynamic[ListLinePlot[Im[var]]]
I think this should calculate Fourier just once. From my understanding, the ListLinePlots should be triggered by the change of var after evaluating Fourier (note that the assignment of var is inside the Dynamic).

How to select sublists faster in Mathematica?

My question sounds more general, but I have a specific example. I have a list of data in form:
plotDataAll={{DateList1, integerValue1}, {DateList2, integerValue2}...}
The dates are sorted chronologically, that is plotDataAll[[2,1]] is a more recent time then plotDataAll[[1,1]].
I want to create plots of specific periods, 24h ago, 1 week ago, etc. For that I need just a portion of data. Here's how I got what I wanted:
mostRecentDate=Max[Map[AbsoluteTime, plotDataAll[[All,1]]]];
plotDataLast24h=Select[plotDataAll,AbsoluteTime[#[[1]]]>(mostRecentDate-86400.)&];
plotDataLastWeek=Select[plotDataAll,AbsoluteTime[#[[1]]]>(mostRecentDate-604800.)&];
plotDataLastMonth=Select[plotDataAll,AbsoluteTime[#[[1]]]>(mostRecentDate-2.592*^6)&];
plotDataLast6M=Select[plotDataAll,AbsoluteTime[#[[1]]]>(mostRecentDate-1.5552*^7)&];
Then I used DateListPlot to plot the data. This becomes slow if you need to do this for many sets of data.
What comes to my mind, if I could find the index of first element in list that satisfies the date condition, because it's chronologically sorted, the rest of them should satisfy the condition as well. So I would have:
plotDataLast24h=plotDataAll[[beginningIndexThatSatisfiesLast24h;;Length[plotDataAll]]
But how do I get the index of the first element that satisfies the condition?
If you have a faster way to do this, please share your answer. Also, if you have a simple, faster, but sub-optimal solution, that's fine too.
EDIT:
Time data is not in regular intervals.
If your data is at regular intervals you should be able to know how many elements constitute a day, week, etc. and use Part.
plotDataAll2[[knownIndex;;-1]]
or more specifically if the data was hourly:
plotDataAll2[[-25;;-1]]
would give you the last 24 hours. If the spacing is irregular then use Select or Pick. Date and time functions in Mma are horrendously slow unfortunately. If you are going to do a lot of date and time calculation better to do a conversion to AbsoluteTime just once and then work with that. You will also notice that your DateListPlots render much faster if you use AbsoluteTime.
plotDataAll2=plotDataAll;
plotDataAll2[[All,1]]=AbsoluteTime/#plotDataAll2[[All,1]];
mostRecentDate=plotDataAll2[[-1,1]]
On my computer Pick is about 3 times faster but there may be other improvements you can make to the code below:
selectInterval[data_, interval_] := (tmp = data[[-1, 1]] - interval;
Select[data, #[[1]] > tmp &])
pickInterval[data_, interval_] := (tmp = data[[-1, 1]] - interval;
Pick[data, Sign[data[[All, 1]] - tmp], 1])
So to find data within the last week:
Timing[selectInterval[plotDataAll2, 604800]]
Timing[pickInterval[plotDataAll2, 604800]]
The thing that you want to avoid is checking all the values in the data table. Since the data is sequential you can just start checking from the back and stop when you have found the correct index.
Schematically:
tab = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
i = j = Length#tab;
While[tab[[i]] > 5, --i];
tab[[i ;; j]]
-> {5, 6, 7, 8, 9}
sustitute > 5 for whatever you want to check for. I didn't have time to test this right now but in your case, e.g.,
maxDate=AbsoluteTime#plotDataAll[[-1,1]]; (* no need to find Max if data is sequential*)
i24h = iWeek = iMonth = iMax = Length#plotDataAll;
While[AbsoluteTime#plotDataAll[[i24h,1]] > maxDate-86400.,--i24h];
While[AbsoluteTime#plotDataAll[[iWeek,1]] > maxDate-604800.,--iWeek];
While[AbsoluteTime#plotDataAll[[iMonth,1]] > maxDate-2.592*^6.,--iMonth];
While[AbsoluteTime#plotDataAll[[i6Month,1]] > maxDate-1.5552*^7.,--i6Month];
Then, e.g.,
DateListPlot#plotDataAll[[i24h;;iMax]]
If you want to start somewhere in the middle of plotDataAll just use a While to first find the starting point and set iMax and maxDate apropriately.
For large data sets this may be one of the few instances where a loop construct is better than MMA's inbuilt functions. That, however, may be my own ignorance and if anyone here knows of a MMA inbuilt function that does this sort of "stop when match found" comparison better than While.
EDIT: Timing comparisons
I played around a bit with Mike's and my solution and compared it to the OP's method. Here is the toy code I used for each solution
tab = Range#1000000;
(* My solution *)
i = j = tab[[-1]];
While[tab[[i]] > j - 24, --i];
tab[[i ;; j]]
(* Mike's solution *)
tmp = tab[[-1]] - 24;
Pick[tab, Sign[tab[[All]] - tmp], 1]
(* Enedene's solution *)
j = tab[[-1]];
Select[tab, # > (j - 24) &]
Here are the results (OS X, MMA 8.0.4, Core2Duo 2.0GHz)
As you can see, Mike's solution has a definite advantage over enedene's solution but, as I surmised originally, the downside of using inbuilt functions like Pick is that they still perform a comparative check on all the element in a list which is highly superfluous in this instance. My solution has constant time due to the fact that no unneccessary checks are made.

Mathematica appending a Matrix

I have to solve a system of non-linear equations for a wide range of parameter space. I'm using FindRoot, which is sensitive to initial start point so I have to do it by hand and by trial and error and plotting, rather than putting the equations in a loop or in a table.
So what I want to do is create a database or a Matrix with a fixed number of columns but variable number of rows so I can keep appending it with new results as and when I solve for them.
Right now I've used something like:
{{{xx, yy}} = {x, y} /. FindRoot[{f1(x,y) == 0,f2(x,y)==0}, {x,a},{y,b}],
g(xx,yy)} >>> "Attempt1.txt"
Where I am solving for two variables and then storing the variables and also a function g(xx,yy) of the variables.
This seems to work for me but the result is not a Matrix any more but the data is stored as some text type thing.
Is there anyway I can get this to stay a matrix or a database where I keep adding rows to it each time I solve for FindRoot by hand? Again, I need to do FindRoot by hand because it is sensitive to the start points and I don't know the good start points without first plotting it.
Thanks a lot
Unless I'm not understanding what you're trying to do, this should work
results = {};
results = Append[Flatten[{{xx, yy} = {x, y} /. FindRoot[{f1(x,y) == 0,f2(x,y)==0}, {x,a},{y,b}],g(xx,yy)}],results];
Then every time you're tying to add a line to the matrix results by hand, you would just type
results = Append[Flatten[{{xx, yy} = {x, y} /. FindRoot[{f1(x,y) == 0,f2(x,y)==0}, {x,a},{y,b}],g(xx,yy)}],results];
By the way, to get around the problem of sensitivity to the initial a and b values, you could explore the parameter space in a loop, varying the parameters slowly and using the solution of x and y from the previous loop iteration for your new a and b values each time.
What you want to do can be achieved by using Read instead of Get. While Get reads the complete file in one run, Read can be adjusted to extract a single Expression, Byte, Number and many more. So what you should do is open your file and read expression after expression and pack it inside a list.
PutAppend[{{1, 2}, {3, 4}}, "tmp.mx"]
PutAppend[{{5, 6}, {7, 8}}, "tmp.mx"]
PutAppend[{{9, 23}, {11, 12}}, "tmp.mx"]
PutAppend[{{13, 14}, {15, 16}}, "tmp.mx"]
stream = OpenRead["tmp.mx"];
mat = ArrayPad[
NestWhileList[Read[stream, Expression] &,
stream = OpenRead["tmp.mx"], # =!= EndOfFile &], -1];
Close[stream];
And now you have in mat a list containing all lines. The ArrayPad, which cuts off one element at each end is necessary because the first element contains the output of the OpenRead and the last element contains EndOfFile. If you are not familiar with functional constructs like NestWhileList then you can put it in a loop as you like, since it is really just the iterated calls to Read
stream = OpenRead["tmp.mx"];
mat = {};
AppendTo[mat, Read[stream, Expression]];
AppendTo[mat, Read[stream, Expression]];
AppendTo[mat, Read[stream, Expression]];
AppendTo[mat, Read[stream, Expression]];
Close[stream];

How to make MatrixForm display row horizontally as a real row vector and not vertically as a column vector?

Is there a way to make MatrixForm display a row vector horizontally on the line and not vertically as it does for column vectors? As this confuses me sometimes. Do you think it will be hard to write wrapper around matrix form to adjust this behavior?
For example, here is a 2 by 2 matrix. The rows display the same as the columns. Both are shown vertical.
Question: Is it possible to make MatrixForm display row vectors laid out horizontally and not vertically?
Sorry if this was asked before, a quick search shows nothing.
thanks
update (1)
fyi, this is in Matlab, it prints rows horizontally and column vertically automatically, I was hoping for something like this. But I'll use suggestion by Heike below for now as it solves this at the cost of little extra typing.
update (2)
Using Hilderic solution is nice also, I always had hard time printing 3D matrix in a way I can read it. Here it is now using the {} trick
For both arrayname[[All,1]] and arrayname[[1,All]], Part delivers a vector, and MatrixForm has no way of determining which "orientation" it has. Accordingly, it always prints vectors as columns.
About the only thing you can do is provide your own output routine for row vectors, e.g., by wrapping it in an enclosing list, converting it back to a (single-row) matrix:
rowVector[a_List] := MatrixForm[{a}]
columnVector = MatrixForm (*for symmetry*)
It's still up to you to remember whether a vector came from a row or a column, though.
Or you could just cook up your own RowForm function, e.g.:
RowForm[(m_)?VectorQ] := Row[{"(",Row[m," "],
")"}, "\[MediumSpace]"];
Then
RowForm[twoRowsMatrix[[All,1]]]
looks kind of o.k.
Alternatively, if you really just care about displaying vectors, you could do:
twoRowsMatrix = {{a11, a12}, {a21, a22}};
TakeColumn[m_?MatrixQ, i_] := (Print[MatrixForm[#]]; #) &#m[[All, i]];
TakeRow[m_?MatrixQ, i_] := (Print[MatrixForm[{#}]]; #) &#m[[i]];
TakeColumn[twoRowsMatrix, 1]
TakeRow[twoRowsMatrix, 1]
If you don't care about the () part, then you can append with ,{}, wrap in curly brackets, and use TableForm or Grid instead:
vec = {x, y, z};
TableForm[{vec, {}}]
Grid[{vec, {}}]
When I get worried about this, I use {{a,b,c}} to specify a row of a,b,c (they can be any kind of list) and Transpose[{{a,b,c}}] to specify a column of a,b,c.
MatrixForm[a = RandomInteger[{0, 6}, {2, 2}]]
MatrixForm[b = RandomInteger[{0, 6}, {2, 2}]]
MatrixForm[c = RandomInteger[{0, 6}, {2, 2}]]
w = {a, b, c};
MatrixForm[w]
w = {{a, b, c}};
MatrixForm[w]
w = Transpose[{{a, b, c}}];
MatrixForm[w]

Mathematica "AppendTo" function problem

I'm a newbie in Mathematica and I'm having a major malfunction with adding columns to a data table. I'm running Mathematica 7 in Vista. I have spent a lot of time RFD before asking here.
I have a data table (mydata) with three columns and five rows. I'm trying to add two lists of five elements to the table (effectively adding two columns to the data table).
This works perfectly:
Table[AppendTo[mydata[[i]],myfirstlist[[i]]],{i,4}]
Printing out the table with: mydata // TableForm shows the added column.
However, when I try to add my second list
Table[AppendTo[mydata[[i]],mysecondlist[[i]]],{i,5}]
either Mathematica crashes(!) or I get a slew of Part::partw and Part::spec errors saying Part 5 does not exist.
However, after all the error messages (if Mathematica does not crash), again printing out the data table with: mydata // TableForm shows the data table with five columns just like I intended. All TableForm formatting options on the revised data table work fine.
Could anyone tell me what I'm doing wrong? Thanks in advance!
Let's try to clarify what the double transpose method consists of. I make no claims about the originality of the approach. My focus is on the clarity of exposition.
Let's begin with 5 lists. First we'll place three in a table. Then we'll add the final two.
food = {"bagels", "lox", "cream cheese", "coffee", "blueberries"};
mammals = {"fisher cat", "weasel", "skunk", "raccon", "squirrel"};
painters = {"Picasso", "Rembrandt", "Klee", "Rousseau", "Warhol"};
countries = {"Brazil", "Portugal", "Azores", "Guinea Bissau",
"Cape Verde"};
sports = {"golf", "badminton", "football", "tennis", "rugby"};
The first three lists--food, mammals, painters--become the elements of lists3. They are just lists, but TableForm displays them in a table as rows.
(lists3 = {food, mammals, painters}) // TableForm
mydata will be the name for lists3 transposed. Now the three lists appear as columns. That's what transposition does: columns and rows are switched.
(mydata = Transpose#lists3) // TableForm
This is where the problem actually begins. How can we add two additional columns (that is, the lists for countries and sports)? So let's work with the remaining two lists.
(lists2 = {countries, sports}) // TableForm
So we can Join Transpose[mydata] and lists2....
(lists5 = Join[Transpose[mydata], lists2]) // TableForm
[Alternatively, we might have Joined lists3 and lists2 because the second transposition, the transposition of mydata undoes the earlier transposition.
lists3 is just the transposition of mydata. (and vice-versa).]
In[]:= lists3 === Transpose[mydata]
Out[]:= True
Now we only need to Transpose the result to obtain the desired final table of five lists, each occupying its own column:
Transpose#lists5 // TableForm
I hope that helps shed some light on how to add two columns to a table. I find this way reasonably clear. You may find some other way clearer.
There are several things to cover here. First, the following code does not give me any errors, so there may be something else going on here. Perhaps you should post a full code block that produces the error.
mydata = Array[Subscript[{##}] &, {5, 3}];
myfirstlist = Range[1, 5];
mysecondlist = Range[6, 10];
Table[AppendTo[mydata[[i]], myfirstlist[[i]]], {i, 4}];
mydata // TableForm
Table[AppendTo[mydata[[i]], mysecondlist[[i]]], {i, 5}];
mydata // TableForm
Second, there is no purpose in using Table here, as you are modifying mydata directly. Table will use up memory pointlessly.
Third, there are better ways to accomplish this task.
See How to prepend a column and Inserting into a 2d list
I must retract my definitive statement that there are better ways. After changing Table to Do and running a few quick tests, this appears to be a competitive method for some data.
I am using Mathematica 7, so that does not appear to be the problem.
As mentioned before, there are better alternatives to adding columns to a list, and like Gareth and Mr.Wizard, I do not seem to be able to reproduce the problem on v. 7. But, I want to focus on the error itself, and see if we can correct it that way. When Mathematica produces the message Part::partw it spits out part of the offending list like
Range[1000][[1001]]
Part::partw: Part 1001 of
{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,
31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,<<950>>}
does not exist.
So, the question I ask is which list is giving me the problems? My best guess is it is mysecondlist, and I'd check Length # mysecondlist to see if it is actually 5 elements long.
Well, here's my two cents with what I believe is a very fast and IMHO most easily understandable construction.
First, some test arrays:
m = RandomInteger[100, {2000, 10000}];
l1 = RandomInteger[100, 2000];
l2 = RandomInteger[100, 2000];
{r, c} = Dimensions[m];
I increased the test array sizes somewhat to improve accuracy of the following timing measurements.
The method involves the invoking of the powers of Part ([[...]]), All and Span (;;).
Basically, I set up a new working matrix with the future dimensions of the data array after addition of the two columns, then add the original matrix using All and Span and add the additional columns with All only. I then copy back the scrap matrix to our original matrix, as the other methods also return the modified data matrix.
n = ConstantArray[0, {r, c} + {0, 2}];
n[[All, 1 ;; c]] = m;
n[[All, c + 1]] = l1;
n[[All, c + 2]] = l2;
m = n;
As for timing:
Mean[
Table[
First[
AbsoluteTiming[
n2 = ConstantArray[0, {r, c} + {0, 2}];
n2[[All, 1 ;; c]] = m;
n2[[All, c + 1]] = l1;
n2[[All, c + 2]] = l2;
m2 = n2;
]
],
{10}
]
]
0.1056061
(an average of 10 runs)
The other proposed method with Do (Mr.Wizard and the OP):
Mean[
Table[
n1 = m;
First[
AbsoluteTiming[
Do[AppendTo[n1[[i]], l1[[i]]], {i, 2000}];
Do[AppendTo[n1[[i]], l2[[i]]], {i, 2000}];
]
],
{10}
]
]
0.4898280
The result is the same:
In[9]:= n2 == n1
Out[9]= True
So, a conceptually easy and quick (5 times faster!) method.
I tried to reproduce this but failed. I'm running Mma 8 on Windows XP; it doesn't seem like the difference should matter, but who knows? I said, successively,
myData = {{1, 2, 3}, {2, 3, 4}, {8, 9, 10}, {1, 1, 1}, {2, 2, 2}}
myFirstList = {9, 9, 9, 9, 9}
mySecondList = {6, 6, 6, 6, 6}
Table[AppendTo[myData[[i]], myFirstList[[i]]], {i, 4}]
Table[AppendTo[myData[[i]], mySecondList[[i]]], {i, 5}]
myData // TableForm
and got (0) no crash, (1) no errors or warnings, and (2) the output I expected. (Note: I used 4 rather than 5 in the limit of the first set of appends, just like in your question, in case that was somehow provoking trouble.)
The Mma documentation claims that AppendTo[a,b] is always equivalent to a=Append[a,b], which suggests that it isn't modifying the list in-place. But I wonder whether maybe AppendTo sometimes does modify the list when it thinks it's safe to do so; then if it thinks it's safe and it isn't, there could be nasty consequences. Do the weird error messages and crashes still happen if you replace AppendTo with Append + ordinary assignment?

Resources