Carl Love

Carl Love

26663 Reputation

25 Badges

11 years, 229 days
Himself
Wayland, Massachusetts, United States
My name was formerly Carl Devore.

MaplePrimes Activity


These are answers submitted by Carl Love

I don't think that any of the respondents here has yet pointed out explicitly that the original input exponent, 29.403243784, has 11 significant digits. Maple's default working precision is 10 digits, so the first internal step in the computation is to round this to 29.40324378. Using this as the exponent, Maple's result is accurate to the full 10 digits, well within the required 0.6 ulps. This is why the major improvement in accuracy occurs when going from 10 to 11 Digits, as acer showed.

So, to answer explicitly your question: To avoid this problem, set the global variable Digits to a value at least as high as the number of significant digits in the most precisely specified operand. Note that significant digits is not the same thing as digits after the decimal point.

Digits:= 11;

You did not specify an initial value for n. I will assume it's 0. Your function u is called Heaviside in Maple (and elsewhere).

y:= t-> Sum(sin(t-n*Pi)*Heaviside(t-n*Pi), n= 0..infinity);

plot(y, 0..30);

Here is another solution. It is similar to Kitonum's in that it iterates over all possible a, b, c; but it stops iterating the recursive sequence as soon as a noninteger is found. This is done by checking the remainder of the division rather than with a type check. The solutions are stored in a table rather than by the asymptotically quadratic list-appending technique (hardly makes any difference here since there are only two solutions, but it is good to practice the avoidance of list appending). All in all, there's about a factor-of-5 performance improvement, mostly from the early terminations of the sequence iteration.

restart;
t:= Array(-1..20, [0,1]):  # [0,1] are initial values
Soln:= table():
abc:= combinat:-cartprod([[$1..20] $ 3]):  #Iterator
while not abc[finished] do
    assign(('a','b','c')= abc[nextvalue]()[]);
    for n from 0 to 19 do
        t[n+1]:= iquo((a*n*(n+1)+b)*t[n] + c*n^2*t[n-1], (n+1)^2, 'r');
        if r <> 0 then  break  end if
    end do;    
    if r = 0 then  Soln[a,b,c]:= convert(t,list)  end if
end do:
eval(Soln);

You have four specific x values in you IBCs, but Maple can handle at most two. You have -5000, -1000, 1000, 5000.

I don't know why the surd doesn't work, but limit(a^(1/k), k= infinity) does work.

There seems to be a bug when there's only one element in the list being mapped over. The bug is not about a difference between `^` and op; but rather about a difference between [1,2] and [[a,b]]: The former has two elements while the latter has only one. The bug is also manifested by Map(`^`, [2], 2).

Here's a very basic (although structured, functional, and extensible) implementation. I didn't include any error checking of user input. So the user needs to make sure that there's the right number (25 by default) of characters in the key, split doubletons in the plain text, make sure only alphabet characters are in the plaintext or ciphertext, and make sure that texts have an even number of characters. However, I did generalize it so that you are not restricted to (the traditional) 5x5 alphabet: You can use any rectangle (just change R and C in the module locals).

(*
A basic implementation of the Playfair cipher (see "Playfair cipher" in Wikipedia).
There is no error checking of user input, and the user has to split doubletons on
their own.
                                                                                   *)
Playfair:= module()
option `Written 19-Apr-2013 by Carl Love.`;
local
    R:= 5, C:= 5,  #For a 5x5=25 alphabet
    
    #Convert number in 1..25 into row-column coordinates
    to_row_col:= proc(n)  local r,c;  r:= iquo(n-1, C, 'c');  (r+1, c+1)  end proc,

    #Convert row-column coordinates to number in 1..25
    from_row_col:= (r,c)-> C*(r-1)+c,

    rotf:= k-> k mod C + 1,  #mod C, shifted by 1 (rotate forward)
    rotd:= k-> k mod R + 1,  #mod R, shifted by 1 (rotate down)
    
    #For a pair in 1..R*C, return the corresponding Playfair pair. Note that if
    #we just consider the indices in the array, then the mapping from index-pair
    #to index-pair is a constant, independent of the cipher key.
    Playfair_pair:= proc(a,b)
    option remember;
    local r1, r2, c1, c2;
        if a=b then  error "expected unequal arguments"  end if;
        (r1,c1):= to_row_col(a);
        (r2,c2):= to_row_col(b);
        if r1=r2 then  (from_row_col(r1,rotf(c1)), from_row_col(r2,rotf(c2)))
        elif c1=c2 then  (from_row_col(rotd(r1),c1), from_row_col(rotd(r2),c2))
        else (from_row_col(r1,c2), from_row_col(r2,c1))
        end if
    end proc,

    EnDig:= table(),  #Encrypt: Digraph to Digraph
    DeDig:= table()   #Decrypt: Digraph to Digraph
