acer

32405 Reputation

29 Badges

19 years, 345 days
Ontario, Canada

Social Networks and Content at Maplesoft.com

MaplePrimes Activity


These are replies submitted by acer

I'm not sure what you mean by "realtime memory usage".

I have, in the past, suggested the ability to clear the memory of a large rtable immediately, under certain safe circumstances.

Firstly, notice that (as Joe's already correctly pointed out) `gc` frees memory in Maple's own self-allocated pool, and doesn't free it back to the operating system. Only `restart` frees memory back to the OS (and only in a few of the last major releases of Maple). But let's stay focused -- freeing the memory back to Maple's pool does allow it to be re-used by Maple and so avoids some increased overall memory allocation. Great.

But just when exactly, can garbage collection (aka "gc") of some allocated piece X occur? It can occur only when the kernel is in a safe state, not buried deep inside some builtin function. It can occur only when there are no existing references to X. And maybe a few more things.

Now, suppose that I am inside a proc of my own authoring. And I've finished with a huge float[8] Matrix. And I wanted to gc its memory after unassigning whatever name I'd assigned it to. And I know that there are no other references to X, because I just created it myself right here in my simple proc which doesn't call any other Library/builtin/other routines at all. For sure, X is collectible. I call gc() and no memory management sweep occurs. (That's testable because creating my new Matrix causes allocation to increase, not reusing X.) So I insert a few silly irrelevant assignments into my proc's code, just to clear %, %%, and %%% from any accidental and forgotten reference to X. And I run it again in fresh session. Same thing -- no immediate gc occurs. The answer is that gc is not yet ready to occur -- it only occurs as a function of bytes used, or other mysterious hidden cause. But I know that I can safely have memory X collected and memory-managed (cleared)! There's just no great way to bring it about.

An idea: what about altering gcfreq to be very low, using a little memory, then issuing a gc call, then restoring gcfreq? It might work as a means of forcing a gc sweep of memory to occur nearly right away. But it will have to take the time to sweep through it all. And that's not at all the same as just a lightning quick clearance of one particular now-unreferenced rtable's data's contiguous memory block.

This kind of thing is frustrating when using very large hardware datatype Matrices or Arrays, since such data objects can consume huge memory. And juggling their allocation may be necessary just to get a computation to be doable. Let's be frank -- this is Matlab's forte, since it was designed for this kind of thing. But Maple's memory management system was designed for juggling lots of pointers (DAGs) and small lists and names and polynomials (large, maybe, but built from many such smaller objects).

These are parts of the reasons why I try to harp on and on in this forum of the benefits of "inplace" operations on re-usable hardware datatype Matrices and Arrays. The current memory management system is not optimized for dealing with large, contiguous memory blocks, either automatically or via any simple user-tools.

There are tempting alternatives involving managing one's own large block memory, in the absence of `clear` or forced-now-gc. Mostly they are crazy schemes involving privately managed memory pools (separate from other Maple memory). You can often recognize their crazy authors, since they are the ones who sometimes claim it is not evil and can be a great solution to a difficult problem.

For example, suppose that you have a linear algebra routine with requires O(n^2) temporary float[8] workspace. You know that it will be called many times. Your first attempt at writing it will be a proc which recreates this workspace as a local, each time it's called. When it runs many times it will create a lot of those locals, as collectible garbage. That's a lot of time spent relying on a memory management system not designed to for such big double-precision blocks. So you rewrite your proc to instead accept the workspace as an argument. That way, the user can pass it in and re-use a workspace that gets created just once. (A similar effect can be attained by having your proc use a global or a module local for the workspace.) Brilliant. But now what if you need varying sizes? Well, you simply write another version, in which the proc tests to see if the re-usable workspace is big enough. Only when it is not already big enough will the proc replace it with the necessary larger object. And that larger object is then installed as the new re-usable workspace object. Fantastic. And maybe you love bells and whistles, so you throw in a utility command to unassign the name assigned that re-usable object, to allow it to be collected when you know you don't need it anymore in your unfinished Maple session. Fabulous! You've created your own private memory management scheme. Sure, it hides memory from the rest of Maple, is totally thread-unsafe, requires extra software maintence, etc, etc. But right now, it's fast. You be the judge.

