Carl Love

Carl Love

27348 Reputation

25 Badges

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

MaplePrimes Activity


These are replies submitted by Carl Love

@Susana30 I added numerous "bells & whistles" to the plot to include features from your hand-drawn one.

plots:-display(
    plots:-polarplot~(
        [r1, r2, [r, theta__1, r= 0..6]], theta=~ [Pi/2..Pi, (0..Pi)$2], 
        color=~ [red, blue, green], thickness=~ [2,2,3],
        legend=~ [r[1]=r1, r[2]=r2, theta[1]=theta__1], 
        axis[2]= [tickmarks= 13], axesfont= [times, bold, 12],
        labels= [`\nr`, theta], labelfont= [times, bold, 18],
        coordinateview= [default, 0..Pi]
    ),
    plots:-polygonplot~(
        [Circle__arc, Cardioid__arc], transparency= .5,
        color=~ [pink, "LightBlue"], legend=~ ["Area 1", "Area 2"]
    ),
    legendstyle= [location= left, font= [times, 14]], size= 500*[2,1]
);

@Muhammad Usman Is it possible that in the example that seemed to work, the graphs were symmetric with respect to the main diagonal, the line y=x? If so, that would explain why it worked.

@Carl Love Here are two more algorithms for the sort. I've included a threadsafe version of degree, which makes each procedure below threadsafe in its entirety. If you don't need it to be threadsafe, you can replace degree__TS with degree, which'll probably be faster. For both algorithms, Nterms is the same as above.

The first new algorithm partitions the list by the signifying variable, then sorts each block by degree and number of terms, then the sorted blocks are catenated. If there are any entries that contain none of the variables. they are sorted by number of terms and placed at the end:

#Thread-safe version of degree, optimized to only be used on expanded 
#polynomials that contain v:
degree__TS:= (p,v)-> max(1, op~(2, indets(p, identical(v)^anything))[])
:
PolySort2:= (F::list, V::list(name))->  local H, N:= F, v;
    [
        (
            for v in V do
                (H,N):= selectremove(has, N, v);
                sort(H, 'key'= [rcurry(degree__TS, v), Nterms])[]
            od
        ),
        sort(N, 'key'= Nterms)[]
    ]
:


The second algorithm also partitions by the signifying variable, then each block is sorted into bins by degree of that variable, then each bin is sorted by the number of terms. Finally, it's all catenated. Entries that contain none of the variables are treated as above: 

#Variant of ListTools:-Classify optimized to this purpose. Returns a 
#list of lists instead of a table of sets.
Classify:= proc(f::appliable, L::list) local e, T:= table();
    for e in L do T[f(e, _rest)][e]:= () od;
    [entries](indices~(T, 'nolist'), 'indexorder')
end proc
:
PolySort3:= (F::list(algebraic), V::list(name))-> local H, N:= F, v;
    [
       (
            for v in V do
                (H,N):= selectremove(has, N, v);
                (op@sort)~(Classify(degree__TS, H, v), 'key'= Nterms)[]
            od
        ),
        sort(N, 'key'= Nterms)[]
    ]
:
PolySort3(F, [x4,x3,x2,x1]);


If you have large lists to be sorted, I'd be curious which algorithm is fastest.

@emendes 

1) Nterms is not an invariant:

The number of terms in an algebraic expression is a "structural" or "syntactic" property of the expression, not an algebraic or mathematical invariant. Your simplify(F1) is partially factored. There's no practical way of counting terms without expanding the polynomial (due to the possibility of cancellation of terms). That's why I said earlier that I assumed that all the polynomials were expanded. The number of terms of an expanded polynomial is an invariant. If you need to work with unexpanded polynomials, it'd be easy to modify the code below to expand each polynomial before assigning it a key. The expanded form needn't be stored. However, the time for expand could easily be the majority of the time.

2) Passing the variables to the Key:

Yes, it can be done. Here's some code:

Nterms:= p-> `if`(p::`+`, nops(p), `if`(p=0, 0, 1))
:
PolySort:= (F::list, V::list(name))->
local S:= {F[]}, B:= 1+max(map(op@degree~, S, {V[]})[], Nterms~(S)[]);
    sort(
        F,
        'key'= proc(p) local v, d, r:= 1;
            for v in V do d:= degree(p,v); r:= B*r+d until d<>0; 
            B*r + Nterms(p)       
        end proc
    )
:
PolySort(F, [x4,x3,x2,x1]);

This code is not threadsafe because degree is not threadsafe.

