Carl Love

Carl Love

28045 Reputation

25 Badges

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

MaplePrimes Activity


These are replies submitted by Carl Love

@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),
    i
):
[seq](beta(i), i= 1..5);
                      [15  -5      -15  5]
                      [--, --, 15, ---, -]
                      [11  2       16   7]

simplify(beta(i));
                                   /    2             \
                                   |11 i  - 66 i + 103|
                                   |------------------|
                                   |    2             |
         /    2              \     \ 2 i  - 13 i + 23 /
         \30 i  - 195 i + 345/ (-1)                    
         ----------------------------------------------
                          2                            
                      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:

restart:
OEIS_A219954_B:= (n::posint)->
local
    #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))
:
OEIS_A219954_B(33);
 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
                           4294901760

 

@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.

Why do you complain so much? So what if there's a redundant command?? They can't be removed due to backwards-compatibility requirements. You should be happy that there's now something better. Instead, you seem to complain that an older, weaker command exists.

Your nearly constant complaining about Maple and especially the way that you highlight negative words and put them in titles is extremely suspicious to me. Are you being paid to do negative SEO so that Maple acquires an association to negative search terms?

I've been writing on MaplePrimes for 10 years, and, on here, I've never seen someone complain about Maple as much as you do. However, on Usenet, more than 20 years ago, there was an even-more-extreme constant complainer. I'm sure (having seen printed evidence) that that person was trying to get a pay-off from Maplesoft to stop posting negative material.

StringBuffer was introduced in Maple 8; String was introduced in Maple 2019. That's a difference of 15 years, so there's no surprise that a much newer command is more efficient. 

It's likely that's there's a significant time difference, but your test cases are much too small to show it definitively. The resolution of the time command's CPU clock is approximately 0.015 s, so you can't draw conclusions from the difference you show, 0.020 vs. 0.015. I don't draw any firm conclusions from measurements less than 0.1 s or differences less than 0.032 s. 

@felixiao @Preben Alsholm

The lines in your big loop that begin with V11:= and V21:= end with characters that look like semicolons, but are actually some weird character. You just need to erase those two characters and replace them with actual keyboard semicolons.

The next problem is that one of the matrices that you're inverting in singular. Perhaps it is inadvertently a zero matrix because perhaps you forgot to include any entries. Just guessing; I haven't printed out your matrices to check that. But you should.

@vv TIL (an Internet-forum abbreviation for Today I Learned) that numboccur is significantly faster than add for counting 1 bits (a.k.a. the Hamming weight). So, you might as well go back to numboccur.

@2cUniverse If you're using Maple 2021 or later and 1D input, and you change $b+1 to $1..b+1, then I think that it'll work for you. You must use 1D input. There's no way that I'm going to modify that code to work in 2D Input.

To get a gray code box in MaplePrimes, click the symbol < > on the toolbar; it's the 4th icon from the right end of the 2nd toolbar. Then copy and paste your code into the box (which is initially white), and click OK. Ignore any awkward spacing of your code in the white box; it'll correct when you click OK and it turns into the grey box. Although you can edit in the white box, I recommend that you don't; it's much easier to edit in the grey box. You need to put something in the white though or it'll disappear when you click OK. Note that the colors and character styles that you see in my gray boxes are the result of my hand editing within the gray boxes. 

You mentioned the efficiency of log2 and Bits:-Split. Note that the efficient command is ilog2, not log2, which is essentially the same as ln(...)/ln(2) and is thus not efficient.

There's no good reason to ever use evalm. It's a very old command that was replaced over 20 years ago. If you want to multiply Matrices AB, and C (for example), all that you need is

MM:= A.B.C;

I don't know if this will completely solve your problem, but, regardless, you should still eliminate all uses of evalm, because they're certainly not doing anything useful.

@sursumCorda Using the Maple code given for A160414  is essentially circular because that code essentially computes the sequence from this Question, multiplies it by 4, and adds 1. This kind of coding leads, over the years, to inefficient libraries full of crufty redundant code (which nonetheless may produce accurate results).

@vv Okay, you're right that it's better here to avoid recursion and a remember table and instead use seq[scan= `+`] (which is an excellent recent innovation from MapleSoft). So I incorporated that with the Bits:-Split, which makes a major efficiency improvement because it's externally compiled. I also removed some redundant counting and powering of 2s and 3s. The overall efficiency improvement is a factor of 30 to get 2^16 terms.

#VV's procedure:
restart:
A219954list := nmax -> [ 
seq[scan=`+`](
    ifelse(n=1, 0, 3^numboccur(convert(n-1, 'base', 2), 1) - ifelse(2^ilog2(n)=n, n/2, 0)),
    n = 1..nmax
)]:
A219954list(33);
 [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(A219954list(2^16)): %[-1];
memory used=0.64GiB, alloc change=-4.00MiB, 
cpu time=4.61s, real time=4.29s, gc time=718.75ms
                           4294901760
#Carl's procedure:
restart:
OEIS_A219954_B:= proc(n::posint)
uses S= Bits:-Split, C= numboccur;
local b:= ilog2(n), k, P:= 2^~[$0..b], Q:= 3^~[$b+1], L:= 1, c;
    [0, seq['scan'= `+`](Q[(c:= C(S(k-1), 1))] - `if`(c=L, P[L++], 0), k= 2..n)]
end proc
:
OEIS_A219954_B(33);
 [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=17.07MiB, alloc change=2.00MiB, 
cpu time=125.00ms, real time=140.00ms, gc time=0ns
                           4294901760

I give you a Vote Up for using seq[scan= `+`], which I think is the best possible thing for this sequence, or indeed any sequence where each term is computed by adding something to the previous term. I learned that today, while coding for this Question; so, thank you @vv.

First 39 40 41 42 43 44 45 Last Page 41 of 709