;
export
    SetKey:= proc(Key::string)
    local i, j, i2, j2, DigPlain, DigCrypt;
         #Encrypt and decrypt every possible digraph.
        for i to R*C do  for j to R*C do
            if i=j then  next  end if;
            (i2,j2):= Playfair_pair(i,j);
            DigPlain:= cat(Key[i],Key[j]);
            DigCrypt:= cat(Key[i2],Key[j2]);
            EnDig[DigPlain]:= DigCrypt;
            DeDig[DigCrypt]:= DigPlain
        end do  end do;
        [][]
    end proc,

    Encrypt:= proc(plaintext::string)
    local k;
        cat(seq(EnDig[plaintext[2*k-1..2*k]], k= 1..iquo(length(plaintext),2)))
    end proc,
    
    Decrypt:= proc(ciphertext::string)
    local k;
       cat(seq(DeDig[ciphertext[2*k-1..2*k]], k= 1..iquo(length(ciphertext),2)))
    end proc
;
end module;

 

restart;

 

(*

module () local R, C, to_row_col, from_row_col, rotf, rotd, Playfair_pair, EnDig, DeDig; export SetKey, Encrypt, Decrypt; end module

Here is the example from the Wikipedia page "Playfair cipher"

Playfair:-SetKey("PLAYFIREXMBCDGHKNOQSTUVWZ"); #No J

Note that X is inserted in "tree" to split the double e.

Playfair:-Encrypt("HIDETHEGOLDINTHETREXESTUMP");

Playfair:-Decrypt(%);

 

 

Download Playfair.mw

The package linalg, the command evalm, and the operators &. and &* (when used in the linalg/matrix context) should not be used... ever. These commands are ancient and deprecated. Even experts are forgetting the nuances of their usage. If you have a professor giving you code to work with, please tell that person that I said to not use these commands... ever.

Maple's solve does not return anything when there are no solutions. I agree that that is confusing. In this case, some trivial algebra "by hand" shows that there is indeed no solution. The -2s and rs cancel and you're left with

abs(1+sqrt(1+4*r)) < 1

On the left, you have 1 plus something nonnegative, so the inequality is never true.

The assuming has nothing to do with this: There are no solutions no matter what you assume.

A Matrix can be an element of an Array, just like anything else. A Matrix can even be an entry in another Matrix. There's nothing special that you need to do. Just try it like you were writing above,

MatrixArray:= Array(1..9);

for i to 9 do MatrixArray[i]:= V(i) end do;

I'm curious as to why you begin variable names with &. Usually these are only used for binary and unary operators. But if that's what you want to use, I guess that there's no harm in it. If you are trying to emulate C syntax, then I think that it is a bad idea: the & symbol has meaning in both languages, but that meaning is completely different.

Let's say that your three procedures are named s1, s2, and s3. And let's suppose that you wish for your users to refer to these methods as "QR", "LU", and "RREF" respectively. In the module below, I made dummies for the three procedures, with just a print statement in each. You'll put your actual procedures there, and you'll want to have actual parameter declarations such as proc(A::Matrix, B::Vector, ...) where I have proc().

Solve:= module()
local
    s1:= proc() print("s1", args) end proc,    
    s2:= proc() print("s2", args) end proc,
    s3:= proc() print("s3", args) end proc,
    
    Methods:= table(["QR"= s1, "LU"= s2, "RREF"= s3]),

    ModuleApply:= proc({method::identical("QR", "RREF", "LU"):= "LU"})
        Methods[method](_rest)
    end proc
;
end module;

Now the users will call this via

Solve(A,B, ...other arguments..., method= "QR");

If no method argument is given, the method will default to "LU" (that's what the :="LU" does). The position of the method argument in the calling sequence does not matter. All arguments other than the method= ... are passed on to the solving procedure (that's what the _rest does). If the user gives a method other than the three listed, an appropriate error message is given. Note that this module does not have, and does not need, any exports; and it does not have, nor need, any main body (other than the NULL body provided by that isolated semicolon).

If you have Maple 17, check out ?SignalProcessing,Engine, ?SignalProcessing,Engine,FFT, etc.

It's not clear what you mean by "radius from 0..1". The radius of a cylinder is constant. I'll assume that you mean that the radius is 1. If the radius is 1, and the volume is Pi/2, then the height is 1/2.

The basic plot of the cylinder is

plot3d([1,theta,z], theta= 0..2*Pi, z= 0..1/2, coords= cylindrical);

Note the part in square brackets: [1,theta,z]. That gives the [r, theta, z] cylindrical coordinates, but, as I said above, r is constant 1 in this case.

If you want to get fancy and put endcaps on your cylinder,

plots:-display([
   
plot3d([1,theta,z], theta= 0..2*Pi, z= 0..1/2, coords= cylindrical), #Same as above
    plot3d(
        [[r,theta,0], [r,theta,1/2]], r= 0..1, theta= 0..2*Pi, coords= cylindrical,
        thickness= 2, grid= [10,25], transparency= .35
   )
]);

 

From the File menu, select Print Preview.

Why not just write your own version?

Mod:= (a,m)-> a mod m + `if`(m < 0, m, 0):

First 364 365 366 367 368 369 370 Last Page 366 of 384