Carl Love

Carl Love

25000 Reputation

25 Badges

10 years, 166 days
Wayland, Massachusetts, United States
My name was formerly Carl Devore.

MaplePrimes Activity

These are replies submitted by Carl Love

@Kitonum I think that your implicitplot3d command is missing a multiplication sign after the y.

@acer It's even more efficient if you avoid direct indexing of the rtable in rtable_scanblock's 1st argument and instead use the 2nd argument to literally specify a "block" (i.e., submatrix, slice, subarray, etc.) for it to "scan":

(m,n):= (99, 10^5):
M:= LinearAlgebra:-RandomMatrix((m,n), density= 0.3):
L1:= CodeTools:-Usage([seq](rtable_scanblock(M, [i, ..], ':-NonZeros'), i= 1..m)):
memory used=9.03KiB, alloc change=0 bytes,
cpu time=234.00ms, real time=231.00ms, gc time=0ns

L2:= CodeTools:-Usage([seq](rtable_scanblock(M[i, ..], [..], ':-NonZeros'), i= 1..m)):
memory used=75.56MiB, alloc change=0 bytes,
cpu time=687.00ms, real time=511.00ms, gc time=265.62ms



What I give here is only a "hunch", i.e., a vague intuitive feeling not backed by direct evidence. I suspect that the solution that you want is a singular solution (like I wrote to you in another thread). That is, I suspect that there is some valuation of some parameters that will yield a solution that cannot be obtained by applying the same valuation to a general solution. The parameter valuations that lead to singular solutions can often be guessed by using valuations that would produce zeros in denominators in the general solution.

@sursumCorda The timing difference that you show is due almost entirely to the different methods of random-number generation: In your fast case, the random numbers are generated all at once in a matrix; in your slow do-loop case, they are generated one pair per iteration. In the example below, I've taken your do-loop case and modified it so that the random numbers are generated in a matrix.


Normalizer := rcurry(RealDomain[simplify], assume = positive):
checknn__2 := proc(f::And(symmfunc(x, y, z), freeof({x, y, z}) &under (e -> ifelse(testeq(e), 0, simplify(eval(e, [x, y, z] =~ 'l'*~[x, y, z])/e, symbolic)))), n::coerce(posint, MTM:-uint32) := 2^16, $)::truefalse;
    options encrypted, hfloat;
    description `All rights reserved.`;
    local data, F := (map(combine@simplify, subs(z = 6 - (x + y), f)) assuming (x, y, 6 - (x + y)) >~ 0);
    to n do
        data := sort(Statistics:-Sample(Uniform(0, 1), 2)) . <2, -1; 0, 3>;
        if not eval(F, [x= data[1], y= data[2]]) >= 0 then
            print([x, y, z] =~ [data[1], data[2], 6 - (data[1] + data[2])]/~6);
            return false
    WARNING("precision may be lost");

CodeTools:-Usage(checknn__2((x^3+y^3+z^3) - (3+1/10000)*x*y*z, 1e5));

[x = HFloat(0.3329693776781595), y = HFloat(0.3333573368712247), z = HFloat(0.3336732854506157)]

memory used=1.32GiB, alloc change=120.01MiB, cpu time=60.89s, real time=59.95s, gc time=2.62s



