Carl Love

Carl Love

25796 Reputation

25 Badges

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

MaplePrimes Activity

These are replies submitted by Carl Love

@vv You wrote:

  • Of course 2 is the "generic" value of the rank. The exact value is given by:
        ans:=(x,y) -> piecewise(x<>0 and y<>0, 2, x<>0 or y<>0, 1, 0)

Yes, if we consider the field of the original matrix to be the complex numbers with x and y being parameters representing field elements, then that piecewise solution applies. On the other hand, if we consider the matrix's underlying field to be C(x,y) (rational functions in x and with complex coefficients), then the generic rank is the rank. But no field can make the rank 3.

This recent Post may be helpful: "Who says Maple doesn't have dark mode?" Since the proposed solution uses Jupyter, I don't know whether it'll be useful to you.

@Carl Love I think @dharr 's simple Answer is probably better, unless perhaps you want to remove the parentheses from the numbers.

@treverona The following Reply was meant to appear earlier, but it was accidentally deleted because I was simultaneously writing Replies on my phone and laptop. When the 2nd was sent, it overwrote the first. All it said was:

What about c_1 = -x^3c_2 = 0c_3 = 1?


If you say that c_1 must be a complex number, not a polynomial, then the entries of your matrix are not field elements. "Standard" linear algebra and the "rank" concept require that a vector's and a matrix's entries come from a field. In this case, the field used is C(x,y), the field of rational functions in x and y with complex coefficients (which of course has -x^3 as a member).

Outside of standard linear algebra, there is an algebraic generalization of vector spaces called "modules" (no connection to the Maple programming structure called module) and there are matrices over these modules. I don't know if there's any concept of the rank of a matrix over a module. There is a Maple package for matrices of polynomials (and it may be restricted to univariate polynomials; not sure) called MatrixPolynomialAlgebra. That package doesn't have a Rank command.

According to what is sometimes called "the fundamental thereom of linear algebra", the rank of a matrix equals the rank of its transpose, so a matrix with a column of zeros cannot have full rank.

We can't help you unless we can see your ODEs (that you named LVS). Either type them here directly, or upload a worksheet via the green uparrow on the toolbar of the MaplePrimes editor. 

@sursumCorda Yes, everything that you said is true. The part about exprseq not being a type (in the Maple-specific sense of that word) is true, although irrelevant, because it's only for purely syntactic reasons that its not a type. Everything else that you said is relevant. There are only a few dozen fundamental (i.e., implemented in the kernel) data structures in Maple; all others are constructed from those with Maple language code. "Expression sequence" is one of those kernel data structures, perhaps the most important nonatomic one. The vast majority of the data structures are immutable. That includes expression sequences. Immutable means literally "cannot be altered". There's no efficiency gain possible by using ​​​​​,= (or any other trick) with an immutable structure, although it works syntactically. I think that the only mutable structures are tables, rtables, procedures, and modules.

Regarding string buffers: In modern Maple, strings can be stored in an rtable (Array) that has datatype= integer[1]. Strings can be appended to the array with ,= without needing to be broken down (by the user) to their individual characters. No indexing is needed. To my mind, these two little details make StringBuffer totally obsolete.


Linked-lists or queues are quite unnecessarily elaborate for this purpose. So-called "flat" and semantics-free containers (rtables, tables) are enough.

Here are four efficient methods to build a Maple list:

#Note the use of [ ] in this procedure:
Nprimes_do:= (n::posint)-> 
local p, i:= 0;
    [for p do if gmp_isprime(p) then i++; p fi until i=n]
#Note the use of ,= in this procedure:
Nprimes_Array:= proc(n::posint)
local P:= Array(1..0), p; 
    for p do if gmp_isprime(p) then i++; P,= p fi until i=n;
end proc
Nprimes_indices:= proc(n::posint)
local P, p, i:= 0;
    for p do if gmp_isprime(p) then P[p]:= ++i fi until i=n;
    [indices](P, 'nolist', 'indexorder')
end proc
Nprimes_entries:= proc(n::posint)
local P, p, i:= 0;
    for p do if gmp_isprime(p) then P[++i]:= p fi until i=n;
    [entries](P, 'nolist', 'indexorder')
end proc
    for P in Nprimes||(_do, _Array, _indices, _entries) do
        lprint(eval(P,1)); gc(); CodeTools:-Usage(P(2^17))[-1]
memory used=175.73MiB, alloc change=16.45MiB,
cpu time=1.22s, real time=1.22s, gc time=0ns
memory used=123.83MiB, alloc change=2.01MiB, 
cpu time=1.12s, real time=1.13s, gc time=0ns
memory used=136.72MiB, alloc change=2.01MiB,
cpu time=1.24s, real time=1.23s, gc time=0ns
memory used=136.77MiB, alloc change=1.00MiB,
cpu time=1.23s, real time=1.24s, gc time=0ns

              [1742537, 1742537, 1742537, 1742537]

Yes, ListBuffer is obsolete.

And I think that the code above shows that your argument from several months ago about for loops being inefficient (based on your misreading of a poorly written and out-of-date help-page passage) is incorrect.