@Carl Love The list-form keys above help to understand how keys and lexicographic sorting of lists works. But we can easily make the key an integer, which is likely more efficient. Just consider the list elements to be digits of a base-B number where some sufficiently large number is substituted for infinity, and the base becomes infinity+1. To be "sufficiently large", the number just needs to be larger than any other digit that might appear. So, in this case, it needs to be larger than both the largest single-variable degree and the largest number of terms. The procedure below uses base B:= 100, mostly because that makes it easy to see how the keys are obtained. For this example, B:= 7 would work just as well.

Nterms:= p-> `if`(p::`+`, nops(p), `if`(p=0, 0, 1))
:
Key:= proc(p) local v, d, B:= 100, r:= 1;
    for v in (x4,x3,x2,x1) do d:= degree(p,v); r:= B*r+d until d<>0; 
    B*r + Nterms(p)       
end proc
:
sort(F, key= Key);

Key~(F);
             [10206, 10103, 10104, 1000206, 1000205, 100000205]

@emendes Sorry, totally my fault, I gave you an incorrect key procedure. Here's a correction:

Nterms:= p-> `if`(p=0, 0, `if`(p::`+`, nops(p), 1))
:
Key:= proc(p) local v, d, t:= Nterms(p), R:= Array(1..0);
    for v in (x4,x3,x2,x1) do
        R,= if (d:= degree(p,v)) = 0 then infinity else d,t fi;
        if d<>0 then return [seq](R) fi
    od
end proc
:
sort(F, key= Key);

To understand how key sorting works, first get the Key for every list element:

Key~(F);
     
[[2, 6], [1, 3], [1, 4], [infinity, 2, 6], [infinity, 2, 5], [infinity, infinity, 2, 5]]

Then simply put the keys into lexicographic order:

sort(%);
     
[[1, 3], [1, 4], [2, 6], [infinity, 2, 5], [infinity, 2, 6],  [infinity, infinity, 2, 5]]

For long lists, key sorting, which uses a 1-argument procedure, can be significantly more efficient than comparison sorting, which uses a 2-argument procedure.

@Christian Wolinski If you do 

restart;
read 
...
;
N:= anames(alluser);

then will contain the names read from the file.

There are two different problems specified, and it doesn't seem like you realize that they are different. The first is the problem specified in your paragraph labeled "1." The second is the problem in the paragraph after that. The region labeled "2" in the graph corresponds to this second problem; however, the region labeled "1" does not correspond to paragraph "1." So, please clarify the Question.

@C_R At ?seq, it says

  • The form seq(x) is equivalent to seq(i,i = x).

So, seq(R) where R is an rtable is a sequence of the elements.

Any procedure or function name f (or sequence of names) can be enclosed in { } or [ ] so that {f}(...) = {f(...)} and [f](...) = [f(...)]. This is documented at ?evalapply.

For me, {seq}(...is much more clear to read than {seq(...)} (especially when the (...is long) because the former makes it immediately obvious that the set is formed strictly from the result of the seq, whereas with the latter form one needs to read ahead to the closing to know whether the set contains something in addition to the result of the seq.

And, since I always use the form {f}(...) when it's applicable, if I see {f(...)... in my own code I know immediately (without needing to look for the }) that the set contains something in addition to the result of f(...).

The notation "..." appears twice in expression pp. It isn't valid Maple syntax. What do you mean by it?

@michaelvio There's no way to "close" a Question in the sense of preventing further Answers and Replies. The closest thing to that would be to select an Answer as the "Best Answer" by clicking on the trophy icon in the Answer's upper-right corner, under the timestamp.

Do you want to do this operation once, which would make the easiest method preferable, or repeatedly (as in a program), which would make the most-efficient method preferable?

At one point, you issue the command Dsolve(ODE2, y(x)) and conclude that Maple couldn't solve the ODE. But what's really happening is that there's no command Dsolve (it should be dsolve).

@Axel Vogt Yes, I agree about Digits:= 15. It is the best value for most (but definitely not all) situations. By "best", I mean that it gives the best balance of speed and precision. This has little to do with Maple and a lot to do with the IEEE-754 Standard floating-point computations that are optimized into nearly all 64-bit processors.

@mehran rajabi 

Firstly, this was stated by others, but I want to restate it more adamantly than they did: This is a linear differential equation, not a nonlinear one. 

Extracting the coeffiecients in this case requires not only the PDEtools:-dcoeffs suggested by @ecterrab but also the command content to get rid of the x parts:

ode:= 
    c1*diff(f(x),x$4) + c2*diff(f(x),x$3)/x +
    c3*diff(f(x),x$2)/x^2 + c4*diff(f(x),x)/x^3 + c5*f(x)
:
content~([PDEtools:-dcoeffs](ode, f(x)), x);

                     
[c1, c2, c3, c4, c5]

Note that I've entered ode not as an equation but as an expression implicitly equated to 0. Most Maple commands do not force you to use one or the other; however, dcoeffs requires the latter.

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