acer

32348 Reputation

29 Badges

19 years, 329 days
Ontario, Canada

Social Networks and Content at Maplesoft.com

MaplePrimes Activity


These are replies submitted by acer

Maple has all these data structures, and they each have different properties. And you are doing the right thing, by asking yourself which is appropriate for the given task. The difficulty is that the answer depends on the aspects of the task (which you've also surmised, great) but that isn't currently documented so usefully.

Arrays, Vectors, and Matrices are mutable. You can change any value within them and Maple will not create a new object. This makes them very efficient. In contrast, a list is not mutable. Unfortunately, many years ago Maple was changed to allow one to change an entry of a list, as long as the list's length was not more than 100. For longer lists, trying that produces an error message. One can still use `subsop` to change an entry of a long list but doing so creates an entirely new object, which is expensive. If the original list was assigned to X, then X got the new list assigned to it automatically. This is the sort of behind-the-scenes user-friendly inefficiency that Maple really doesn't need.

There is also a table in Maple, which is another mutable object. Tables are growable and very useful. In fact, if you don't create your container objects in advance, doing something like X[12,g]:=blah will create X as a table automagically.

Closely related to mutability is the concept which I'll call identity. I won't call it uniquification because I don't want to get confused with duplicate-removal in set objects. You might call it "simpl'ing", if you have heard that Maple kernel term before. The basic idea is that some objects should only get represented once internally. It would be inefficient if Maple stored two copies of the list [1,2,3], even if each were separately assigned to different names x and y. For such objects, evalb(x=y) reports `true` when they are compared. In contrast, one can assign x:=Vector([1,2,3]) and y:=Vector([1,2,3]) and Maple will store two distinct objects. Here, evalb(x=y) will return false, even though they have the same entries. This is deliberate. It relates highly to mutability. One can consider that, since subsequent changes to the entries of Vector x won't affect Vector y, they should certainly be reported as distinct.

You mentioned growth. In Maple, a table is growable. A list is not. Matrices, Vectors, and Arrays were not growable when introduces in Maple 6, but they are in Maple 12 and onwards using their new round-bracket notation (see rtable_indexing and Maple12's programming news).

A Maple set has much the same properties as a list, in terms of mutability, growability, and identity. But the contents of a set get uniquified (duplicates removed) and re-ordered (by some scheme Maple deems appropriate).

A list of lists is another way to get a 2D structure, another way to get an indexable collection of indexable objects. But here the outer container as well as the inner parts are all not properly mutable, or growable, without inefficient object recreation and replacement. I very much doubt that this is right for your task.

There's more that could be written, but let's consider your task. If you are willing to create the storage for all 120 time instances right at the beginning, then you could use a 3x120 Matrix or a 2D 3x120 Array or a 1D Array of 120 3-Vectors, or even a table of 120 2-Vectors. And you can use a counter or a default value to denote whether they each have yet been initialized. If you don't want to allocate the storage for them all up front, then you could use a table or a 1D Array of Vectors.

Accessing individual Vectors is easy in all these cases, even if slightly different square-bracket syntax is used. But distinct from the action of entry read/write access is the action of referencing individual Vectors to be passed as arguments to some routine (which you presumably cannot control, since it is part of Maple proper). If you have to pass just a particular Vector then extracting it from say a Matrix will create a new 1D object each time. If you call foo(M[1..3,17]) then Maple has to create M[1..3,17] as a new object. This might method not scale well in performance, or your task might be simple enough that it doesn't matter.

Are you feeling overwhelmed yet?

acer

Maple has all these data structures, and they each have different properties. And you are doing the right thing, by asking yourself which is appropriate for the given task. The difficulty is that the answer depends on the aspects of the task (which you've also surmised, great) but that isn't currently documented so usefully.

Arrays, Vectors, and Matrices are mutable. You can change any value within them and Maple will not create a new object. This makes them very efficient. In contrast, a list is not mutable. Unfortunately, many years ago Maple was changed to allow one to change an entry of a list, as long as the list's length was not more than 100. For longer lists, trying that produces an error message. One can still use `subsop` to change an entry of a long list but doing so creates an entirely new object, which is expensive. If the original list was assigned to X, then X got the new list assigned to it automatically. This is the sort of behind-the-scenes user-friendly inefficiency that Maple really doesn't need.

There is also a table in Maple, which is another mutable object. Tables are growable and very useful. In fact, if you don't create your container objects in advance, doing something like X[12,g]:=blah will create X as a table automagically.

Closely related to mutability is the concept which I'll call identity. I won't call it uniquification because I don't want to get confused with duplicate-removal in set objects. You might call it "simpl'ing", if you have heard that Maple kernel term before. The basic idea is that some objects should only get represented once internally. It would be inefficient if Maple stored two copies of the list [1,2,3], even if each were separately assigned to different names x and y. For such objects, evalb(x=y) reports `true` when they are compared. In contrast, one can assign x:=Vector([1,2,3]) and y:=Vector([1,2,3]) and Maple will store two distinct objects. Here, evalb(x=y) will return false, even though they have the same entries. This is deliberate. It relates highly to mutability. One can consider that, since subsequent changes to the entries of Vector x won't affect Vector y, they should certainly be reported as distinct.

You mentioned growth. In Maple, a table is growable. A list is not. Matrices, Vectors, and Arrays were not growable when introduces in Maple 6, but they are in Maple 12 and onwards using their new round-bracket notation (see rtable_indexing and Maple12's programming news).

A Maple set has much the same properties as a list, in terms of mutability, growability, and identity. But the contents of a set get uniquified (duplicates removed) and re-ordered (by some scheme Maple deems appropriate).

A list of lists is another way to get a 2D structure, another way to get an indexable collection of indexable objects. But here the outer container as well as the inner parts are all not properly mutable, or growable, without inefficient object recreation and replacement. I very much doubt that this is right for your task.

There's more that could be written, but let's consider your task. If you are willing to create the storage for all 120 time instances right at the beginning, then you could use a 3x120 Matrix or a 2D 3x120 Array or a 1D Array of 120 3-Vectors, or even a table of 120 2-Vectors. And you can use a counter or a default value to denote whether they each have yet been initialized. If you don't want to allocate the storage for them all up front, then you could use a table or a 1D Array of Vectors.

Accessing individual Vectors is easy in all these cases, even if slightly different square-bracket syntax is used. But distinct from the action of entry read/write access is the action of referencing individual Vectors to be passed as arguments to some routine (which you presumably cannot control, since it is part of Maple proper). If you have to pass just a particular Vector then extracting it from say a Matrix will create a new 1D object each time. If you call foo(M[1..3,17]) then Maple has to create M[1..3,17] as a new object. This might method not scale well in performance, or your task might be simple enough that it doesn't matter.

Are you feeling overwhelmed yet?

acer

I smile that Robert was clearly writing this while I composed my own message below. They appear to have much in common.

acer

I smile that Robert was clearly writing this while I composed my own message below. They appear to have much in common.

acer

I think that it's because the author has been adding tags to those posts. (For a while, this also cause the post to show in Active Conversations, but that seems fixed now.)

acer

Yes, this was mentioned a while back. I expect that Will is looking into it.

acer

This doesn't seem to do what was requested. The OP appeared to want to be be able to pass an assignable symbol into the proc, but have assignment to that parameter be disabled within the proc. This suggestion does something different, by disallowing any assignable argument from being passed altogether. It's quite a different thing. There was no indication that the OP wanted a proc to which no assignable symbol could be passed.

If I am wrong here, I would say that the OP misrepresented the actual desire.

acer

This doesn't seem to do what was requested. The OP appeared to want to be be able to pass an assignable symbol into the proc, but have assignment to that parameter be disabled within the proc. This suggestion does something different, by disallowing any assignable argument from being passed altogether. It's quite a different thing. There was no indication that the OP wanted a proc to which no assignable symbol could be passed.

If I am wrong here, I would say that the OP misrepresented the actual desire.

acer

@John Fredsted This shows first since it has the most thumbs-up votes at this time.

@John Fredsted This shows first since it has the most thumbs-up votes at this time.

@roman_pearce thanks, Roman. Somehow I missed that. I'm still adjusting.

I'd like to point out that the posted code is not faster than LinearAlgebra:-Transpose when the datatype of the Matrix is float[8] or complex[8] (or sfloat or complex(sfloat) when Digits>15 or UseHardwareFloats=false, etc).

For those datatypes LinearAlgebra:-Transpose is very fast for storage=sparse (and no indexing function). At size 500x500 it is about 1000 times faster than the code here. The performance difference grows with the size, as well.

I realize that Roman's post was about datatype=anything Matrices. And that is an important case. But it is not strictly true that LinearAlgebra:-Transpose is not sparse (as was claimed). For the float datatypes, it is.

acer

When not logged in to Mapleprimes the "Recent" tab takes me to,

    http://www.mapleprimes.com/recent

When logged in, it takes me to,

    http://www.mapleprimes.com/recent/unread

The first of those two gives me the full set, while the second gives me only the ones I haven't read yet. But I would prefer the full view even when logged in. So I could make a bookmark for that one in my web browser.

acer

It is front page material.

acer

"When a true genius appears in this world, you may know him by this sign,
that the dunces are all in confederacy against him." - Swift

I look forward to finding out what mark Alec's qsort gets on the assignment. ;)

The essence of the mechanism by which mysort works looks the same as that of numsorter above (with a few differences like evalhf speed vs evalf flexibility, ~ vs map, etc, etc).

acer

First 458 459 460 461 462 463 464 Last Page 460 of 592