Carl Love

Carl Love

25319 Reputation

25 Badges

10 years, 235 days
Natick, Massachusetts, United States
My name was formerly Carl Devore.

MaplePrimes Activity

These are answers submitted by Carl Love

There is a bug that occurs when a procedure containing `<|>`( saved as plaintext: It's actually saved as `<,>`(...). This doesn't happen if it's saved in internal format rather than plaintext. Here's a worksheet that proves and documents the existence of this bug and shows how to work around it.


Row:= ()-> `<|>`(args);

proc () options operator, arrow; `<|>`(args) end proc

# Despite the erroneous way that Row is prettyprinted above, it works correctly...

Vector[row](2, {(1) = 1, (2) = 2})

# ...and closer inspection via ToInert(eval(Row)) will show that the internal
# procedure is indeed `<|>`, not `<,>`.
# However, when the procedure is saved **as plaintext**...
save Row, "/Users/carlj/desktop/Row.mpl";

#'s saved as if it were actually that erroneously printed form:

"Row := () -> <_passed>;

# Thus, it doesn't work correctly when read back in from the plaintext:
read "/Users/carlj/desktop/Row.mpl":

Vector(2, {(1) = 1, (2) = 2})

# This shows a way to work around the bug:
Row:= ()-> `<|>`(args):
# Save in internal ".m" format:
save Row, "/Users/carlj/desktop/Row.m":


M:= module() option package;
export Row;
    # $include won't work for ".m" file. You need to do this instead:
    read "/Users/carlj/desktop/Row.m"; Row:= eval(:-Row)
end module:

Vector[row](2, {(1) = 1, (2) = 2})

# And that'll still work when the module is saved to a ".mla".



I consider this a "very bad" bug. But I suspect that it'll be very easy for Maplesoft to fix it.

My workaround is very kludgy and quick-and-dirty. It's only intended as a stop-gap workaround, not as a "fix".

It can be easily proven to converge by doing a Direct Comparison Test with Sum(1/n^4, n= 1..infinity).

Since Maple doesn't "know" that n < ithprime(n) for all positive integers n

is(n < ithprime(n)) assuming n::posint;

we can't get Maple to do that Direct Comparison Test. Nonetheless, that inequality is obvious, as is the complete application of the Test to this problem.

This is something called "last name evaluation" that only applies to tables, procedures, and modules. (See help page ?last_name_eval.) The expression atable["b"] hasn't been fully evaluated. If you change the last line to whattype(eval(atable["b"])), it'll respond table. (I'm not recommending that you use eval there in general; this is just for explanatory purposes.) For atable["a"], the "last name" in the evaluation chain is a; for atable["b"], it's atable["b"] (an indexed name). What I recommend that you do in practice is change the 3rd command to atable["a"]:= eval(a); then the later eval is not needed.

You didn't say what your Maple version was. If you have a fairly new version of Maple, then your first question can be solved like this:

In:= (a, S::set(set))-> select[2](member, a, S):

For older Maple, change that to this:

In:= (a, S::set(set))-> select(curry(member, a), S):


X:= {a,b,c,d}:

             {{a, b}, {a, b, c}}

For your second question, use

XxX:= (S::set(set), X::set)-> 
    (a-> `[]`~(a, `intersect`(In(a,S)[]))[])~(X intersect `union`(S[]))

             {[a, a], [a, b], [b, b], [c, c]}

To exclude the diagonal elements, change to

XxX:= (S::set(set), X::set)-> 
    (a-> `[]`~(a, `intersect`(In(a,S)[]) minus {a})[])~(X intersect `union`(S[]))

{[a, b]}

It is a widespread myth that Maple's for-loops are slow.


The message means that items that should have been numeric plot coordinates were actually unassigned variables, presumably because those global variables mentioned in the procedure were not given values before the procedure was called.

I don't know if you want them to be on the same row. If not, you could do

for g in lis[10..20] do 
    print(DrawSubgroupLattice(SmallGroup(g), 'highlight' = CompositionSeries(SmallGroup(g))))

Or, you could limit the number of groups per row to, say, 4, with each as large as possible so that 4 would fit.

The right side of ode1 should be square_wave_periodic(t).

I'm always skeptical of assuming some_property without specifying variables. If you change it to assuming x::real, then it works. Otherwise, some problem occurs when it tries to also assume that right is real. I don't know why that only happens when you use quotes.

I assume that you know that the assumption real is redundant when using left or right, but for whatever reason you want to use it anyway.

Another solution is to make right protected. (I guess that assumptions on unspecified variables don't apply to protected variables.)

protect(right); of your code...

The mathematical constant is spelled Pi (capital P); pi (lowercase) is just another variable.

To convert the units, do 

convert(Rac, units, ohm);

The displayed form will use the capital Omega that you expect.

Here's a procedure for it. Since I suspect that you only want to exclude the integral if the special function depends on the variable of integration, I included an optional second parameter for a variable name or set of variable names. The procedure is constructed with subs so that the calls to FunctionAdvisor and the construction of the set are only done once.

has_special_math_function:= subs(
    _F= {(op@FunctionAdvisor)~(FunctionAdvisor("class_members", "quiet"), "quiet")[]}
        minus {FunctionAdvisor("elementary", "quiet")[]},
    proc(e::algebraic, x::{name, set(name)}:= {})
        hastype(e, And(specfunc(_F), dependent(x)))
    end proc
has_special_math_function := proc (e::algebraic, x::{name, set(name)} := {})
    hastype(e, And(specfunc({AiryAi, AiryBi, 
        AngerJ, BellB, BesselI, BesselJ, BesselK, BesselY, Beta, 
        Chi, Ci, Dirac, Ei, GAMMA, HeunB, HeunC, HeunD, HeunG, 
        HeunT, Im, JacobiP, KummerM, KummerU, Li, MeijerG, Psi, Re, 
        Shi, Si, Ssi, StruveH, StruveL, WeberE, Zeta, abs, dawson, 
        dilog, erf, erfc, erfi, euler, fourier, hankel, hilbert, 
        laplace, lnGAMMA, max, mellin, min, polylog, signum, 
        unwindK, AppellF1, AppellF2, AppellF3, AppellF4, ChebyshevT, 
        ChebyshevU, CompleteBellB, CoulombF, CylinderD, CylinderU, 
        CylinderV, EllipticCE, EllipticCK, EllipticCPi, EllipticE, 
        EllipticF, EllipticK, EllipticModulus, EllipticNome, 
        EllipticPi, FresnelC, FresnelS, Fresnelf, Fresnelg, 
        GaussAGM, GegenbauerC, HankelH1, HankelH2, Heaviside, 
        HermiteH, HeunBPrime, HeunCPrime, HeunDPrime, HeunGPrime, 
        HeunTPrime, IncompleteBellB, InverseJacobiAM, InverseJacobiCD,
        InverseJacobiCN, InverseJacobiCS, InverseJacobiDC, 
        InverseJacobiDN, InverseJacobiDS, InverseJacobiNC, 
        InverseJacobiND, InverseJacobiNS, InverseJacobiSC, 
        InverseJacobiSD, InverseJacobiSN, JacobiAM, JacobiCD, 
        JacobiCN, JacobiCS, JacobiDC, JacobiDN, JacobiDS, JacobiNC, 
        JacobiND, JacobiNS, JacobiSC, JacobiSD, JacobiSN, 
        JacobiTheta1, JacobiTheta2, JacobiTheta3, JacobiTheta4, 
        JacobiZeta, KelvinBei, KelvinBer, KelvinHei, KelvinHer, 
        KelvinKei, KelvinKer, LaguerreL, LambertW, LegendreP, 
        LegendreQ, LerchPhi, LommelS1, LommelS2, MathieuA, MathieuB, 
        MathieuC, MathieuCE, MathieuCEPrime, MathieuCPrime, 
        MathieuExponent, MathieuFloquet, MathieuS, MathieuSE, 
        MathieuSEPrime, MathieuSPrime, MultiPolylog, MultiZeta, 
        NielsenPolylog, SphericalY, Stirling1, Stirling2, 
        WeierstrassP, WeierstrassZeta, WhittakerM, WhittakerW, 
        Wrightomega, argument, bernoulli, binomial, conjugate, 
        doublefactorial, factorial, fouriercos, fouriersin, 
        harmonic, hypergeom, invfourier, invhilbert, invlaplace, 
        invmellin, multinomial, piecewise, pochhammer, GeneralizedPolylog, 
        MathieuFloquetPrime, WeierstrassPPrime, WeierstrassSigma}), 
end proc

You may want to exclude some functions such as signumabsReImargument, etc. from that set.

Setting the value of _Envsignum0 only affects signum(0), not signum(a) for arbitrary a.

FWIW, you could do 

limit(diff(y*fy, y), y= 0, right) assuming a > 0

to make signum(a) = 1. For that matter, you could do

eval(limit(diff(y*fy, y), y= 0, right), [signum= 1, csgn= 1])

although it's not clear to me why you don't want signum in the result.

The command 

series(x/(tan(x) - sin(x)), x= 0)

shows that f(x) is approximately equal to 2/x^2 for x close to 0. This suggests that g(x) = 1/x^2 might be a reasonable choice.

In procedure SOR, change x_0:= x to

x_0[]:= x

This overwrites the vector's elements rather than its pointer.

Like this:

plots:-animatte(plot, [[[x1, z1], [x2, z2](t), [x3, z3](t)]], t= 0..T, frames= n);

where is positive and n a positive integer.

If you want to create a dynamically sized array row-by-row (rather than element-by-element) and then convert it to a matrix, it can be done like this:

A:= Array(1..0):
for i to 9 do A,= (i, i+1, i+2) od:
B:= ArrayTools:-Alias(A, [9,3], C_order);

This is an efficient conversion requiring no intermediate lists or other structures. It doesn't even need to copy the data; it just creates a new pointer to the original array with a different indexing scheme.

First 9 10 11 12 13 14 15 Last Page 11 of 369