Joe Riel

9660 Reputation

23 Badges

20 years, 4 days

MaplePrimes Activity


These are replies submitted by Joe Riel

@Andriy I confess, I hadn/t actually tested your worksheet before responding.  I now see what you are describing. I'll submit an SCR against this. My statement about not executing the startup region is correct, that is, because you haven't enabled automatic execution of the startup region (in the security settings), it is not executed until you respond to the dialog. It appears as though the pending embedded component actions are executed before the response to the dialog. That should not happen. If you change the security setting so that auto-execute regions are automatically executed, without an approval by the user, then the problem does not occur; however, it should work properly with the approval dialog.

@Alejandro Jakubi True, the corner cases don't quite fit the description, however, precisely describing them would not necessarily improve the situation.  Sometimes the simple lie is more useful.

@Andriy What's happening is that Maple first tries to execute any code in the startup region.  Because that is not enabled, it doesn't occur. Maple then attempts to execute the input regions in the worksheet set to autoexecute. Presumably some of them reference the module assigned in the startup-region, but because that wasn't executed the module was not assigned so an error occurs.  If you do not want to allow the startup region to execute automatically, then you'll have to remove the autoexecute settings from any input regions to avoid errors. I suppose you could add a conditional around each auto-executed region that checks whether the module is assigned and if not, do nothing.  For example,

if assigned(Actions) then ... end if;

P.S. The explanation, above, isn't entirely germane to the situation in that the worksheet does not have any auto-execute regions. The sole problem is that the Actions module is not yet assigned.  You could add the conditional, above, to each of the executable code regions (you might have to eliminate the use statement and explicitly call the module) to give a useful error message, but that merely substitutes one error for another, albeit one with a userful message.

Add/remove the offending delimiter. Hard for me to say which one without seeing the expression. 

@Carl Love The warning will never be activated.  When a for-loop exits normally, the counter goes past the 'to' value.  Change the conditional to if k > maxiters.

@Carl Love Escaping a forward slash by preceding it with a backslash is harmless.  The backslash is ignored, the forward slash appears in the string.

If you like the brackets, but prefer an upright font, the following procedure does the job.  It also has the advantage that Maple's copy and paste works properly with it, that is, copying the 2D math retains the units.

`print/Unit` := proc(u) 
uses Typesetting;
   mrow(mo("⟦"),eval(Typeset(EV(u)),mi=(n->mi(n,'italic'="false"))),mo("⟧"));
end proc:

@Axel Vogt It does use option remember.  Be aware that showstat doesn't show options.

op(3, eval(a));

          remember, system, ...

Use interface(verboseproc=2) and print a.

@Carl Love Note the use of option remember in Carl's solution.  This is critical.  It, essentially, implements memoization (aka Dynamic Programming).  That is, the results of computations are saved and reused.  Without that, the procedure would not return in a practical timeframe.  You can compute how many calls would be required without option remember using the same technique.

N := proc(n) option cache; N(n-1) + N(n-2) + N(n-3); end proc:
N(0) := 1: N(1) := 1: N(2) := 1:
length(N(2013));
                               533

i.e., some 10^533 calls. Note that I used option cache here rather than option remember. The difference isn't significant here.

@Kitonum Using is for the comparison is not the most efficient.  That won't matter here, but in a large application it makes a difference. Simpler and faster is (a,b)->a[1]<=b[1].

@Carl Love By simpler, I meant conceptually simpler.  Attributes aren't difficult but they aren't typically used and I wouldn't expect most users to know about them. The operation of a do loop is obvious. Here's an example where it is quite a bit faster

Max1 := proc(B)
local b;
    attributes(max(seq(setattribute(Float(b[2]-b[1]),b),b=B)));
end proc:

Max2 := proc(B)
local b,bmx,i,mx;
    bmx := B[1];
    mx := bmx[2]-bmx[1];
    for i from 2 to nops(B) do
        b := B[i];
        if b[2]-b[1] > mx then
            mx := b[2]-b[1];
            bmx := b;
        end if;
    end do;
    bmx;
end proc:

N := 10^6:
B := RandomTools:-Generate(listlist(integer(range=1..N),N,2)):

(**) CodeTools:-Usage(Max1(B));
memory used=167.86MiB, alloc change=87.27MiB, cpu time=5.68s, real time=4.02s, gc time=3.60s
                                                 [580, 999835]

(**) CodeTools:-Usage(Max2(B));
memory used=22.89MiB, alloc change=0 bytes, cpu time=824.00ms, real time=826.00ms, gc time=0ns
                                                 [580, 999835]

(**) CodeTools:-Usage(Max1(B));
memory used=167.85MiB, alloc change=24.00MiB, cpu time=3.65s, real time=2.96s, gc time=1.72s
                                                 [580, 999835]

(**) CodeTools:-Usage(Max2(B));
memory used=22.89MiB, alloc change=0 bytes, cpu time=828.00ms, real time=828.00ms, gc time=0ns
                                                 [580, 999835]

I ran each twice (probably should have reset and reseeded the random generator, but this should suffice). Max2, which uses a coded do-loop, ran in under 1 second, while Max1, which uses all builtins, took over 3 seconds.  The cost there is creating the sequence and the Floats.  Note the increase in memory allocated when Max1 is run. If the data were given as Floats, the call to the Float constructor would not be necessary (it is needed with integers because attributes cannot be attached to integers) and Max1 does better.

Note Max2 fails with an empty list.  That is easily corrected but wasn't worth the effort for the demo.

P.S. Using sort with the above data took 40 secs.

@Konstantin@ You can, of course, just execute the statements one at a time, assuming they were entered as separate statements. Do you have an example that illustrates a particular issue?

@Carl Love If I have some time I'll look into why asolve misses some roots. My assumption is that it has to do with the number of Digits being used. It would have been slightly easier to code asolve if I took advantage of fsolve's actual operation, that is, either returning all, one, or no roots. I'm more interested in why findroots is significantly faster.

@Carl Love Do you have a particular example handy?  I don't doubt that a problem exists, just looking for an example. The following hack job might do a bit better:

asolve := proc(ex, var :: name, rng :: range, {avoid :: set := {}})
local avoids,ends,i,sols;
    sols := [fsolve](ex, var, rng, _options['avoid']);
    if sols = [] or not sols :: 'list(numeric)' then
        return avoid;
    else
        ends := [lhs(rng), op(sort(sols)), rhs(rng)]; # sols already sorted?
        avoids := {op(avoid),map2(`=`,var,sols)[]};
        {seq(op(thisproc(ex,var,ends[i-1]..ends[i], ':-avoid' = avoids))
             , i = 2 .. nops(ends))};
    end if;
end proc:

asolve(exp(x)*cos(x)+1=0, x, 0..10);
                        {x = 1.746139530, x = 4.703323759, x = 7.854369687}

 

@Bendesarts "Flange" is the general term for a mechanical connection.  It is analogous to "port" or "pin" in other domains. In the 1D Mechanical models, the model of a flange has two components, torque and angle (or force and position, for a translation flange). In the multibody models things get more complicated.

First 48 49 50 51 52 53 54 Last Page 50 of 195