Another alternative is to request better memory management by the system itself of large contiguous blocks (ie. what gets used for the data of double-precision Matrices and Arrays).

acer

There is at least one serious issue related to using `is` for comparison of exact numeric terms, esp. against floating-point numeric terms.

For example, there are problems related to remember tables (or Cache) and the caching of previously computed results. Using evalf directly can avoid some of the issues because evalf has a "special" sort of remember table which stores result not just by input-arguments but also by environmental Digits setting.

Take the following example. At a very high fixed precision, the correct answer is 'false'. Notice how `is` repeats the initial wrong answer of 'true' even when one raises Digits. The wrong answer is being spuriously remembered. (It's a bug I've previously reported.)

> restart:
> z:=3.1415926535897932384626433:
> is(Pi<z);

                              true
> Digits:=30:
> is(Pi<z);

                              true
> Digits:=300:
> is(Pi<z);
                              true

But now redo the query in a fresh session, with all system remember tables and Caches cleared.

> restart:
> Digits:=30:
> z:=3.1415926535897932384626433:
> is(Pi<z);
                             false

For interest, notice that it is not at all easy to get Maple to clear the offending remember tables, as far as I can see. I've trying using subsop(4=..) and `forget` on `is`, `is/internal`, and a few more deeper system routines. But I had no success in Maple 13 and 14. (I have a notion that in some earlier version I was able to succeed in clearing the offending remember table, possibly just with forget(`is/internal`) . But no longer.).

Hence I'd prefer to use `evalf` over `is` in similar situations.

...and now I am reminded that I want to finish writing a post on using (shake or) evalr for attaining specified accuracy.

acer

There is at least one serious issue related to using `is` for comparison of exact numeric terms, esp. against floating-point numeric terms.

For example, there are problems related to remember tables (or Cache) and the caching of previously computed results. Using evalf directly can avoid some of the issues because evalf has a "special" sort of remember table which stores result not just by input-arguments but also by environmental Digits setting.

Take the following example. At a very high fixed precision, the correct answer is 'false'. Notice how `is` repeats the initial wrong answer of 'true' even when one raises Digits. The wrong answer is being spuriously remembered. (It's a bug I've previously reported.)

> restart:
> z:=3.1415926535897932384626433:
> is(Pi<z);

                              true
> Digits:=30:
> is(Pi<z);

                              true
> Digits:=300:
> is(Pi<z);
                              true

But now redo the query in a fresh session, with all system remember tables and Caches cleared.

> restart:
> Digits:=30:
> z:=3.1415926535897932384626433:
> is(Pi<z);
                             false

For interest, notice that it is not at all easy to get Maple to clear the offending remember tables, as far as I can see. I've trying using subsop(4=..) and `forget` on `is`, `is/internal`, and a few more deeper system routines. But I had no success in Maple 13 and 14. (I have a notion that in some earlier version I was able to succeed in clearing the offending remember table, possibly just with forget(`is/internal`) . But no longer.).

Hence I'd prefer to use `evalf` over `is` in similar situations.

...and now I am reminded that I want to finish writing a post on using (shake or) evalr for attaining specified accuracy.

acer

Yes, the elementwise solution using tilde was in the earlier response as the last line of code.

acer

Yes, the elementwise solution using tilde was in the earlier response as the last line of code.

acer

Are you asking for a way to generate the objective and constraints, as equations, in a programmatic way -- given say general formulae for them?

Or are you asking for a way to generate the Matrix form, given an an objective and a varying number of constraints in a varying number of variables?

Or are you asking both such questions, or some other question?

acer

@hirnyk That is implied at the end of the longer Answer above, I think.

