Carl Love

Carl Love

28050 Reputation

25 Badges

12 years, 335 days
Himself
Wayland, Massachusetts, United States
My name was formerly Carl Devore.

MaplePrimes Activity


These are replies submitted by Carl Love

@tomleslie Please reread what I wrote very carefully. It's only three lines. You are completely misinterpretting it. I said that in most modern languages a line break is treated the same as a space. I did not say that in most modern languages a space is treated as multiplication. Indeed, the only serious (*) general-purpose languages that I can recall where line break and space are treated differently are Fortran, Basic, Cobol, and Python and its descendents. (I'm sure that I'm missing several. I used to use Foxpro / dBase a lot, but I can't recall how the space-vs-line-break issue is handled there.) And of course I mean syntactic uses, not uses where the character---line break or space---is in a string.

(*) There's a non-serious language called Whitespace. You can look it up on Wikipedia.

@tomleslie In Maple (and I think most moderm languages), a line break is parsed just liked a space. When code using your indentation style is copy-and-pasted as 2-D Input, there is a line break, hence a space, hence an implicit multiplication, between the procedure names and their following left parenthesis.

@annarita What version of Maple are you using? You seem to "know" about the colorscheme option, yet your version of Maple doesn't seem to support it. When I run your worksheet, my version of the command produces the plot without error.

@Christian Wolinski Your use of @ contributes to the simplicity of the code. However, the terminal punctuation definitely needs to be a comma, not a semicolon. Your version of Maple doesn't use initializers in variable declarations. The following two procedures are different:

proc() local x:= 1, y:= 2; end proc:

proc() local x:= 1; y:= 2 end proc:

In the first, y is explicitly declared local. With the second, is only implicitly declared local, with a warning message.

@vv Oh, your Answer is in Reply to YasH's Reply about Eigenvectors rather than being an answer to the OP's Question. It is confusing that you (or someone) classified it as an Answer.

@vv Has the posted code been changed? I can find no use of indices in either of the posted worksheets. I searched with the GUI's Find command (from the Edit menu). I searched both inside and outside of the Code Edit Regions.

@YasH Your test with randomize is very strong evidence that the variability of the order of the returned eigenvectors is not due to the code's use of some type of randomization. So, the variability must be due to some address-based storage issue, such as what's discussed about the indices command above. I use indices in nearly all of my programs where the order of the returned results doesn't matter because it's an extremely efficient command, so I'd guess that it's widely used in the library code also.

@vv Yes, indices are stored by some address scheme, and hence the order is session dependent. If you want the results of indices or entries to be returned in a consistent order, then use option indexorder:

indices(MyTable, indexorder);

and likewise for entries. The order will then be the same as if the indices (not the entries) were an ordinary Maple set.

@YasH That's a good question, and, yes, it's related. I don't know the answer, but it's not too difficult to figure out with a few experiments. For example, after a restart, do the four always come in the same order? If yes, that's a sign that random numbers are used in the algorithm. If no, that's a sign that the ordering is based on the addresses of certain objects, most likely vectors.

The idea that random numbers might be used in the algorithm can be further investigated by checking if the pre-determined sequence of random numbers changes after calling Eigenvectors.

@vv Vote up. My tests below show that a simple for-loop approach, taking the remainder at each step, is fastest, at least for word-sized integers.

In a post a few months ago, I showed that the divide-and-conquer approach was much faster than plain mul or a linear for-loop for plain multiplication. Apparently, plain mul uses a linear simple-loop approach. This probably prevents the use of the much faster FFT-based multiplication algorithm (which is only used when both factors are supra-word-length integers).

Taking the remaindering into account, the divide-and-conquer approach is still much faster than mul, but it doesn't beat the simple for loop. ModMul.mw

restart:


#Divide-and-conquer multiplication; no mod
DandCMul:= proc(X)
local n:= nops(X), h;
     if n < 4 then `*`(X[])
     else
          h:= iquo(n,2);
          thisproc(X[..h])*thisproc(X[h+1..])
     end if
end proc:


#Divide-and-conquer and do mod at each step
DandCModMul:= proc(X, p)
local n:= nops(X), h, r;
     if n < 4 then r:= `*`(X[])
     else
          h:= iquo(n,2);
          r:= thisproc(X[..h],p)*thisproc(X[h+1..],p)
     end if;
     irem(r,p)
end proc:
 


#This should be similiar to `fold` but a little faster and less garbage.
LinearModMul:= proc(X, p)
local x, r:= 1;
     for x in X do r:= irem(r*x, p) end do
end proc:
 

 

Test with word-length integers and modulus.

 

R:= rand(1..2^64):
L:= ['R()'$2^17]:

p:= nextprime(R()):


gc4:= proc() to 4 do gc() od end proc:


gc4(): r1:= CodeTools:-Usage(irem(mul(x, x= L), p)):

memory used=62.57GiB, alloc change=23.49MiB, cpu time=68.28s, real time=62.95s, gc time=49.62s

gc4(): r2:= CodeTools:-Usage(DandCModMul(L,p)):

memory used=64.66MiB, alloc change=0 bytes, cpu time=594.00ms, real time=607.00ms, gc time=93.75ms

gc4(): r3:= CodeTools:-Usage(LinearModMul(L, p)):

memory used=15.52MiB, alloc change=0 bytes, cpu time=250.00ms, real time=202.00ms, gc time=109.38ms

gc4(): r4:= CodeTools:-Usage(irem(DandCMul(L),p)):

memory used=86.11MiB, alloc change=0 bytes, cpu time=641.00ms, real time=636.00ms, gc time=93.75ms

evalb~([seq](r1=r||k, k= 2..4));

[true, true, true]

 

 


Download ModMul.mw

@vv Yes, my tests show that you are correct about this.

@taro The semicolon at the end of the added line needs to be a comma, and the procedure needs to be surrounded by parentheses:

Change this:

numer_expand := a->expand(numer(a))/denom(a);

to this:

numer_expand := (a->expand(numer(a))/denom(a)),

@sigl1982 Presumably your original code had some condition by which it would decide when it was time to stop going to Step8, or else it'd be an infinite loop. Since you didn't show that condition, I just made up the name condition0 for it. It's not the same as continue or not continue.

@sigl1982 A simple control variable (I called it continue below) should do it:

while condition0 do
      #Set up parameters.
      continue:= true;
      while condition and continue do
          for s in S while continue do
              #  do anything
              if condition2 then   
                 #  do anything
                 if condition3 then
                       #  do anything
                       continue:= false;   
                 end if;
              end if;  
          end do;    
      end do;
end do;

Please explain in more detail how you can do it manually. Maybe I'd be able to use that info to figure out how to do it with Maple.

First 378 379 380 381 382 383 384 Last Page 380 of 709