Alec Mihailovs

Dr. Aleksandrs Mihailovs

4455 Reputation

21 Badges

20 years, 306 days
Mihailovs, Inc.
Owner, President, and CEO
Tyngsboro, Massachusetts, United States

Social Networks and Content at Maplesoft.com

I received my Ph.D. from the University of Pennsylvania in 1998 and I have been teaching since then at SUNY Oneonta for 1 year, at Shepherd University for 5 years, at Tennessee Tech for 2 years, at Lane College for 1 year, and this year I taught at the University of Massachusetts Lowell. My research interests include Representation Theory and Combinatorics.

MaplePrimes Activity


These are replies submitted by Alec Mihailovs

That certainly looks nice. Also, 1/~S[1..3] is about ten times faster than Vector...,

time(seq(1/~S[1..3],i=1..100000));

                                0.405

time(seq(Vector(3,i->evalhf(1/S[i])),i=1..100000));

                                5.569

Alec

For such calculations, it works better without the 'flat' property in the define definition.

sum(A^i,i=0..k)&*P&*sum(B^i,i=0..k);

  // (k + 1)     \     (k + 1)\   // (k + 1)     \         \
  ||A            |    B       |   ||A            |      1  |
  ||-------- &* P| &* --------| - ||-------- &* P| &* -----|
  \\ A - 1       /     B - 1  /   \\ A - 1       /    B - 1/

           /                 (k + 1)\
           |/  1       \    B       |   //  1       \      1  \
         - ||----- &* P| &* --------| + ||----- &* P| &* -----|
           \\A - 1     /     B - 1  /   \\A - 1     /    B - 1/

which is wrong if A-1, or B-1 are not invertible, but otherwise is fine.

The downside is that multiplying 2 of such kind of expressions, there might be few Ps next to each other - without associativity (what flat provides), they are not converted to P^2 or P^3.

In general, it's not good for complicated calculations, but might work for simple ones.

Such thing with the definition above including flat, as

A&*B&*1;

                             &*(A, B, 1)

A&*P&*P;

                             &*(A, P, P)

I would consider being a bug.

Without flat, the first one is OK,

A&*B&*1;

                                A &* B

but the second one, while being OK with flat not specified, is not in the form that one would like to see it,

A&*P&*P;

                            (A &* P) &* P

Alec

For such calculations, it works better without the 'flat' property in the define definition.

sum(A^i,i=0..k)&*P&*sum(B^i,i=0..k);

  // (k + 1)     \     (k + 1)\   // (k + 1)     \         \
  ||A            |    B       |   ||A            |      1  |
  ||-------- &* P| &* --------| - ||-------- &* P| &* -----|
  \\ A - 1       /     B - 1  /   \\ A - 1       /    B - 1/

           /                 (k + 1)\
           |/  1       \    B       |   //  1       \      1  \
         - ||----- &* P| &* --------| + ||----- &* P| &* -----|
           \\A - 1     /     B - 1  /   \\A - 1     /    B - 1/

which is wrong if A-1, or B-1 are not invertible, but otherwise is fine.

The downside is that multiplying 2 of such kind of expressions, there might be few Ps next to each other - without associativity (what flat provides), they are not converted to P^2 or P^3.

In general, it's not good for complicated calculations, but might work for simple ones.

Such thing with the definition above including flat, as

A&*B&*1;

                             &*(A, B, 1)

A&*P&*P;

                             &*(A, P, P)

I would consider being a bug.

Without flat, the first one is OK,

A&*B&*1;

                                A &* B

but the second one, while being OK with flat not specified, is not in the form that one would like to see it,

A&*P&*P;

                            (A &* P) &* P

Alec

Convert to + is a simple way to add elements of the list,

convert([1,2,3],`+`);
                                  6

The procedure that I used, selects the permutations of L, i.e. combinat:-permute(L) with the sum of the first 5 numbers equal i, then adds the sums of the next 5 numbers in the selected lists.

Alec

Convert to + is a simple way to add elements of the list,

convert([1,2,3],`+`);
                                  6

The procedure that I used, selects the permutations of L, i.e. combinat:-permute(L) with the sum of the first 5 numbers equal i, then adds the sums of the next 5 numbers in the selected lists.

Alec

The shortest is just using sort,

sort(map(a->[evalf(a),a],a))[-1,2];

                               [6, 12]

or even automatic set sorting,

{op(map(a->[evalf(a),a],a))}[-1,2];

                               [6, 12]

The most efficient theoretically is passing the list once in a loop,

Max:=proc(a)
    local m, i;
    m:=a[1];
    for i in a do
        if i[1]>m[1] or (i[1]=m[1] and i[2]>m[2]) 
            then m:=i 
        fi
    od;
    m 
