Carl Love

Carl Love

26488 Reputation

25 Badges

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

MaplePrimes Activity


These are answers submitted by Carl Love

Here's an exercise for you. By using the help pages and asking here for pointers to the correct help pages, figure out what this code does and how. It's very much related to your questions about odds, evens, and squares. (My code is dense, but nothing has been intentionally obfuscated.)

EvenSqrSeries:= proc(N::And(posint, odd))
local 
    n:= N, e, 
    sq:= proc(n) 
    local r:= isqrt(n); 
        if r^2 >= n then r-- fi; 
        `if`(r::odd, r-1, r)
    end proc
;
    add([while (n-= (e:= sq(n))^2) > 4 do e od]%^~2) + n
end proc
:

n:= 2*rand(10^99..10^100-1)() + 1;
   [output omitted]
EvenSqrSeries(n);
   [output omitted]
value(%);
   [output omitted]

This code needs to be run in 1D input (plaintext input).

Sort the DataFrame by the date field before you extract the TimeSeries. Let's say the DataFrame is named DF, and the date field is named mydate. Then do, quite simply,

newDF:= sort(DF, mydate);

Then do whatever you did before to extract the TimeSeries, but do it to newDF rather than to DF.

See help page ?DataFrame,sort.

@nm You wrote:

  • The program can't call dsolve twice each time in order to make sure it gets the smaller infolevel output. That will be too inefficient.

That's not true, due to the efficiency provided by the remember tables. Using the ode from your worksheet posted above, I did the following:

  • I ran the dsolve without setting infolevel, which took 17.64 seconds;
  • then I set infolevel[dsolve]:= 2 and reran the dsolve to get the shorter userinfo output, which took 0.141 seconds.

Thus, the 2nd running was 125 times faster than the 1st.

Then I timed the longer userinfo output: I did restart, set infolevel[dsolve]:= 2, and ran the dsolve again. This took 19.5 seconds, which is 10% more than the sum of the previous two runs. So, in a sense you'd actually be saving time by running it twice.

I'm sorry that I didn't step into this discussion earlier. The code below does what that Matlab code was intended to do (implement a discrete simulation of a 1D Wiener process), and it gives you a function (e.g., B) that can be evaluated at any value in a specified interval in the usual way, such as B(1.2).

This requires Maple 2018 or later. If you have an earlier version of Maple, let me know, and I can easily adjust this.

restart:
Wiener1D:= proc(
    T::range(realcons), N::And(posint, Not(1)), W0::realcons:= 0
)
description "Discrete simulation of 1D Wiener process";
uses AT= ArrayTools, In= Interpolation, St= Statistics;
local 
    a:= lhs(T), b:= rhs(T), dt:= evalf((b-a)/(N-1)),
    t:= rtable(1..N, i-> a+(i-1)*dt, datatype= hfloat),
    W:= evalf(W0) +~ AT:-ScanAlongDimension(
        `+`, St:-Sample(Normal(0, sqrt(dt)), N), 'inplace', evalhf
    )
;
    W[1]:= W0;
    In:-LinearInterpolation(t, W)
end proc
:

Example usage:

randomize():
B:= Wiener1D(0..2, 10^5):
B(1.2);

                       
-0.488707422425162

plot(B, 0..2, numpoints= 1000);

This and other stochastic integration simulations can also be done by the Finance package, as I mentioned before.

You might as well use the command specifically made for extracting a sublist based on a boolean condition of the elements: select:

points2:= select(p-> andmap(x-> abs(x)<5, p), points);

A slightly slicker variation is

points2:= select[2](andmap, x-> abs(x)<5, points);

These methods require no indexing and no counting, neither of the overall list nor of its list/point elements; they'll work, unchanged, for any list of lists of explicit real numbers.

The k-values need not be evenly spaced nor in order. Like this:

#any real-valued algebraic expression depending only on x and k:
y:= (x,k)-> x+k:
 
#any real numbers; order doesn't matter:
K:= [1.1, 1.3, 1.7, 2.0]:
 
plot(y~(x,K), x= -2..2, legend= K, caption= "Legend shows k-value");

Maple chooses the colors, but you can choose your own colors and linestyles (dash, dot, etc.) to ensure sufficient visual variation (especially helpful for a large number of lines or curves).

