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

I see, your example was deliberately contrived so as to simulate heavy memory use.

Following what John wrote, one might reasonably suspect a memory leak. I could imagine that as possible, during software float (not evalhf) callbacks from an external solver to Maple for each objective and constraint evaluation. I do not know how to get around that, except to rewrite the code similarly to what I suggested above, on a case by case basis and where possible.

As for upgrading your machine or memory, well, that will only help you so far. Whatever code is consuming memory will likely continue to do so, perhaps at the same rate, unless you can change it.

You might find this link useful, if you use a Microsoft OS.

acer

The bytes used and gc (and hence timing for the whole worksheet) is likely very high because of what goes on inside the objective function.

The objective function is this below, and it  is run for likely tens or hundreds of thousands of pairs of numeric values for parameters M1 and C1.

model_res:=proc(M1,C1)
  local res:
  res:=add((data[i,2]-
           subs({m=M1,c=C1},
                int(m*data[i,1]/(1+t+t^2)+c*t,t=0..5)))^2,
           i=1..RowDimension(data)):
  return(res):
end:

The data object is being set up a lowercase "a" array (lowercase "m" matrix) and is being passed to RowDimension which is a command for uppercase "M" Matrices. So probably a needless conversion occurs with each invocation. And it should be LinearAlgebra:-RowDimension and not rely upon LinearAlgebra being loaded at the top-level.

The most serious memory usage issue, I suspect, is that the symbolic integral is being done for each M1,C1 pair. And for each such given pair it is being done for each i. That integral can be done once, for generic C1,M1, and i, to provide a formula. Maple can evaluate such a formula efficiently.

If the objective function were also "fixed" to not rely on lexical scoping of 'data' then it might even run under fast evalhf mode. GlobalOptimization would try that, and handle it, automagically. But even if that were not so, evaluating a formula would be leaner than doing nested `int` calls.

> int(m*data[i,1]/(1+t+t^2)+c*t,t=0..5);
                                                                1/2
                      1/2                        1/2        11 3       25 c
   -1/9 m data[i, 1] 3    Pi + 2/3 m data[i, 1] 3    arctan(-------) + ----
                                                               3        2

I suggest rewriting `model_res` so that it accepts parameters m,c, and data. And have data be a datatype=float[8] Matrix. And have it use the formula for the integral rather than call `int` even once.

acer

And more generally, if one wishes to obtain P{X>x} for many other points x then integration is not necessary at each of them. One may instead compute a symbolic integral just once, to obtain a function of x, or simply use the CDF as Doug pointed out. And it may also be done for (as yet) unknown mean and variance.

> with( Statistics ):

> X := RandomVariable( Normal(m,s) ):

> PXms := int( PDF(X,t), t=x..infinity )
>   assuming m>0, m<infinity, s>0, s<infinity;
                                      1/2
                                     2    (-x + m)
                     PXms := 1/2 erf(-------------) + 1/2
                                          2 s

> Px := unapply(eval(PXms,[m=3,s=3]),x);
                                          1/2
                  Px := x -> 1/2 erf(1/6 2    (-x + 3)) + 1/2
 
> evalf(Px(0));
                                 0.8413447460

And, of course, this is the same as what one gets from the CDF,

> X := RandomVariable( Normal(m,s) ):

> 1-CDF(X,x);
                                        1/2
                                       2    (-x + m)
                         1/2 + 1/2 erf(-------------)
                                            2 s

acer

And more generally, if one wishes to obtain P{X>x} for many other points x then integration is not necessary at each of them. One may instead compute a symbolic integral just once, to obtain a function of x, or simply use the CDF as Doug pointed out. And it may also be done for (as yet) unknown mean and variance.

> with( Statistics ):

> X := RandomVariable( Normal(m,s) ):

> PXms := int( PDF(X,t), t=x..infinity )
>   assuming m>0, m<infinity, s>0, s<infinity;
                                      1/2
                                     2    (-x + m)
                     PXms := 1/2 erf(-------------) + 1/2
                                          2 s

> Px := unapply(eval(PXms,[m=3,s=3]),x);
                                          1/2
                  Px := x -> 1/2 erf(1/6 2    (-x + 3)) + 1/2
 
> evalf(Px(0));
                                 0.8413447460

And, of course, this is the same as what one gets from the CDF,

> X := RandomVariable( Normal(m,s) ):

> 1-CDF(X,x);
                                        1/2
                                       2    (-x + m)
                         1/2 + 1/2 erf(-------------)
                                            2 s

acer

That reply is much more useful and instructive for the student.