end;

Max(a);

                               [6, 12]

Alec

The shortest is just using sort,

sort(map(a->[evalf(a),a],a))[-1,2];

                               [6, 12]

or even automatic set sorting,

{op(map(a->[evalf(a),a],a))}[-1,2];

                               [6, 12]

The most efficient theoretically is passing the list once in a loop,

Max:=proc(a)
    local m, i;
    m:=a[1];
    for i in a do
        if i[1]>m[1] or (i[1]=m[1] and i[2]>m[2]) 
            then m:=i 
        fi
    od;
    m 
end;

Max(a);

                               [6, 12]

Alec

Oh, that's interesting. I didn't check that - that's good to know. Thank you!

Would quoting Array(1..16) help? That should help with $, I think - because then it will be 3 different Arrays.

Edit: Yes, quoting helps in both cases,

restart;
L := [a,b,c]:
assign(op(L) = ('Array(1..16)'$3));
a[1]:= foo:
b[1];
                                  0
restart;
L := [a,b,c]:
assign(map(`=`,L,'Array(1..16)'));
a[1]:= foo:
b[1];
                                  0

What I like in the map solution is that the number of elements of L doesn't have to be specified.

Alec

Oh, that's interesting. I didn't check that - that's good to know. Thank you!

Would quoting Array(1..16) help? That should help with $, I think - because then it will be 3 different Arrays.

Edit: Yes, quoting helps in both cases,

restart;
L := [a,b,c]:
assign(op(L) = ('Array(1..16)'$3));
a[1]:= foo:
b[1];
                                  0
restart;
L := [a,b,c]:
assign(map(`=`,L,'Array(1..16)'));
a[1]:= foo:
b[1];
                                  0

What I like in the map solution is that the number of elements of L doesn't have to be specified.

Alec

Thank you!

Actually, I didn't try it in Standard - just in Classic, which is still pretty good in Windows. It would be nice if that worked in Standard, too.

Alec

I got it similarly - for k from floor(m/2)+1 to m we have trunc(m/k)=1 and the limit of that part of the sum is ln 2. Then, for k from floor(m/3)+1 to floor(m/2) we have trunc(m/k)=2, and the limit of that part is (1/2)*ln(3/2). For k from floor(m/4)+1 to floor(m/3) we have trunc(m/k)=3, and the limit is (1/3)*ln(4/3), and so on.

It can be written in a few other interesting forms, in particular,

sum(ln(n)/n/(n-1),n=2..infinity);

                          infinity
                           -----
                            \        ln(n)
                             )     ---------
                            /      n (n - 1)
                           -----
                           n = 2

sum((-1)^n*Zeta(n)/(n-1),n=2..infinity);

                        infinity
                         -----       n
                          \      (-1)  Zeta(n)
                           )     -------------
                          /          n - 1
                         -----
                         n = 2

-sum(Zeta(1,n),n=2..infinity);

                         /infinity           \
                         | -----             |
                         |  \                |
                        -|   )     Zeta(1, n)|
                         |  /                |
                         | -----             |
                         \ n = 2             /

Alec

I got it similarly - for k from floor(m/2)+1 to m we have trunc(m/k)=1 and the limit of that part of the sum is ln 2. Then, for k from floor(m/3)+1 to floor(m/2) we have trunc(m/k)=2, and the limit of that part is (1/2)*ln(3/2). For k from floor(m/4)+1 to floor(m/3) we have trunc(m/k)=3, and the limit is (1/3)*ln(4/3), and so on.

It can be written in a few other interesting forms, in particular,

sum(ln(n)/n/(n-1),n=2..infinity);

                          infinity
                           -----
                            \        ln(n)
                             )     ---------
                            /      n (n - 1)
                           -----
                           n = 2

sum((-1)^n*Zeta(n)/(n-1),n=2..infinity);

                        infinity
                         -----       n
                          \      (-1)  Zeta(n)
                           )     -------------
                          /          n - 1
                         -----
                         n = 2

-sum(Zeta(1,n),n=2..infinity);

                         /infinity           \
                         | -----             |
                         |  \                |
                        -|   )     Zeta(1, n)|
                         |  /                |
                         | -----             |
                         \ n = 2             /

Alec

It may be

sum(ln(1+1/n)/n,n=1..infinity);

                         infinity
                          -----
                           \      ln(1 + 1/n)
                            )     -----------
                           /           n
                          -----
                          n = 1

evalf(%);

                             1.257746887

Alec

First 21 22 23 24 25 26 27 Last Page 23 of 180