acer

32333 Reputation

29 Badges

19 years, 320 days
Ontario, Canada

Social Networks and Content at Maplesoft.com

MaplePrimes Activity


These are replies submitted by acer

It's unfortunate that the help query, issued in the Standard GUI,

  ?:-

takes one to the `use` help-page instead of the more appropriate `colondash` help-page.

And, naturally, both those pages should mention each other.

It's also unfortunate that the query ?uses takes one to the `procedure` help-page instead of to its own dedicated help-page (or to an expanded `use` help-page).

acer

There is a lot more that one can learn. But you don't need to learn it all before you can get going.

You could try the "Introductory Programming Guide". Look here, for some downloads.

acer

There is a lot more that one can learn. But you don't need to learn it all before you can get going.

You could try the "Introductory Programming Guide". Look here, for some downloads.

acer

You assign various values i[m], in a triple-loop where m has positive integer values. (This is the global name i)

The operator phi is defined to return expressions which contain those i[..] values. (This also is the global name i)

When you construct a top-level for..do loop using loop variable i, then running it wipes out those stored values i[m]. (This also is the global name i)

At that point, inside OVLM, calls to phi() are not returning what you expect. They are returning expressions containing things like 1[1], 1[2], etc.

The problem above isn't because `i` and `j` are also names of parameters of procedure OVLM.

If you replace the int() calls inside OVLM by Int(), then you can see it go wrong as follows. Unassign name i by issuing  i:='i': The call OVLM(1,1). Then assign i:=1: Then call OVLM(1,1) again. After that last call to OVLM, you can see how the output differs. In the last call, there are objects like this,

r[1]^( 2*1[1] + 1 )

So here's the deal. When you use a for..do loop, the loop indexing variable is not somehow "local" to only that loop. When you issue such a loop at the top-level, the loop variable is the global name. That's going to collide with any other previous use of that name (in your case, assigned values of i[m]).

If your loop variable (in your problematic loop) were ii instead of i then it would not be clobbering the "unique radial exponents for the 34 basis functions" stored as i[m]. And then the repeated calls to OVLM would work, since phi() would work as you intended. Eg,

for ii to 1 do
 JS := OVLM(1, 1);
end do

acer

You assign various values i[m], in a triple-loop where m has positive integer values. (This is the global name i)

The operator phi is defined to return expressions which contain those i[..] values. (This also is the global name i)

When you construct a top-level for..do loop using loop variable i, then running it wipes out those stored values i[m]. (This also is the global name i)

At that point, inside OVLM, calls to phi() are not returning what you expect. They are returning expressions containing things like 1[1], 1[2], etc.

The problem above isn't because `i` and `j` are also names of parameters of procedure OVLM.

If you replace the int() calls inside OVLM by Int(), then you can see it go wrong as follows. Unassign name i by issuing  i:='i': The call OVLM(1,1). Then assign i:=1: Then call OVLM(1,1) again. After that last call to OVLM, you can see how the output differs. In the last call, there are objects like this,

r[1]^( 2*1[1] + 1 )

So here's the deal. When you use a for..do loop, the loop indexing variable is not somehow "local" to only that loop. When you issue such a loop at the top-level, the loop variable is the global name. That's going to collide with any other previous use of that name (in your case, assigned values of i[m]).

If your loop variable (in your problematic loop) were ii instead of i then it would not be clobbering the "unique radial exponents for the 34 basis functions" stored as i[m]. And then the repeated calls to OVLM would work, since phi() would work as you intended. Eg,

for ii to 1 do
 JS := OVLM(1, 1);
end do

acer

I'm a little tired, but that reads a little odd to me.

The result of evalf(C) will contain symbols, since every entry in C is just an indexed name like corr[i,j]. So, I imagine that you wish to instantiate all those corr[i,j] at numeric values. Only then will the Cholesky factorization be fast, and the result be writable to float[8] datatype Matrix CD. So that's where the action of the GUI "component" must go, to give values to the corr[i,j]. They could be set either before C is created, or after, but they must be set prior to CD being calculated.

Now let's consider the number of variables. Your symmetric Matrix C has n*n/2 distinct indexed names in it, no? That's 500000 variables when n=1000 as you have it. It looks like they will all appear in Matrix B, since it's likely that no element of A is exactly zero. That doesn't match what you wrote about having 1000 variables. But no matter, because there is the more important issue to address: do you really want to have 1000 sliders to control?. And you mentioned 1000 images. But each slider need not get its own image (and the GUI would likely not support 1000 plot components well, if at all).

Maybe I've misunderstood. How many sliders do you want? How many plots? What should the sliders control? If the sliders control the values of the corr[i,j] variables then how, exactly (if it is not a 1-1 thing)?

