Carl Love

Carl Love

28055 Reputation

25 Badges

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

MaplePrimes Activity


These are replies submitted by Carl Love

@mmcdara I disagree totally. You could just as well say that it's impossible to have a random poker hand because the cards are necessarily all different.

However, the OP should learn that when it's said without any qualification, "randomly chosen" means "randomly chosen with replacement", this being not their first Question whose Answer needed to be modified because of that. Perhaps this is all that you were trying to point out.

@jalal Since you've named the columns x[i] and n[i], you need to refer to them by those names in the Remove command:

Remove(df, x[i]);

The code for the inverse procedure is simpler:

PruferToTree:= proc(a::And(list(posint), satisfies(a-> max(a) < nops(a)+3)))
option `Author: Carl Love <carl.j.love@gmail.com> 2020-Nov-8`;
local d:= Array(1..nops(a)+2, ':-fill'= 1), i, j;
    for i in a do d[i]++ od;
    GraphTheory:-Graph(
        {for i in a do for j do if d[j]=1 then d[i]--; d[j]--; {i,j}; break fi od od}
        union
        {{seq}(ArrayTools:-SearchArray(d))}
    )
end proc
#This procedure is intended for 1D input only.
:
GT:-DrawGraph(PruferToTree([4,3,4,8,8,9,4]));

That's easily seen to be the same tree that we started with.

I tested the above code on random trees of up to 2^16 = 65,536 vertices. (A 2^16 tree takes about 10 seconds.) I concluded that the code is efficient, and that it achieves the theoretically optimal asymptotic time complexity O(n*ln(n)), where n is the number of vertices. Here are the details of my test:

For each k from 2 to 16, I generated 9 random trees of size n:= 2^k and added the CPU times for running my code on all 9. I divided this sum by ln(n) and called this AdjTime (adjusted time). Then I did a linear regression of ln(AdjTime) vs. ln(n), achieving a very high r^2 and very low p-values, which indicates that time/ln(n) is proportional to n, i.e., time ~ O(n*ln(n)).

Ns:= 2^~[$2..16]:
AdjTimes:= [seq](
    add(
        CodeTools:-Usage(
            TreeToPrufer(GT:-RandomGraphs:-RandomTree(n)), 
            output= cputime, quiet
        ),
        1..9
    ) / evalf(ln(n)),
    n= Ns
);
 AdjTimes := [0.01082021281, 0., 0.005770780164, 0.008944709253, 
   0.01130111115, 0.01607574474, 0.03390333346, 0.06251678511, 
   0.1308524402, 0.3564768292, 0.5353600847, 1.167029311, 
   2.278324618, 4.803020329, 9.783275745]

s:= 1+max(0, ListTools:-SearchAll(0., AdjTimes));
                             s := 3

Statistics:-LinearFit(
    [1,m], ln~(Ns[s..]), ln~(AdjTimes[s..]), m, 
    output= rsquared, summarize
);
Summary:
----------------
Model: -8.2575900+.93048285*m
----------------
Coefficients:
              Estimate  Std. Error  t-value  P(>|t|)
Parameter 1   -8.2576    0.2227     -37.0855   0.0000
Parameter 2    0.9305    0.0301      30.9269   0.0000
----------------
R-squared: 0.9886, Adjusted R-squared: 0.9876
                       0.988630192645212

 

@Jaqr I don't think that you actually mean "useless" as that word is used in common English. It has a negative or perjorative connotation that primpart doesn't deserve. Appropriate words are "unnecessary" or "superfluous".

@dim____ 

Use

solve(30 = rhs(sol), t); evalf(%);

... And the inertness effect of the `` symbols (as well as the invisible symbols themselves) can be removed by expand.

@Jaqr The command sign returns the sign of the "coefficient" of the "leading term" of the polynomial (those terms are in quotes because it's not absolutely clear (yet) that they are unambiguously defined). The mist-ery (mystery) arises because How does one determine which term is the leading term for a multivariate polynomial in the mist (midst) of the two categories of variables, some of which are primary and thus cannot appear in what will be called "coefficients"; and then how do you determine the sign of a coefficient that contains (non-primary) variables? Thankfully, sign returns an error rather than a misleading result if it cannot resolve the ambiguities. The way that your trick gets around this is that after the first primpart has discarded the "coefficients" (other than their signs), all remaining variables are considered primary for the computation of the sign, and thus the coefficients are numeric. Note that in this case it makes no difference to us which term is considered leading as long as for any p it's corresponding terms in both p and -p that are chosen (and that'll certainly happen because the coefficient has nothing to do with that determination).

I think that if my analysis above is completely correct, then the second primpart (the one on the left in your code, that being the one which is applied secondly) is unnecessary. Please check this.

@jalal Remove the randomize commands. This command, if it's ever used at all, should only be used once per restart.

Of course, random, by itself, does not imply different (or choice without replacement). If you want random choices without replacement, use combinat:-randperm:

Choices:= combinat:-randperm({indices(Plots, nolist)});

@mmcdara Your code covers only the first part of the exercise, which isn't so bad. And of course your code is an interesting solution that goes far above and beyond the scope of the exercise. It's the other two parts of the exercise that really put it over the top for me: the part about what to do if a random value is 0 and the part about selecting random values from the matrix.

The ugliness is compounded by the fact that direct user input is inherently ugly in Maple. This is the fault of Maple, not the instructor, but the instructor should know better than to assign an exercise requiring it.

@emendes The rcurry is just a syntactic convenience for makIing extra arguments the default. It has nothing to do with efficiency. For example, I almost always want to use the extra argument nolist with the indices command. So, after doing 

Indices:= rcurry(indices, nolist),

Indices(T) is equivalent to indices(T, nolist).

If the new code is significantly faster, it's due to using sets instead of lists. Search time through sets should be shorter due to them being stored sorted.

@Jaqr Yes, your idea cleverly gets around the issue by ignoring the V after the first primpart command is done. I hope that this works for all csses.

@Jaqr Yes, @ is the function composition operator in Maple, or, as you say, sequential application.

@Jaqr For reasons that I don't know, the command primpart intentionally doesn't divide out the sign. But there is a sign command for that. So, here's a correction:

RemoveUncommomFactors:= (S::{set,list}(algebraic), V::set(name))->
    map((p-> sign(p,V)*p)@primpart, S, V)
:

 

@Jaqr Yes, it's precise enough. I think that the rule can be stated more briefly: Discard any factor that doesn't contain a category-1 variable. Do you agree?

First 154 155 156 157 158 159 160 Last Page 156 of 709