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

@emendes 

If your order matters and you want to save repetitions, you can do this:

k:= 0:
A:= Vector():
for
... do
    
...
     r:= ...;
     k:= k+1;
     A(k):= r
end do;
A:= convert(A, list):

In the above, it's important that the k only be updated when you've found an r that you want to save.

I'm not 100% sure that Vector stretching works in Maple 14. If it doesn't, then use this table-based version, which is only very slightly slower:

k:= 0:
A:= table():
for
... do
    
...
     r:= ...;
     k:= k+1;
     A[k]:= r
end do;
A:= convert(A, list):

@tomleslie Why do you compare your final version against my first draft? Does that seem fair? My final version is

IndicesOfMatches:= proc(L::list)
local T, k;
     for  k to nops(L) do T[L[k]][k]:= () end do;
     [indices]~([entries(T, nolist)], nolist)
end proc:

Besides, it's already been established that the OP doesn't have consistent access to Classify because of use of Maple 14.

@emendes So you're starting with 2^20 ~ 1 million polynomials. After removing some elements, approximately how many will there be? I've seen Groebner basis computations choke up on 10 polynomials. I don't know much about Groebner, but I think that your computation is far from feasible.

The code

A:= NULL;
for
... do
     ...
     r:= ...;
     A:= A,r;
end do;

is called iterative appending, which has already been mentioned a few times in this thread. It is very inefficient when the sequence A is long. I think that it's the number-one cause of inefficient Maple code. There are several easy and efficient ways to rewrite this using tables or Vectors. The best way to use depends on two things: whether you care about the order and whether you care to save repetitions.

@Dr. Venkat Subramanian

I wonder where and how you got "the impression that shortcuts are just for typing convenience." That is completely untrue. Most shortcuts are coded completely separately from the commands that they are shortcuts for. It is worth learning the shortcuts for the simple reason that knowing them will make your thinking itself more efficient.

Most efficiency differences are due to one version being builtin kernel code and the other version being Maple library code. Here's are some comparisons that I know or can guess:

1. The matrix/vector constructor operators `<,>` and `<|>` are far more efficient than the commands Matrix and Vector. If you read through the bloated library code of the latter, you'll understand why. But if you need to add options such as datatype, then you need to use the spelled out versions.

2. There's no computational efficiency difference between -> and proc...end proc. However, I consider this the number one example of a shortcut that'll make your thinking more efficient.

3. `[]` and `{}` are more efficient than (a,b)-> [a,b], ()-> [args], (a,b)-> {a,b}, and ()-> {args} because the former are builtin.

4. (f@g)(x) is less efficient than f(g(x)). It was vv I think who some time in the last few months provided an example showing the efficiency difference.

5. When ~ is used as a replacement for map, I don't think that there's any difference. I'm not sure about this one.

6. When ~ is used as a replacement for zip, I think that ~ is more efficient because zip is library code.

7. () is ever so slightly more efficient than NULL because the latter requires one more evaluation to be processed. However, that extra evaluation is often syntactically required.

8. Generally, things that avoid the use of -> or proc are more efficient. So map2(op, 1, L) is more efficient than map(x-> op(1,x), L).

 

@emendes You can limit the amount of time used by a command with the timelimit command. For example, the following imposes a limit of 1 second:

try
     r:= timelimit(1, IndicesOfMatches(gb1))
catch "time expired":
     print("Time expired.");
     r:= 'r'
end try;

As far as I know, there is no equivalent for limiting memory usage. You can set a memory limit with kernelopts(datalimit= ...), but there is no effective way of trapping the error when that limit is exceeded. Indeed, the Maple session may crash.

It's not an issue of a "code of conduct" with the file extensions. The issue is that computers interpret the file extension and files get opened automatically in a certain way based on it. Opening your file with Maple as a worksheet doesn't really work.

@taro The cat isn't necessary. I only used it so that I didn't need to type none(), four times. However the backslashes are necessary to include quotation marks inside a string. Without the backslashes, the second quotation mark marks the end of the string.

@emendes I downloaded your example, and it runs fine, in under 0.2 sec. I don't know if you were trying to get further help with it.

It is not appropriate to use the file extension .mw for a file such as what you posted since it is not a Maple worksheet. The best extension is probably .txt.

@vv Ah, you intend to delete L. You didn't say that before. Yes, then I agree that your addressof trick could provide a benefit, if memory usage were an issue. The OP's currently posted example fits inside 38M.

