Carl Love

Carl Love

26488 Reputation

25 Badges

12 years, 260 days
Himself
Wayland, Massachusetts, United States
My name was formerly Carl Devore.

MaplePrimes Activity


These are answers submitted by Carl Love

The option axis= [mode= log] is not intended to be a replacement for the plots commands logplotsemilogplotloglogplot, etc. The difference is that mode= log applies the logarithm after the points are computed, but the dedicated log-plotting commands choose the points knowing that they should be spaced logarithmically. The part of your plot that looks linear is the result of too few values of x being used at the left end of the logarithmic domain.

plots:-semilogplot(
   k, x= 10..1e6, view= [10..1e6, 0.92..0.99], 
   color= "Blue", background= "Ivory", filled= [color= "Cyan", transparency= 0.9], 
   axis= [gridlines= [color= "gray"]], size= [600, 300]
)

Use combine(T1).

I think that this (below) is related to why solve isn't working for this problem. To investigate, I solve the corresponding equation, which is what solve does anyway:

solve(log[2](7/10*x) = log[3](3*x-1), x): lprint(%);
        10/7*RootOf(30*_Z-7*_Z^(ln(3)/ln(2))-7)

evalf([allvalues](%));
        [16.60731836, 0.3730125035 + 0. I, 0.3730125035]

That middle root is spurious and has the same real part as the last root. If I increase Digits to 15, a second spurious root appears, the same as above but with "- 0. I". Increasing Digits further does not change anything except the number of digits in the real parts.

Now, obviously, the solution to your original problem is the closed interval between the two real roots shown.

There is a convert command that returns the list of column or row vectors for a Matrix. Let be a Matrix. The list of column vectors is 

convert(M, list, dimension= 2)

and the list of row vectors is 

convert(M, list, dimension= 1)

The command also handles higher-dimensional Arrays; see ?convert,list.

If you don't want to specify the functional dependence a priori, you should use D instead of diff:

lis:= [f||(1..10)];
L:= D~(lis)

The Ds can be converted to diff after specifying the dependence:

convert(L(t), diff)

Here's a way to do it that changes only the view option of the plot; it doesn't add any other structure (point, curve, etc.). It's not limited to plots produced by the plot command; it works for any non-animated 2-D plot, containing any number of any kind of plot components. It works for plots containing vertical asymptotes or any other form of "undefined".

Include0View:= proc(P::specfunc(PLOT), {xview::range(realcons):= "default"})
local m:= 0, M:= 0, p;
    plots:-display(
        if membertype(
            And(specfunc('VIEW'), 'patfunc'(range(realcons)$2, anything)), 
            P, p
        ) then
            subsop(
                `if`(xview::range, [p,1]= xview, [][]),
                [p,2,1]= min(m, op([p,2,1], P)), [p,2,2]= max(M, op([p,2,2], P)),
                P
            )
        else
            plottools:-transform(
                proc(x,Y)
                local y:= `if`(Y::undefined, undefined, Y);
                    if [x,Y]::list(float) then 
                        m:= min['defined'](m,y); M:= max['defined'](M,y)
                    fi; 
                    [x,Y]
                end proc
            )(P),
            'view'= [xview, m..M]
        fi, _rest
    )
end proc
: 

Example usage:

Include0View(plot(3 + sin(x), x= -Pi..Pi, thickness= 3));

Let expr be an expression that you want to remove dz from. Then do

eval(expr, dz= 1)

In the vast majority of cases, there isn't the slightest problem or name conflict with using a Maple command or package name or a procedure name from one of your own modules as a keyword parameter's keyword. The only case where there is an issue is if the keyword is also one of the 47 reserved words (see help page ?reserved).

You are dealing with permutations. It's not very useful to internally represent them as single integers. If you want to represent them that way externally -- say for a more-compact display -- that's another matter, which is easily handled with a `print/...` procedure:

`print/PERM`:= (L::list(posint))-> Typesetting:-mrow((Typesetting:-mn@String)~(L)[]):