But the subtlety is that you are creating y after having loaded RealDomain (or even just its `^` exports). An issue suggested by the longer Answer is whether the following would work for the poster's (or any other) example,

with(RealDomain):

y := ... something complicated

plot(y, k=...);

If the above goes wrong and does not properly construct y then substitution of :-`^` by RealDomain:-`^` into y, after computing y without having loaded all or any part of RealDomain, may work.

@hirnyk That is implied at the end of the longer Answer above, I think.

But the subtlety is that you are creating y after having loaded RealDomain (or even just its `^` exports). An issue suggested by the longer Answer is whether the following would work for the poster's (or any other) example,

with(RealDomain):

y := ... something complicated

plot(y, k=...);

If the above goes wrong and does not properly construct y then substitution of :-`^` by RealDomain:-`^` into y, after computing y without having loaded all or any part of RealDomain, may work.

@Christopher2222 

Maybe you had sprintf in mind? (There is no syntax precisely like you describe, unless one fakes it with a wrapping call to StringTools:-CharacterMap or similar.)

> WhatDay:=proc(Year,Month,Day)
> StringTools:-ParseTime("%Y-%m-%d",
> sprintf("%d-%d-%d",Year,Month,Day)
> )['weekDayName'];
> end proc:

> WhatDay(2010,9,9);

"Thursday"

@Christopher2222 

Maybe you had sprintf in mind? (There is no syntax precisely like you describe, unless one fakes it with a wrapping call to StringTools:-CharacterMap or similar.)

> WhatDay:=proc(Year,Month,Day)
> StringTools:-ParseTime("%Y-%m-%d",
> sprintf("%d-%d-%d",Year,Month,Day)
> )['weekDayName'];
> end proc:

> WhatDay(2010,9,9);

"Thursday"

Maybe you had sprintf in mind?

> WhatDay:=proc(Year,Month,Day)
>     StringTools:-ParseTime("%Y-%m-%d",
>                            sprintf("%d-%d-%d",Year,Month,Day)
>                            )['weekDayName'];
> end proc:

> WhatDay(2010,9,9);

                           "Thursday"

acer

@Joe Riel 

When I first saw this topic the first thing that occurred to me was to redefine `assuming` in the equality case. But I discounted it since I was convinced that it would break some existing functionality. As we know, currently 'assuming' places temporary assumptions by replacing by local names with assumptions on them. So then 'is' works, but there is no evaluated substitution (and evalb checks don't ensue, and all kinds of other stuff doesn't come about, etc).

I suspect that there is some class of problem which would behave significantly differently if actual temporary assignment were done instead of merely temporary assumptions, when using such a new `assuming` in the equality case. But alas I have no significant example at hand of "breakage" -- just a gut feeling. ;) So one question is: would such examples (of now differing functioning) always be a good enhancement to `assuming`? Or could there be some undesirable breakage in some (rare?) current usage? Sure, this sounds like an all round improvement, but what about code that relies on the current behaviour? This is mostly why I considered that `using` may be a better choice of infix operator for such new functionality, instead of highjacking `assuming`.

And, of course, highjacking is quite the wrong term. Maybe it's a great fit.

It's a neat piece of syntactic sugar.

But perhaps `assigning` is not the best choice of word, as it doesn't hang as nicely as it might as an English statement. How about `using` instead? Eg,

plot(a*sin(x),x=0..b) &using a=-2,b=7;

I note that what you are proposing seems to function like the following, which already works and relies on the word  `use`.

use a=-2,b=7 in plot(a*sin(x),x=0..b); end use;

It would be nicer with (both 1D and 2D) parser support, to accept the infix operator without its being prefixed by `&`. And, as you mentioned if it had a high enough precedence to work even without round-bracket grouping of the substitution terms. Ie.

plot(a*sin(x),x=0..b) using a=-2,b=7;

which seems quite natural.

acer

It seems to work as expected in the Classic GUI of Maple 14.

It seems to work as expected in the Classic GUI of Maple 14.

First 451 452 453 454 455 456 457 Last Page 453 of 593