As an aside, I was looking at Statistics:-CorrelationMatrix. Even for purely datatype=float[8] it doesn't treat Matrices efficiently. It breaks them up into Vectors, it seems. I got timings like this below, which are not great.

> for k from 1 to 10 do
> M := LinearAlgebra:-RandomMatrix(k*100,outputoptions=[datatype=float[8]]):
> print( time( Statistics:-CorrelationMatrix(M) ) );
> end do:
                                     0.391
 
                                     1.636
 
                                     4.310
 
                                     8.671
 
                                    15.534
 
                                    25.184
 
                                    38.933
 
                                    56.622
 
                                    76.200
 
                                    100.595

I would like to see if it can be improved, in a manner similar to this, for Matrix input (and no weights). I imagine that you would not want to have to wait 100 seconds for the CorrelationMatrix result, each time that B had some change in its values.

If only one or two columns of B changed, then the correlation Matrix could be updated more selectively and quickly. But I don't see how one can map simple changes to C into such simple changes in B, since there is a Cholesky factorization between them.

acer

I'm a little tired, but that reads a little odd to me.

The result of evalf(C) will contain symbols, since every entry in C is just an indexed name like corr[i,j]. So, I imagine that you wish to instantiate all those corr[i,j] at numeric values. Only then will the Cholesky factorization be fast, and the result be writable to float[8] datatype Matrix CD. So that's where the action of the GUI "component" must go, to give values to the corr[i,j]. They could be set either before C is created, or after, but they must be set prior to CD being calculated.

Now let's consider the number of variables. Your symmetric Matrix C has n*n/2 distinct indexed names in it, no? That's 500000 variables when n=1000 as you have it. It looks like they will all appear in Matrix B, since it's likely that no element of A is exactly zero. That doesn't match what you wrote about having 1000 variables. But no matter, because there is the more important issue to address: do you really want to have 1000 sliders to control?. And you mentioned 1000 images. But each slider need not get its own image (and the GUI would likely not support 1000 plot components well, if at all).

Maybe I've misunderstood. How many sliders do you want? How many plots? What should the sliders control? If the sliders control the values of the corr[i,j] variables then how, exactly (if it is not a 1-1 thing)?

As an aside, I was looking at Statistics:-CorrelationMatrix. Even for purely datatype=float[8] it doesn't treat Matrices efficiently. It breaks them up into Vectors, it seems. I got timings like this below, which are not great.

> for k from 1 to 10 do
> M := LinearAlgebra:-RandomMatrix(k*100,outputoptions=[datatype=float[8]]):
> print( time( Statistics:-CorrelationMatrix(M) ) );
> end do:
                                     0.391
 
                                     1.636
 
                                     4.310
 
                                     8.671
 
                                    15.534
 
                                    25.184
 
                                    38.933
 
                                    56.622
 
                                    76.200
 
                                    100.595

I would like to see if it can be improved, in a manner similar to this, for Matrix input (and no weights). I imagine that you would not want to have to wait 100 seconds for the CorrelationMatrix result, each time that B had some change in its values.

If only one or two columns of B changed, then the correlation Matrix could be updated more selectively and quickly. But I don't see how one can map simple changes to C into such simple changes in B, since there is a Cholesky factorization between them.

acer

And someone has incorporated those into Sage.  ;)

acer

And someone has incorporated those into Sage.  ;)

acer

For large numbers, better still might be to first split the number into an even number of equal-length "pieces" where each piece is an immediate integer. For example, one could compare the 1st and the 4th, and the 2nd and 3rd, if there were four pieces. That might reduce slowdown due to creation and memory management of big (gmp) integers.

Such slowdown for big integers makes `f` slow. Consider,

> f:=proc(n)
>     local a, k, len, m;
>     a:=n;
>     for len from length(a)-2 by -2 to 0 do
>         a:=iquo(a,10,'k');
>         a:=irem(a,10^len,'m');
>         if not k=m then return false fi
>         od;
>     true
> end:

> N := (10^10000+1)^2:
> f(N);
memory used=291.4MB, alloc=10.9MB, time=11.12
memory used=299.0MB, alloc=10.9MB, time=11.23
memory used=306.7MB, alloc=10.9MB, time=11.33
memory used=314.3MB, alloc=10.9MB, time=11.43
memory used=321.9MB, alloc=10.9MB, time=11.53
memory used=329.6MB, alloc=10.9MB, time=11.62
memory used=337.2MB, alloc=10.9MB, time=11.71
memory used=344.8MB, alloc=10.9MB, time=11.79
                                     true