`print/...procedure doesn't change an object's internal representation; it only changes the way it's displayed.

What you're calling "the combination of sets" is usually called the Cartesian product. It can be done numerous ways, one of which is Iterator:-CartesianProduct:

A:= {[1,2], [1,7], [2,4], [2,8]}:
B:= {[3,5,8], [5,6,8]}:
{seq}([seq](p), p= Iterator:-CartesianProduct(A,B));
{[[1, 2], [3, 5, 8]], [[1, 2], [5, 6, 8]], [[1, 7], [3, 5, 8]], [[1, 7], [5, 6, 8]],
 [[2, 4], [3, 5, 8]], [[2, 4], [5, 6, 8]], [[2, 8], [3, 5, 8]], [[2, 8], [5, 6, 8]]}

ListTools:-Flatten~(%);
     {[1, 2, 3, 5, 8], [1, 2, 5, 6, 8], [1, 7, 3, 5, 8], [1, 7, 5, 6, 8],
      [2, 4, 3, 5, 8], [2, 4, 5, 6, 8], [2, 8, 3, 5, 8], [2, 8, 5, 6, 8]}

P:= PERM~(%);
    {12358, 12568, 17358, 17568, 24358, 24568, 28358, 28568}

Finally, you want to impose that uniqueness condition:

select(p-> nops(op(p))=nops({op(p)[]}), P);   
           {12358, 12568, 17358, 17568, 24358, 24568}

That command uses the fact that the internal representation hasn't been changed. Use lprint to view the internal representation:

lprint(%);
{PERM([1, 2, 3, 5, 8]), PERM([1, 2, 5, 6, 8]), PERM([1, 7, 3, 5, 8]), 
PERM([1, 7, 5, 6, 8]), PERM([2, 4, 3, 5, 8]), PERM([2, 4, 5, 6, 8])}

 

Here's how those negative counts arise. As has been mentioned in several recent Questions, some operations on MaplePrimes are very slow (often intermittently). One such operation is pressing the "Submit" button on a Reply (Answer, Comment, etc.). On several occasions, the "busy spinner" has spun for several hours for me before the page refreshes. If you back out of this (without pressing the "Cancel" button), the Reply will usually be posted anyway, but the counter for the number of replies will not be incremented. Once the count is short like this, subsequent deletions may lead to a negative count.

The (kl)-shuffles that you mentioned in a Reply can be done by the oddly named command Iterator:-TopologicalSorts. The odd name comes from Donald Knuth; I don't know if it's standard. The command (when used with its inverse option) lists all permutations that satisfy certain positional inequalities. For example, the positional inequalities for a (2,3)-shuffle are {1 < 2, 3 < 4, 4 < 5}.

KLshuffle:= (K::posint, L::posint)->
local i, p;
    {seq}(
        [seq](p),
        p= Iterator:-TopologicalSorts(
            K+L, {seq(i < i+1, i= 1..K-1), seq(i < i+1, i= K+1..K+L-1)},
            'inverse'
        )
    )
:
KLshuffle(2,3);
     {[1, 2, 3, 4, 5], [1, 3, 2, 4, 5], [1, 4, 2, 3, 5], [1, 5, 2, 3, 4], 
      [2, 3, 1, 4, 5], [2, 4, 1, 3, 5], [2, 5, 1, 3, 4], [3, 4, 1, 2, 5],
      [3, 5, 1, 2, 4], [4, 5, 1, 2, 3]}

 

@MapleMathMatt Your procedure IsSubsequence is much faster, by a factor of about 3, than ArrayTools:-IsSubsequence. It can be simplified not making A into an Array and by not indexing it. Also, it's very easy to add an option to return the indices of such that B[K] = A when A as been verified as a sublist. (This is akin to the output= indices option of ArrayTools:-IsSubsequence.)   I did these things for code simplification and added functionality; the efficiency is about the same.

Definition: A list A is a sublist of a list B if there exists a strictly increasing list of positive integers (indices of B) such that A = B[K].

Here's my procedure:

Sublist?:= proc(A::list, B1::list, {indices::truefalse:= false}, $)
uses AT= ArrayTools;
local 
    n:= nops(B1), B:= rtable(B1), a, p:= 0,
    J:= [for a in A do if member(a, AT:-Alias(B, p, [p+1...n]), 'p') then p else return false fi od]
;
    if indices then J else true fi
end proc
:


Here's a time-test comparison of verifying a 10000-member sublist of a 10-million-member list:

R:= rand(1..10^4):
B:= ['R'()$10^7]:
K:= [combinat:-randcomb(10^7, 10^4)[]]:
A:= B[K]:

J:= CodeTools:-Usage(Sublist?(A, B, indices)):
memory used=79.58MiB, alloc change=76.30MiB, 
cpu time=78.00ms, real time=115.00ms, gc time=0ns

#Verify correctness:
type(J[..-2] - J[2..], list(negint)), evalb(B[J] = A);
                           true, true

CodeTools:-Usage(ArrayTools:-IsSubsequence(A, B, output= indices)):
memory used=114.70MiB, alloc change=-38.15MiB, 
cpu time=219.00ms, real time=471.00ms, gc time=93.75ms

CodeTools:-Usage(Sublist?(A, B)):
memory used=79.58MiB, alloc change=76.30MiB, 
cpu time=78.00ms, real time=104.00ms, gc time=0ns

CodeTools:-Usage(ArrayTools:-IsSubsequence(A, B)): 
memory used=114.58MiB, alloc change=114.45MiB, 
cpu time=312.00ms, real time=421.00ms, gc time=0ns

 

I strongly advise you to use a constructive approach (akin to what @sand15 showed) rather than a modification approach (akin to what @Kitonum showed). I am not considering any issues of computational effciency in this; the constructive approach leads to easier-to-read and easier-to-modify code.

If you were to use a modification approach, it can easily be done with subs without referring to any position within the list:

parms:= subs((thickness=0)= (thickness=3), parms);

However, I'd also want to avoid the specifc reference to 0. With that in mind, you can do

parms:= subsindets(parms, identical(thickness)=anything, ()-> thickness=5);

When options are repeated -- -such as your example that produces a list containing both thickness=0 and thickness=3 -- the option appearing at a higher position in the list takes precedence. In other words, there's no need to remove thickness=0 as long as thickness=3 appears anywhere in the list after it. This can be effectively utilized in plotting procedures by using the _rest meta-parameter. This lets the procedure's user specify ad hoc option modifications on the command line. For example:

MyPlot:= proc(MainArgs::list)
local default_opts:= (color= red, thickness= 0, linestyle= dash);
    plot(MainArgs[], default_opts,
_rest)
end proc
:
MyPlot([x^2, x= -2..2]);
MyPlot([x^2, x= -2..2],
thickness= 3);
 

Pad the text strings with the newline control character, which is "\n" in Maple. That will add a blank line either above or below the text snippet. And I agree with you totally that the relative linear measure of text should be determined by the font and be independent of the Cartesian coordinates of the base point of the text. Here's an example:

plots:-display(
    plot(
        [[[-3,1],[-1,1]], [[1,1],[3,1]], [[-3,-1],[-1,-1]], [[1,-1],[3,-1]]],
        thickness= 5
    ),
    plots:-textplot([
        [-2, 1, "A1", align= below],  [2, 1, "\nB2", align= below],
        [-2, -1, "C3", align= above], [2, -1, "D4\n", align= above]
    ]),
    axes= normal, size= [300$2]
);

There are many ways to represent a complex function in real 3D space. Here, I give separate animations of surface plots of the real and imaginary parts of your sol. Your t becomes the time-based animation parameter.

If you execute this code in a Maple worksheet, the plots will appear side-by-side with the t-values synchronized. It's difficult to copy that to this forum, so I present them here in separate Replies and not necessarily synchronized.

(plots:-display @ `<|>` @ plots:-animate~)(
    plot3d, 
    `[]`~(
        (evalc@[Re,Im])(exp(I*t)*sin(10*x)*sin(4*y)), x= 0..Pi, y= 0..Pi, 
        title=~ cat~(["Real", "Imaginary"], " part of solution\n")
    ),
    t= 0..1, frames= 49
);

1 2 3 4 5 6 7 Last Page 1 of 382