The command parse is by far the most common way (and I think also the most efficient way) to convert a string of digits to its corresponding integer. And parse also has other far more arcane uses for which you can ignore the help for now.

However, an easy way to completely avoid the issue of strings (i.e., to do the work with pure arithmetic) is

convert(x, base, 1000)

This will order the 3-digit integers from least significant (on the left) to most significant (on the right). This is usually the most convenient order for programming (despite looking weird for purely cultural non-mathematical reasons), but if you don't like it that way, do

ListTools:-Reverse(convert(x, base, 1000))

It's a much more fundamental bug in evaluating 0*infinity cases. The following two also return undefined:

int(0, [x= 0..1, y= 0..infinity]);
int(0, [y= 0..infinity, x= 0..1]);

Having cos in the exponent in your code line

x := (u, v) -> a^cos(u)*sin(v);

seems unusual to me. Didn't you intend that to be

x := (u, v) -> a*cos(u)*sin(v);

?

The following uses the permutation selection criterion that no player from either team appears in consecutive matches. There are 9! = 362,880 "raw" permutations of the 9 matches. There are only 1512 that meet that criterion, and this lists them all:

T:= Array(0..8, [[A, X], [A, Y], [A, Z], [B, X], [B, Y], [B, Z], [C, X], [C, Y], [C, Z]]):
Perms:= [
    for p in Iterator:-Permute([$0..8]) do 
        q:= iquo~(p,3); r:= irem~(p,3);
        for k to 8 while q[k]<>q[k+1] and r[k]<>r[k+1] do od;
        if k=9 then [seq](T[[seq](p)]) fi
    od
];

This code relies on the specific order of the "master permutation" T, so don't change that. Specifically, if two indices of T have the same quotient when divided by 3, then the first team member is the same; if the remainder is the same, then the second team member is the same.

See the command Finance:-BrownianMotion (help page ?Finance,BrownianMotion).

There are three major problems with your code:

1. In the piecewise command, the boolean conditions (i.e., the inequalities in this case) must come before their corresponding expressions, even though they appear after in the standard forms of display (whether in Maple or just typeset mathematics).

2. You can't use x both as a vector and as a symbolic variable (such as a variable of integration). Below, I've changed the symbolic x to xi.

3. Variables that appear in expressions after an arrow -> are not evaluated at the time the function (procedure, arrow expression) is defined. They aren't evaluated until the function is called. This could be corrected with unapply (as suggested by VV above), but I think that it's better to eliminate the loop entirely.

To correct these problems, delete the entire loop where phi is defined. Replace it with this single function definition:

phi:= (k::posint, X::Vector(realcons), h::algebraic)->
    x-> piecewise(Or(x < X[k], x > X[k+2]), 0, x <= X[k+1], x-X[k], X[k+2]-x)/h
:

And change the int command to

F[k]:= int(sin(Pi*xi)*phi(k,x,h)(xi), xi= 0..1)

It's quite simple, and nothing needs to be done implicitly:

ode:= diff(f(x),x)*exp(f(x)-x^2-1) = 2*x:
dsolve({ode, f(0)=1});
                                 2    
                         f(x) = x  + 1
int(rhs(%), x= 0..1);
                               4
                               -
                               3

By the way, note that the ODE is separable as 

int(exp(y), y) = C+int(2*x*exp(x^2+1), x)

where y= f(x).

The Optimization package is for numeric solutions. It can't give solutions for one variable in terms of other variables.

The radius for 4 points is obviously 1/sqrt(2). A set of four points satisfying the conditions is {[1/sqrt(2), 0], [0, 1/sqrt(2)], [-1/sqrt(2), 0], [0, -1/sqrt(2)]}.

For any n, the radius r can be determined by solving the equation

sol:= solve(1=(r-r*cos(2*Pi/n))^2+(r*sin(2*Pi/n))^2, r)

and taking the positive branch of the square root. The result (very easy to obtain by hand also) is

r = 1/sqrt(2 - 2*cos(2*Pi/n))

That can be simplified via a half-angle identity to 

r = csc(Pi/n)/2

A list of n concyclic points satisfying the condition is then

[seq](r*~[cos,sin](2*Pi*k/n), k= 1..n) 

with as given above.

First 40 41 42 43 44 45 46 Last Page 42 of 382