> N := (10^100000+1)^2:
> f(N);
memory used=7.6MB, alloc=6.8MB, time=0.21
memory used=15.3MB, alloc=10.7MB, time=0.51
memory used=23.0MB, alloc=10.7MB, time=0.81
memory used=30.6MB, alloc=10.7MB, time=1.11
memory used=38.3MB, alloc=10.7MB, time=1.42
memory used=45.9MB, alloc=10.7MB, time=1.72
memory used=53.6MB, alloc=10.7MB, time=2.02
memory used=61.3MB, alloc=10.8MB, time=2.32
memory used=69.0MB, alloc=10.8MB, time=2.62
memory used=76.7MB, alloc=10.8MB, time=2.92
memory used=84.4MB, alloc=10.8MB, time=3.22
memory used=92.0MB, alloc=10.8MB, time=3.53
memory used=99.7MB, alloc=10.8MB, time=3.82
memory used=107.4MB, alloc=10.8MB, time=4.12
memory used=115.0MB, alloc=10.8MB, time=4.42
memory used=122.7MB, alloc=10.8MB, time=4.72
memory used=130.4MB, alloc=10.8MB, time=5.02
memory used=138.0MB, alloc=10.8MB, time=5.32
memory used=145.6MB, alloc=10.8MB, time=5.62
memory used=153.3MB, alloc=10.8MB, time=5.92
memory used=160.9MB, alloc=10.8MB, time=6.22
memory used=168.6MB, alloc=10.8MB, time=6.51
memory used=176.3MB, alloc=10.8MB, time=6.81
memory used=183.9MB, alloc=10.8MB, time=7.11
memory used=191.6MB, alloc=10.8MB, time=7.41
memory used=199.3MB, alloc=10.8MB, time=7.71
memory used=207.0MB, alloc=10.8MB, time=8.01
memory used=214.6MB, alloc=10.8MB, time=8.31
memory used=222.3MB, alloc=10.8MB, time=8.61
memory used=230.0MB, alloc=10.9MB, time=8.91
memory used=237.7MB, alloc=10.9MB, time=9.21
memory used=245.4MB, alloc=10.9MB, time=9.51
memory used=253.1MB, alloc=10.9MB, time=9.81
memory used=260.7MB, alloc=10.9MB, time=10.11
memory used=268.4MB, alloc=10.9MB, time=10.41
memory used=276.1MB, alloc=10.9MB, time=10.71
memory used=283.8MB, alloc=10.9MB, time=11.01
Interrupted

> g := proc(n)
>     local s;
>     s := ""||n;
>     evalb(s = StringTools:-Reverse(s));
> end:

> N := (10^100000+1)^2:
> g(N);
                                     true

> time( g(N) );
                                     0.055

> F(N); # Using `F` posted above.
                                     true
 
> time( F(N) );
                                     0.071

acer

For large numbers, better still might be to first split the number into an even number of equal-length "pieces" where each piece is an immediate integer. For example, one could compare the 1st and the 4th, and the 2nd and 3rd, if there were four pieces. That might reduce slowdown due to creation and memory management of big (gmp) integers.

Such slowdown for big integers makes `f` slow. Consider,

> f:=proc(n)
>     local a, k, len, m;
>     a:=n;
>     for len from length(a)-2 by -2 to 0 do
>         a:=iquo(a,10,'k');
>         a:=irem(a,10^len,'m');
>         if not k=m then return false fi
>         od;
>     true
> end:

> N := (10^10000+1)^2:
> f(N);
memory used=291.4MB, alloc=10.9MB, time=11.12
memory used=299.0MB, alloc=10.9MB, time=11.23
memory used=306.7MB, alloc=10.9MB, time=11.33
memory used=314.3MB, alloc=10.9MB, time=11.43
memory used=321.9MB, alloc=10.9MB, time=11.53
memory used=329.6MB, alloc=10.9MB, time=11.62
memory used=337.2MB, alloc=10.9MB, time=11.71
memory used=344.8MB, alloc=10.9MB, time=11.79
                                     true