There could be more pedagogical difference between VectorCalculus:-ArcLength and Student:-VectorCalculus:-ArcLength.

acer

That reply is much more useful and instructive for the student.

There could be more pedagogical difference between VectorCalculus:-ArcLength and Student:-VectorCalculus:-ArcLength.

acer

I would probably do it like this,

> F:=proc(L)
>   subsop(1=NULL,L);
> end proc:
> L:=[x,y,z,d];
                               L := [x, y, z, d]
 
> L:= F(L);
                                L := [y, z, d]
 
> L:= F(L);
                                  L := [z, d]
 
> L:= F(L);
                                   L := [d]
 
> L:= F(L);
                                    L := []

That keeps it as simple as possible, is easiest to understand, and is less confusing.

Doing it the other way, to bring about the change in L as a so-called side-effect on the name, can cause confusion. In a sense, it's deliberately subverting any protection Maple may otherwise give you about not having your procedure overwrite the formal parameter. As a general rule, you may not wish to do that unless it's necessary. For your example, the above way to overwrite L (explicitly, by the call to the proc) is more straightforward.

Way back in the day, before Maple allowed multiple assignments, some routines would use side-effects as a mechanism to fake multiple assignment. For example,

> f := proc(a,b)
>   b := 2*a;
>   3*a;
> end proc:

> x:=11:

> x := f(x,'y'):
> x,y;
                                    33, 22
 
> x := f(x,'y'):
> x,y;
                                    99, 66

The above procedure changes both x and y. There was a time, long ago, when that was one of the easier ways to do get that effect. Nowadays, it can be done much more simply with a multiple assignment,

> restart:

> f := proc(a)
>  3*a, 2*a;
> end proc:

> x:=11:

> x,y := f(x);
                                x, y := 33, 22
 
> x,y := f(x);
                                x, y := 99, 66

When using side effects, one can get confused the by quotes, by either forgetting them or inserting them when they are not wanted.

> restart:

> f := proc(a,b)
>   b := 2*a;
>   3*a;
> end proc:

> x:=11:

> x := f(11,y): # it works once, without quotes...
> x,y;
                                    33, 22
 
> x := f(11,y): # and now, the second time...
Error, (in f) illegal use of a formal parameter

And, doing it another way,

> f := proc(x::evaln)
>   x := 2*eval(x);
> end proc:

> x:=11:

> f(x):
> x;
                                      22
 
> f('x'):
Error, illegal use of an object as a name

And also, documenting its use for others is more involved if it's implemented in these ways.

acer

I would probably do it like this,

> F:=proc(L)
>   subsop(1=NULL,L);
> end proc:
> L:=[x,y,z,d];
                               L := [x, y, z, d]
 
> L:= F(L);
                                L := [y, z, d]
 
> L:= F(L);
                                  L := [z, d]
 
> L:= F(L);
                                   L := [d]
 
> L:= F(L);
                                    L := []

That keeps it as simple as possible, is easiest to understand, and is less confusing.

Doing it the other way, to bring about the change in L as a so-called side-effect on the name, can cause confusion. In a sense, it's deliberately subverting any protection Maple may otherwise give you about not having your procedure overwrite the formal parameter. As a general rule, you may not wish to do that unless it's necessary. For your example, the above way to overwrite L (explicitly, by the call to the proc) is more straightforward.

Way back in the day, before Maple allowed multiple assignments, some routines would use side-effects as a mechanism to fake multiple assignment. For example,

> f := proc(a,b)
>   b := 2*a;
>   3*a;
> end proc:

> x:=11:

> x := f(x,'y'):
> x,y;
                                    33, 22
 
> x := f(x,'y'):
> x,y;
                                    99, 66

The above procedure changes both x and y. There was a time, long ago, when that was one of the easier ways to do get that effect. Nowadays, it can be done much more simply with a multiple assignment,

> restart:

> f := proc(a)
>  3*a, 2*a;
> end proc:

> x:=11:

> x,y := f(x);
                                x, y := 33, 22
 
> x,y := f(x);
                                x, y := 99, 66

When using side effects, one can get confused the by quotes, by either forgetting them or inserting them when they are not wanted.

> restart:

> f := proc(a,b)
>   b := 2*a;
>   3*a;
> end proc:

> x:=11:

> x := f(11,y): # it works once, without quotes...
> x,y;
                                    33, 22
 
> x := f(11,y): # and now, the second time...
Error, (in f) illegal use of a formal parameter

And, doing it another way,

> f := proc(x::evaln)
>   x := 2*eval(x);
> end proc:

> x:=11:

> f(x):
> x;
                                      22
 
> f('x'):
Error, illegal use of an object as a name

And also, documenting its use for others is more involved if it's implemented in these ways.

acer

I disagree with most of what you've written. And that's OK with me.

The bit that sticks out most is the claim that the syntax if A=B then... could get a quite different new set of meanings and that this might not break a lot of existing users' code and worksheets.

acer

I disagree with most of what you've written. And that's OK with me.

The bit that sticks out most is the claim that the syntax if A=B then... could get a quite different new set of meanings and that this might not break a lot of existing users' code and worksheets.

acer

On the one hand, there is the question of consistency. What you describe would mean that the behaviour of if A=B then... would differ much more dramatically according to the types of objects A and B. To me, that would be more inconsistent.

And what else might follow logically, to accompany this? If `=`, then why not `<`, to strive for at least some consistency? That too can be taken as "mathematical", just like Matrix arithmetic. Should these next two behave the same?

> restart:
> assume(a>b):
> if a>b then boo else foo end if;
Error, cannot determine if this expression is true or false: b < a
> if is(a>b) then boo else foo end if;
                                      boo

And, how about automatic normalization or simplification? The following is just as "mathematical" as Matrix arithmetic, no? Should these behave the same?

> if sin(x)^2+cos(x)^2 = 1 then boo else foo end if;
                                      foo
 
> if simplify(sin(x)^2+cos(x)^2) = 1 then boo else foo end if;
                                      boo

If mathematical simplification were also handled by default in if A=B then..., then there'd have to also be a syntax to deliberately avoid it.

And, doesn't it matter that the proposal is backwards incompatible and would break a lot of users' previously authored code? I'm pretty sure that the change couldn't be accommodated by an automatic code-updating script. There are just too many strange ways to get a Matrix into a symbol -- the script would have a terrible time trying to figure out which instances of if A=B then... should be changed to the new identity-check for Matrices.

To me, implementing the suggested alternative would introduce arbitrariness and inconsistency, would slow Maple down, and would constitute major code backwards incompatibility.

I don't think that Maple's current behaviour is so bad. But parts of it could be documented much more clearly and comprehensively.

acer

On the one hand, there is the question of consistency. What you describe would mean that the behaviour of if A=B then... would differ much more dramatically according to the types of objects A and B. To me, that would be more inconsistent.

And what else might follow logically, to accompany this? If `=`, then why not `<`, to strive for at least some consistency? That too can be taken as "mathematical", just like Matrix arithmetic. Should these next two behave the same?

> restart:
> assume(a>b):
> if a>b then boo else foo end if;
Error, cannot determine if this expression is true or false: b < a
> if is(a>b) then boo else foo end if;
                                      boo

And, how about automatic normalization or simplification? The following is just as "mathematical" as Matrix arithmetic, no? Should these behave the same?

> if sin(x)^2+cos(x)^2 = 1 then boo else foo end if;
                                      foo
 
> if simplify(sin(x)^2+cos(x)^2) = 1 then boo else foo end if;
                                      boo

If mathematical simplification were also handled by default in if A=B then..., then there'd have to also be a syntax to deliberately avoid it.

And, doesn't it matter that the proposal is backwards incompatible and would break a lot of users' previously authored code? I'm pretty sure that the change couldn't be accommodated by an automatic code-updating script. There are just too many strange ways to get a Matrix into a symbol -- the script would have a terrible time trying to figure out which instances of if A=B then... should be changed to the new identity-check for Matrices.

To me, implementing the suggested alternative would introduce arbitrariness and inconsistency, would slow Maple down, and would constitute major code backwards incompatibility.

I don't think that Maple's current behaviour is so bad. But parts of it could be documented much more clearly and comprehensively.

acer

According to the original post, he apparently wants,

> S(X);
                            proc() 'X'[1] end proc

Presumably, that really is what he is after.

That won't happen for the S above. But with a few uneval quotes like in subs(K=''Y'',eval(T)) it could. Then it might be a question of whether he'd rather define it as proc(Y::uneval)... or as proc(Y::evaln)...

acer

According to the original post, he apparently wants,

> S(X);
                            proc() 'X'[1] end proc

Presumably, that really is what he is after.

That won't happen for the S above. But with a few uneval quotes like in subs(K=''Y'',eval(T)) it could. Then it might be a question of whether he'd rather define it as proc(Y::uneval)... or as proc(Y::evaln)...

acer

An excellent choice.

acer

First 510 511 512 513 514 515 516 Last Page 512 of 591