@vv Oh, I have no doubt that your addressof technique gives valid results. What I don't understand is how it can provide a benefit, a memory savings. Can you provide an example showing that?

Again, please read the book section that I referenced. It's only a page, but it'll probably take several readings and some time to digest.

@emendes

The message "Exceeds limit of ..." simply means that the result is too long to show on your screen. The result has nonetheless still been computed. You should save it to a variable, ending the command with a colon to suppress the display. Then, if you must visually examine the results, do so a small piece at a time.

@emendes To set 1D input (aka Maple Input) as the default, go to menu Tools -> Options -> Display -> Input Display and select Maple Notation. Then go to tab Interface and at "Default format for new worksheets," select Worksheet. Then click Apply Globally, then open a new worksheet.

@vv Would you please provide an example where you think that this addressof trick provides some benefit? From my knowledge of how Maple stores things, I can't see how there'd be any benefit. The mapping of identical expressions to the same address happens in the automatic simplification of L, so (as far as I understand) the user never has access to the raw un-identified forms. See the section "The Simplification Table" of Appendix A of the Maple Programming Guide.

@Leocor Several unrelated comments:

1. Code that uses global variabes can't be threadsafe because Threads shares memory across the threads. Most complex Maple commands---regardless of the commonality of their usage---were written many years before Threads, and they use global variables (often environment variables such as Digits).

2. The errors produced by using unthreadsafe code with Threads are unpredictable. Sometimes you will just get a numerically wrong result rather than an error. A kernel crash is a also a common error in this situation. When you do have a kernel crash, there's no need to restart Maple, despite what the error message says. It's much faster to

  1. save your worksheet,
  2. then close your worksheet,
  3. then reopen your worksheet.

This is assuming that you have a normal setup where every worksheet gets a fresh kernel.

3. If you want to find a known-to-be-unique floating-point root of a real function over a real interval (finite or infinite), the command to use in the vast, vast majority of cases is fsolve, not solve or RealDomain:-solve. My opinion of RealDomain is that it only exists for pedagogical reasons for use in low-level courses such as precalculus and first-year calculus where (for strictly pedagogical reasons) one wants to avoid discussion of complex numbers. That pedagogy is flawed in my opinion: There are issues in real-variable calculus that can't be properly addressed without considering complex numbers. For example, Why does the Maclaurin series of arctangent have radius of convergence 1?

If you encounter a situation where fsolve doesn't seem to work (and there are plenty)please post it. It can often be made to work by adjusting Digits. If that doesn't work, there's a freely avaiable third-party package called DirectSearch that can be used.

4. Floating-point solutions which are known to be real for theoretical reasons often come with small imaginary parts (such, as you said, value + 0.0*I). This is due to round-off error in computations which don't have access to the knowledge that the solutions are necessarily real. These imaginary parts can be safely discarded by applying Re to them.

5. It's generally a bad idea efficiency-wise to perform a symbolic integration (int with a lowercase i) inside a procedure that has a single real parameter. If possible, do the int with a symbolic variable, using assuming to assume the variable  real, then construct the procedure by applying unapply with respect to the variable. That way, the symbolic integration is only done once.

On the other hand, if you know that the symbolic integration will fail (i.e., will return unintegrated), it's better to use evalf(Int(...)) inside the procedure. This avoids any attempt at symbolic integration and goes straight to numeric integration.

Either way, it saves a lot of time.

@vv Did you mean to say that ff with lists rather than sets is a bit faster than f4? Yes, the list-to-set conversions take some little bit of time because they involve sorting. Maple sets are always stored sorted.

In the application at hand, the uniqueness of the lists and their elements is already guaranteed: the end result is necessarily a partition of {$1..nops(L)}.

@vv While sleeping, I realized that the explicit pairing of elements to indices via `[]`~ is only needed if using Classify. It can be removed from ff and f4, making the code both simpler and faster:

f5:= proc(L::list)
local T, k;
     for  k to nops(L) do T[L[k]][k]:= () od;
     [indices]~([entries(T, nolist)], nolist)
end proc:

r5:= CodeTools:-Usage(f5(L)):
memory used=12.75MiB, alloc change=0 bytes, cpu time=125.00ms, real time=144.00ms, gc time=31.25ms

evalb(r1 = {(_-> {_[]})~(r5)[]});
     true

First 388 389 390 391 392 393 394 Last Page 390 of 709