@Zeineb It's certainly possible to get an algebraic formula to permute any finite number of numeric elements, and Maple can easily do it, but the formulas returned are usually so complicated that I don't see any practical value in it. But here it is anyway:

alpha:= i-> (-1)^(i+1)*15/(5*i-4):
beta:= unapply(
    (alpha@CurveFitting:-RationalInterpolation)([$1..5], [3,2,1,4,5], i),
[seq](beta(i), i= 1..5);
                      [15  -5      -15  5]
                      [--, --, 15, ---, -]
                      [11  2       16   7]

                                   /    2             \
                                   |11 i  - 66 i + 103|
                                   |    2             |
         /    2              \     \ 2 i  - 13 i + 23 /
         \30 i  - 195 i + 345/ (-1)                    
                      37 i  - 213 i + 308              


@acer I had assumed that the OP was producing the plot in a procedure for which p and c were parameters. In that case, Typeset(p < c) is not enough. It needs something like Typeset(:-p < :-c).

@RezaZanjirani The download link to your file doesn't work. I think that it's because of punctuation characters in the name. (This is not your fault; it's a MaplePrimes problem.) Please try again using a simple filename (ending with .mw, of course).

@2cUniverse The W used in W=B is the one computed in the same line to the left of the minus. You can see that it can't possibly be from one step before because W is not given an initial value in the declarations. 

@2cUniverse Here's some help for your studying of the code:

  • Bits:-Split(n) returns exactly the same thing as convert(n, 'base', 2); it just does it much faster because it's externally compiled and it's tailored to bases that are powers of 2.
  • Read the help ?seq for info on its recently added option scan. Essentially, it produces something akin to the "sequence of partial sums", but the operator can be anything; it needn't be `+`. If the operator is `+`, then it produces precisely the sequence of partial sums. It does this without creating the sequence of primary terms, so it's more efficient than other methods such as ListTools:-PartialSums.
  • The embedded assignments (`^`(n,e):= ...) and (W:= wt(k-1)) and the "dereference, return, then increment" operator ++ (as in B++) work the same way as in the numerous other languages that have those operators. Since you may be already familiar with some of those languages, I won't say more unless you ask.
  • Putting `^`(n,e) on the left side of := in procedure `^` is essentially the same thing as using a "remember table" (see help ?remember) to save previously computed results and avoid recomputation.
  • option inline (as used in procedure wt) causes the direct substitution of the parameter-substituted body of a single-expression procedure in the places where it's called. These are like parameterized macros in some other languages. (Maple has a command macro, but it can't use parameters.) See ?option,inline.
  • `if`(W=B, ...): This is making use of the fact that if all bits of k-1 are 1, then is a power of 2.

@vv Okay, while striving for efficiency, brevity, and readability, I may have gone too far in the brevity department and detracted from the readability. Let me know if you find this more readable:

OEIS_A219954_B:= (n::posint)->
    #Overloaded ^, tailored for efficiency for this particular sequence: 
    `^`:= (n,e)-> (`^`(n,e):= `if`(e=0, 1, n*n^(e-1))),
    #wt(n) counts 1 bits (Hamming weight):
    wt:= proc(n) option inline; numboccur(Bits:-Split(n), 1) end proc,
    k, W, B:= 1  #B = number of bits; W = Hamming weight (number of 1 bits) 
    (0, seq['scan'= `+`](3^(W:= wt(k-1)) - `if`(W=B, 2^(-1+B++), 0), k= 2..n))
 0, 2, 5, 12, 15, 24, 33, 56, 59, 68, 77, 104, 113, 140, 167, 240, 243, 252,
  261, 288, 297, 324, 351, 432, 441, 468, 495, 576, 603, 684, 765, 992, 995

CodeTools:-Usage(OEIS_A219954_B(2^16)): %[-1];
memory used=20.20MiB, alloc change=0 bytes, 
cpu time=156.00ms, real time=156.00ms, gc time=0ns


@FDS It was my pleasure to help.

Yes, the syntax possibilities are huge. There is the added complexity that DataFrame is an object (a special type of module). Objects can define "overloads" on top of the ordinary syntax, and a user may not realize that the syntax has been changed. In this case, the meaning of [ ] when appended to a DataFrame has been changed. You can see the code for this particular overload with

showstat(DataFrame :: `?[]`);

The with command has also been overloaded. See showstat(DataFrame :: with). DataFrames are built from a slightly simpler object called DataSeries, which has an overload of and (see showstat(DataSeries :: `and`)). There isn't an overload of andseq, but the standard builtin command andseq, in this case, simply builds a catenation of and, and then the overload of and takes over. Finally, both DataFrame and DataSeries overload the elementwise operator (see showstat(DataFrame :: `~`) and showstat(DataSeries :: `~`)), which means, in this case, that <>~ is overloaded.

From reading the help pages, I would've expected this to work, but it doesn't:

DF[andseq(C <>~ undefined, C= with(DF))];

Figuring out an alternative to that that works---replacing the first with DF[C]---is what took most of the time that I spent experimenting.

I'd appreciate getting a Vote Up for my Answer.

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