Normalizer:= rcurry(RealDomain:-simplify, assume= positive):
checknn__3:= proc(
        symmfunc(x, y, z),
        freeof({x, y, z}) &under (
            e-> if testeq(e) then 0
                else simplify(eval(e, [x, y, z] =~ 'l'*~[x, y, z])/e, symbolic)
    n::coerce(posint, MTM:-uint32):= 2^16,
options encrypted, hfloat, `All rights reserved.`;
    Data:= LinearAlgebra:-RandomMatrix(n, 2, generator= 0..1., datatype= float[4]),
    F:= (unapply(
        subs({x= X[1], y= X[2]}, map(combine@simplify, subs(z = 6 - (x + y), f))), X
    ) assuming (x, y, 6 - (x + y)) >~ 0),
    for k to n do
        data:= sort(Data[k]) . <2, -1; 0, 3>;
        if F(data) < 0 then
            print([x, y, z] =~ [data[1], data[2], 6 - (data[1] + data[2])]/~6);
            return false
    WARNING("precision may be lost");
end proc

CodeTools:-Usage(checknn__3((x^3+y^3+z^3) - (3+1/10000)*x*y*z, 1e5));

[x = HFloat(0.3328814307848612), y = HFloat(0.3331732551256815), z = HFloat(0.33394531408945716)]

memory used=250.21MiB, alloc change=104.00MiB, cpu time=1.70s, real time=1.71s, gc time=93.75ms





@vs140580 Why not just compute the 500x500 (symmetric) correlation matrix? It's much smaller than the 1000x125250 matrix that you're asking for.

Just to clarify: If starting with 500 coluimns, you want to append new columns of all pairwise products for a total of 125250 columns?

@sursumCorda Okay, I understand what you were trying to highlight: The 1+ is to draw the attention of the human reader to a mathematical fact; you weren't intending for it to make any difference to Maple. If there were some situation where Maple treated 1+20230321 and 20230322 differently, that would be a much more serious bug. (I'm not saying that your reported bug isn't serious. I think it's serious.)

Vote Up. Your first algorithm had an innovative use of symbolic polynomial algebra, and this one has a very innovative use of matrix algebra.

What aspect, if any, of this bug are you trying to highlight by the weirdly specified coefficient (1 + ...)?

@dharr Vote Up. It's a great and surprisingly short (codewise) algorithm with an innovative use of symbolics. I haven't tried it yet, but from a quick read-through on my phone, I'd guess that the storage requirement is at least O(n^(k+2)), where k is the final output (and note that necessarily k >= n). Perhaps the procedure can be refactored to reduce this. Two things that might help:

  1. Carefully control the number of times expand is used.
  2. Send the result of any particular expand to the garbage collector as soon as it's known that it won't be needed later.

(Your code may already do both of those things; I won't know until I actually run it.)

Note that Maple only stores a single copy of any polynomial; all other references, including as parenthesized subexpressions of other polynomials, are just pointers to that master copy. It's useful to keep this in mind when attempting to reduce storage requirements.

Your example clearly shows to me that you're strictly interested in the number of characters per line without regard to any typographical niceties such as not beginning lines with commas or the physical width of the output (in, say, milimeters). This of course makes your request quite easy to fulfill for any specific output, but I don't know of any Maple technique to post-process all worksheet output. I've often wanted something like that. I think that it'd be quite easy for Maplesoft to provide such a mechanism; it'd be as simple as allowing a `print/...procedure to apply to all output. It should then be up to the user to program in exclusions for, say, plot output, which'd be trivial to do if the particular post-processing isn't wanted for plots.

Regarding the specific example that you showed, did you explicitly intend to remove the spaces that ordinarily come after commas?

@vs140580 I think that the following idea can help for your reformulated Question, although I haven't yet figured out all the steps for a proper algorithm.

My idea is based on the powers of the adjacency matrix, say A. For any nonnegative integer k, the [i,j] entry of A^k is the number of walks of length exactly from vertex i to vertex j. So self-returning walks always appear as nonzero diagonal entries of A^k for some k. (For this problem, we don't care about that actual value on the diagonal, only that it's not 0.) The main thing that I haven't figured out yet is how to know that all vertices are included in the walk.

As I've said to you before, Maple's type processing (which is used by indets), is purely syntactic and doesn't consider semantics such as mathematical definitions; and this is the way it has always been and must be. Incorporating mathematical semantics is of course possible, but it must be built on top of the syntactic type system. I don't see how it could possibly be otherwise.

@mmcdara Thanks for your correction and especially for your pedagogically excellent and well-presented counterexample. Unfortunately, I've never seen a proper formal definition of cycle basis, so my Answer was based on guessing. If "basis" means what it usually means in math, then I'd expect that all cycles could be generated from the cycle basis via some relatively easy computation (such as unions and intersections). Since your example only has one member containing 5, I don't see how that works. Do you know how to get the cycle [3, 4, 5, 6, 8] from your basis?

I see now that under the OP's reformulation of the Question, cycle bases won't be useful for its Answer. However, I'd still appreciate any teaching that you can give regarding the issues that I mentioned in the first paragraph.

@Carl Love Perhaps the symbolic solution that you actually want is a singular solution that can't be expressed as any instantiation of a generic symbolic solution. By instantiation I mean an assigment of numeric values to some parameters. Here's an example:

#2x2 matrix and 2x1 vector. 5 parameters (a, b, d, x, y). The 2 decision variables are
#unseen and unnamed in this pure matrix-vector form. Their values are the two entries 
#in the solution vectors S0 and S1.

A:= <a, b; 0, d>;  B:= <x, y>;

#Get a generic solution:
S0:= LinearAlgebra:-LinearSolve(A, B);

#Instantiate 3 parameters (a, d, y) to 0 and solve again:
S1:= LinearAlgebra:-LinearSolve(eval([A, B], [a, d, y]=~ 0)[]);

#Note that no possible instantiation of S0 can produce S1.


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