> N := (10^100000+1)^2:
> f(N);
memory used=7.6MB, alloc=6.8MB, time=0.21
memory used=15.3MB, alloc=10.7MB, time=0.51
memory used=23.0MB, alloc=10.7MB, time=0.81
memory used=30.6MB, alloc=10.7MB, time=1.11
memory used=38.3MB, alloc=10.7MB, time=1.42
memory used=45.9MB, alloc=10.7MB, time=1.72
memory used=53.6MB, alloc=10.7MB, time=2.02
memory used=61.3MB, alloc=10.8MB, time=2.32
memory used=69.0MB, alloc=10.8MB, time=2.62
memory used=76.7MB, alloc=10.8MB, time=2.92
memory used=84.4MB, alloc=10.8MB, time=3.22
memory used=92.0MB, alloc=10.8MB, time=3.53
memory used=99.7MB, alloc=10.8MB, time=3.82
memory used=107.4MB, alloc=10.8MB, time=4.12
memory used=115.0MB, alloc=10.8MB, time=4.42
memory used=122.7MB, alloc=10.8MB, time=4.72
memory used=130.4MB, alloc=10.8MB, time=5.02
memory used=138.0MB, alloc=10.8MB, time=5.32
memory used=145.6MB, alloc=10.8MB, time=5.62
memory used=153.3MB, alloc=10.8MB, time=5.92
memory used=160.9MB, alloc=10.8MB, time=6.22
memory used=168.6MB, alloc=10.8MB, time=6.51
memory used=176.3MB, alloc=10.8MB, time=6.81
memory used=183.9MB, alloc=10.8MB, time=7.11
memory used=191.6MB, alloc=10.8MB, time=7.41
memory used=199.3MB, alloc=10.8MB, time=7.71
memory used=207.0MB, alloc=10.8MB, time=8.01
memory used=214.6MB, alloc=10.8MB, time=8.31
memory used=222.3MB, alloc=10.8MB, time=8.61
memory used=230.0MB, alloc=10.9MB, time=8.91
memory used=237.7MB, alloc=10.9MB, time=9.21
memory used=245.4MB, alloc=10.9MB, time=9.51
memory used=253.1MB, alloc=10.9MB, time=9.81
memory used=260.7MB, alloc=10.9MB, time=10.11
memory used=268.4MB, alloc=10.9MB, time=10.41
memory used=276.1MB, alloc=10.9MB, time=10.71
memory used=283.8MB, alloc=10.9MB, time=11.01
Interrupted

> g := proc(n)
>     local s;
>     s := ""||n;
>     evalb(s = StringTools:-Reverse(s));
> end:

> N := (10^100000+1)^2:
> g(N);
                                     true

> time( g(N) );
                                     0.055

> F(N); # Using `F` posted above.
                                     true
 
> time( F(N) );
                                     0.071

acer

Perhaps you could upload a short but representative example of your input to this site. (Use the green up-arrow in the bottom row of the editing toolbar, visible when one adds a comment.)

acer

Have a look at the help-pages for the Worksheet and XMLTools packages.

acer

The evalhf (fast, hardware floating-point) interpreter understands how to run procedures with calls to the `Array` constructor. It understands Matrix and rtable objects, but it doesn't understand  `Matrix` or `rtable` constructors calls.

> p := proc(x)
>   Array([[x^2, x], [1, x]]);
> end proc:

> evalhf( p(0.1) );
                [0.0100000000000000002    0.100000000000000006]
                [                                             ]
                [         1.              0.100000000000000006]
 
> rtable_options(%);
datatype = float[8], subtype = Array, storage = rectangular, order = Fortran_order

You can also use the eval command to escape back to regular Maple from within evalhf and so create Matrices (or other rtables, or other objects).

> p := proc(x)
>   Matrix([[x^2, x], [1, x]],datatype=float[8]);
> end proc:

> evalhf( p(0.1) );
Error, unable to evaluate expression to hardware floats: [[.1000000000e-1,
.100000000000000006], [1, .100000000000000006]]

> p := proc(x)
>   eval( Matrix([[x^2, x], [1, x]],datatype=float[8]) );
> end proc:

> evalhf( p(0.1) );
                [0.0100000000000000002    0.100000000000000006]
                [                                             ]
                [         1.              0.100000000000000006]
 
> rtable_options(%);
datatype = float[8], subtype = Matrix, storage = rectangular, order = Fortran_order

The performance penalty for the eval escape doesn't appear to be so bad.

acer

The evalhf (fast, hardware floating-point) interpreter understands how to run procedures with calls to the `Array` constructor. It understands Matrix and rtable objects, but it doesn't understand  `Matrix` or `rtable` constructors calls.

> p := proc(x)
>   Array([[x^2, x], [1, x]]);
> end proc:

> evalhf( p(0.1) );
                [0.0100000000000000002    0.100000000000000006]
                [                                             ]
                [         1.              0.100000000000000006]
 
> rtable_options(%);
datatype = float[8], subtype = Array, storage = rectangular, order = Fortran_order

You can also use the eval command to escape back to regular Maple from within evalhf and so create Matrices (or other rtables, or other objects).

> p := proc(x)
>   Matrix([[x^2, x], [1, x]],datatype=float[8]);
> end proc:

> evalhf( p(0.1) );
Error, unable to evaluate expression to hardware floats: [[.1000000000e-1,
.100000000000000006], [1, .100000000000000006]]

> p := proc(x)
>   eval( Matrix([[x^2, x], [1, x]],datatype=float[8]) );
> end proc:

> evalhf( p(0.1) );
                [0.0100000000000000002    0.100000000000000006]
                [                                             ]
                [         1.              0.100000000000000006]
 
> rtable_options(%);
datatype = float[8], subtype = Matrix, storage = rectangular, order = Fortran_order

The performance penalty for the eval escape doesn't appear to be so bad.

acer

First 503 504 505 506 507 508 509 Last Page 505 of 591