Carl Love

Carl Love

28015 Reputation

25 Badges

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

MaplePrimes Activity


These are answers submitted by Carl Love

Your general solution isn't general enough. If f is *any* differentiable function such that f(0)=1, then x0 = y0 = f is a solution to your equation. 

A basic fact about systems of equations is that the number of things that can be solved for is at most the number of equations. 

If is the list of expressions, then all that you need to do is

R:= Grid:-Map(int, L, x= 0..1);

For numeric integration, do 

R:= Grid:-Map(int, L, x= 0..1, numeric);

The command will automatically apply some rudimentary load balancing.

It's possible to get the exact solutions for all 6 functions by direct use (i.e., without using dsolve) of the Method of Undetermined Coefficients. If you try to do this with dsolve, it will get the first 5, but the 6th took longer than I cared to wait. I killed it after more than an hour. The method below gets it in seconds.
 

Direct application of Method of Undetermined Coefficients

restart
:

#right sides of the 6 odes:
RHS:= [
    0, -v__0^3, -3*v__0^2*v__1, -3*v__0*v__1^2 - 3*v__0^2*v__2,
    -6*v__0*v__1*v__2 - 3*v__0^2*v__3 - v__1^3,
    -6*v__0*v__1*v__3 - 3*v__1^2*v__2 - 3*v__0^2*v__4 - 3*v__0*v__2^2
]:
print~(RHS)
:

0

-v__0^3

-3*v__0^2*v__1

-3*v__0^2*v__2-3*v__0*v__1^2

-3*v__0^2*v__3-6*v__0*v__1*v__2-v__1^3

-3*v__0^2*v__4-6*v__0*v__1*v__3-3*v__0*v__2^2-3*v__1^2*v__2

ICs:= [[1,0], [0,0]$5] #initial conditions of the 6 odes
:

for k to nops(RHS) do
    S:= C1*sin(t) + C2*cos(t); #general homogenous solution
    #Perform method of undetermined coefficients termwise:
    rs:= combine(expand(RHS[k]));
    for f in indets(rs, specfunc({sin,cos})) do #for each term on right side
        C:= coeff(rs, f);
        d:= degree(C,t);
        o:= op(f);
        P:= add(a[i]*t^i, i= 0..d)*sin(o) + add(b[i]*t^i, i= 0..d)*cos(o);
        if o=t then P*= t fi; #extra power of t   
        S+= eval(P, solve(identity(diff(P,t$2)+P=C*f, t)))
    od;
    #Apply initial conditions to determine C1 and C2:
    v__||(k-1):= (combine@expand@eval)(S, solve(eval([S, diff(S,t)], t=0)=~ICs[k]));
    print(v[k-1] = v__||(k-1))
od:

v[0] = cos(t)

v[1] = -(1/32)*cos(t)-(3/8)*sin(t)*t+(1/32)*cos(3*t)

v[2] = (23/1024)*cos(t)+(3/32)*sin(t)*t-(3/128)*cos(3*t)+(1/1024)*cos(5*t)-(9/128)*cos(t)*t^2-(9/256)*t*sin(3*t)

v[3] = -(547/32768)*cos(t)+(9/1024)*sin(t)*t^3-(207/4096)*sin(t)*t+(135/4096)*cos(t)*t^2+(279/8192)*t*sin(3*t)-(81/4096)*t^2*cos(3*t)+(297/16384)*cos(3*t)-(3/2048)*cos(5*t)+(1/32768)*cos(7*t)-(15/8192)*t*sin(5*t)

v[4] = (1/1048576)*cos(9*t)-(99/16384)*sin(t)*t^3-(9/131072)*cos(7*t)+(1539/65536)*t^2*cos(3*t)+(825/262144)*t*sin(5*t)-(1359/65536)*cos(t)*t^2-(3915/131072)*t*sin(3*t)+(883/524288)*cos(5*t)-(15121/1048576)*cos(3*t)+(8997/262144)*sin(t)*t+(6713/524288)*cos(t)+(27/32768)*cos(t)*t^4-(225/131072)*t^2*cos(5*t)+(243/32768)*t^3*sin(3*t)-(21/262144)*t*sin(7*t)

v[5] = -(3/1048576)*cos(9*t)+(4635/1048576)*sin(t)*t^3-(81/1310720)*sin(t)*t^5+(1757/16777216)*cos(7*t)-(96795/4194304)*t^2*cos(3*t)-(16575/4194304)*t*sin(5*t)+(15777/1048576)*cos(t)*t^2+(108243/4194304)*t*sin(3*t)-(921/524288)*cos(5*t)+(394701/33554432)*cos(3*t)-(108357/4194304)*sin(t)*t-(42397/4194304)*cos(t)-(441/4194304)*t^2*cos(7*t)-(27/8388608)*t*sin(9*t)+(2187/1048576)*t^4*cos(3*t)+(1125/1048576)*t^3*sin(5*t)+(1/33554432)*cos(11*t)-(783/1048576)*cos(t)*t^4+(6975/2097152)*t^2*cos(5*t)-(10935/1048576)*t^3*sin(3*t)+(1659/8388608)*t*sin(7*t)

 

Download UndeterminedCoeffs.mw

The plot command is plotting over a real interval. It can't be expected to find on its own every turn of a function, especially considering that there could be infinitely many of them (such as for the Weierstrass function[*1]). If there are values of n that you want to make sure are included, you can use the sample option. In this case, we might as well make the sample all the integers in the interval:

f:= n-> ceil(sqrt(4*floor(n))) - floor(sqrt(2*floor(n))) - 1:

Edit: My intention was to use the OP's original function, but I mistakenly copy and pasted Tom Leslie's modification of the original. So, make that

f:= n-> ceil(sqrt(4*n)) - floor(sqrt(2*n)) - 1:
plot(f, 10...100, sample= [$10..100]);

[*1] Weierstrass function: f:= x-> Sum(cos(3^n*x)/2^n, n= 0..infinity). It is continuous everywhere and differentiable nowhere.
 

You should use for derivatives in initial and boundary conditions. I don't know why that is, but it was the only change that I needed to make to your code. Sometimes the diff form works, but the form always works and is a lot less to type.

sys:= {
    diff(phi(eta), eta$2) + 5.261282735*f(eta)*diff(phi(eta), eta) - 
    2.630641368*phi(eta) = 0,
 
    1.059704409*diff(theta(eta), eta$2) + 6.176017503*f(eta)*diff(theta(eta), eta) 
    + 21.03607964*diff(f(eta), eta$2) + 0.5*phi(eta) = 0,
 
    diff(f(eta), eta$4) - 1.052256547*diff(f(eta), eta)*diff(f(eta), eta$2) + 
    1.052256547*f(eta)*diff(f(eta), eta$3) + 5.165076420*diff(theta(eta), eta) + 
    5.261282735*diff(phi(eta), eta) = 0,

    D(phi)(0) = 1 + 0.5*(D@@2)(f)(0),
    D(phi)(1) = 0.5*(D@@2)(f)(1), 
    f(0) = -0.5, f(1) = 0.5, 
    phi(0) = 1, phi(1) = 0, 
    theta(0) = 1, theta(1) = 0
}:
dsol:= dsolve(sys, numeric):
plots:-odeplot(
    dsol, `[]`~(eta, [f, phi, theta](eta)), eta= 0..1, 
    legend= [f, phi, theta]
);

This is an attempt to Answer your followup Question.

A single summation with two indices, say, Sum(f(i, j), i+j= 0..N), is equivalent to the nested summation

Sum(Sum(f(i, j-i), i= 0..j), j= 0..N)

So, if you define your function as 

P:= (x,y)-> Sum(Sum(alpha[i, j-i]*x^i*y^(j-i), i= 0..j), j= 0..N)

then you can differentiate it like any usual function of x and y.

You began your worksheet by assigning numeric values to "symbols". Then you used those symbols in some formulas, and then you obtained or attempted to obtain some purely numeric solutions, such as plots. This is almost always a bad order to do things---whether you're using a symbolic language like Maple, a numeric language like Matlab, or just doing it with pen and paper: It may seem convenient at first, but it becomes inconvenient when you want to change something. And, if you're using a symbolic language, that order may prevent you from using some of the symbolic features. For example, in the worksheet below, I use some of the basic commands for manipulating symbolic polynomials. These don't work as well when the polynomials contain numeric constants with decimal points (called floats). (They still work, but not as well.)

The better approach is to start with a fully symbolic presentation of the problem and then incorporate the numerics at the end.

The central formula (equation) of your worksheet (the one in the solve command) can be easily converted to a polynomial in x. And, if you keep it symbolic, most above-average high-school algebra 2 students could do that conversion with pen and paper. If decimal numbers are used before this step, the result becomes a difficult-to-read mess. There are many benefits to using a polynomial. For example, fsolve automatically returns multiple solutions for polynomials, but not for other equations.

The worksheet below runs many, many times faster than the original approach of solving for 100 values of t.
 

NULLLCC Resonant Converter - Frequency Finder

 

Idea, technical formulas, and numeric data by  @Gata@mapleprimes.com

 

Maple code by Carl Love <carl.j.love@gmail.com>

2022-May-8

 

restart
:

#Very important: There are no decimal points
#used in the input *anywhere* in this worksheet!
                                                #
params:= [
    #These are things that you set at the top of your worksheet. Note that I'm not
    #assigning these values *yet*, just declaring them and loosely associating
    #them with some symbols.
    V__out= 50,
    omega__line= 100*Pi,
    #t= ... Don't specify any t values at this time!
    #But we keep in mind that t goes from 0 to 1/100.
    theta= omega__line*t,
    V__line= 85*sqrt(2)*sin(theta),
    #m= ... I'm holding off on giving m a value here;
    #       I'll leave that up to you.
    Q__s= 16/5*sin(theta)^2,

    #I added this one because it helps simplify the equation:
    VR= V__line/V__out #"Voltage Ratio"
]:
tr:= 0..1/100 #range of t.
:                             

#This is your original equation, except that I substituted my VR.
eq:= 1/VR = 1/sqrt((-m*x^2 + m + 1)^2 + (Q__s*(x - 1/x))^~2);

1/VR = 1/((-m*x^2+m+1)^2+Q__s^2*(x-1/x)^2)^(1/2)

#Convert it to a polynomial in x. Although that could be done by Maple, I think in this
#case it's easier to just use high-school algebra. The steps are
#    1. Reciprocate both sides.
#    2. Square both sides.
#    3. Subtract left side from right side (obtaining an expression implicitly
#       equated to 0).
#    4. Multiply by x^2.
#    5. Expand.
#    6. Collect powers of x.
:

#Those 6 steps are all done by this single line of code:
eqP:= collect(expand(x^2*((rhs-lhs)@map)(`^` , eq, -2)), x);

x^6*m^2+(Q__s^2-2*m^2-2*m)*x^4+(-2*Q__s^2-VR^2+m^2+2*m+1)*x^2+Q__s^2

#Note that all powers of x are even. Since we're only interested in positive solutions,
#we can substitute X for x^2 *now*, then we'll take the square root of the numeric
#solutions *after* they're obtained.
:
eqP2:= simplify(eqP, {x^2= X});

Q__s^2+(-2*Q__s^2-VR^2+m^2+2*m+1)*X+(Q__s^2-2*m^2-2*m)*X^2+m^2*X^3

#This "inner" procedure calls fsolve, not solve, and returns all
#solutions X >= 0. Note that m must be specified via an "outer" procedure.
:
FS_inner:= proc(t, X::name:= :-X)
option remember;
local r;
    if not t::realcons then return 'procname'(args) fi;
    r:= [fsolve](_P, X= 0..infinity, 'avoid'= {X=0});
    if not r::list(numeric) then
        printf("No solution found for t = %a.\n", t);
        [undefined]
    else
        r
    fi
end proc
:

#The outer "wrapper" that handles m:
FS:= subs(
    _inner= eval(FS_inner),
    _P= subs(m= _m, eval[recurse](eqP2, params)),
    proc(m) option remember; rcurry(subs(_m= m, _inner), _rest) end proc    
):

#Operator for the final solutions: The square roots of the min and max of the
#polynomial solutions:
#
x_min_max:= m-> sqrt@~[min,max]@~FS(m, _rest):

#Plot for m=1:
plot(
    x_min_max(1), tr,
    title= "LCC Gain Frequency",
    labels= [t,x], labelfont= [TIMES, BOLD, 14],
    color= [red, green], thickness= 2, view= [tr, 0..2],
    caption= typeset(cat(` `$9, m) = 1),
    captionfont= [HELVETICA, BOLD, 16]
);

 

``

Download ProcSubs2Levels.mw

If you'd like the horizontal axis to be scaled by V__line (as VV did), I can make a small adjustment to do that.

You could use the top-level longstanding galois command for the information that you want.

galois(x^5 + 20*x + 32);
             
"5T2", {"5:2", "D(5)"}, "+", 10, {"(1 2 3 4 5)", "(1 4)(2 3)"}

The help page ?galois describes what all that means.

On the other hand, any place where a space is allowed, you can use multiple spaces, or line breaks, or any combination of those.

The command convert(..., binary) is not very useful for doing further arithmetic; it's mainly to display as output a binary representation of a number. An extremely efficient alternative is Bits:-Split, which returns a list of 0s and 1s. It's trivial to add a list with add (after Maple 2018, I believe) or `+`@op (in any Maple). To create your histogram, you could do

Statistics:-Histogram((`+`@op@Bits:-Split)~([$0..2^16]), binwidth= 1);

Another option that returns the same list is convert(..., base, 2). This is much slower than Bits:-Split (which is compiled code), but it's a command worth knowing because the 2 can be replaced by any positive integer other than 1; whereas Bits:-Split can only work with bases that are powers of 2. And it's not a very slow command; it's just relatively slow compared to the super-efficient Bits:-Split. The above command takes 2 seconds on my computer. If I use convert(..., base, 2), then it takes 7 seconds.

Both of these commands return the digits in order from least significant on the left to most significant on the right. Although that looks backward to us due to the way we usually write numbers, it is the form most convenient for further processing. It is only due to cultural rather than mathematical reasons that it looks weird. 

The dsolve has returned an equation whose left side is y(x) and whose right side is some expression containing but not y. We call that an explicit solution. You don't want to carry around that left side for the remaining computations. Change the line

C := eval(N__1, x = 200)

to

C:= eval[recurse](y(x), [N__1, x= 200])

There's no need to "estimate" the distance; it can be done exactly. Modify your distance function, like this:

dist:= proc(p::[integer,integer], q::[integer,integer])
local H;
    min((add@abs~)~([seq]([p[2]-H, p[1]-q[1], H-q[2]], H= [1,10])))
end proc  
:
Edgs:= {seq}([({op}@lhs~)(e), dist(rhs~(e)[])], e= combinat:-choose(pts2, 2)):
G1:= GraphTheory:-Graph(Edgs):
(distance, Tour):= GraphTheory:-TravelingSalesman(G1);
            distance, Tour := 38, [A, D, C, B, E, A]

I'm working on a method to highlight the trail with arrows.

Your troubles were caused by a hard-to-see typo. The subexpression beta(sin(alpha)/sin(beta)) occurs in the denominator of eq1. That beta is not multiplied by its following expression. To get implied multiplication in 2D Input, you need a space after beta. Or, you can use an explicit multiplication symbol *. If I make this correction and specify variable ranges to fsolve, then I get a solution close to (but not identical to) the one you mentioned earlier.

restart:

Digits:= 15:

params:= [
    Rrt= R/t, Ea= E/(1-nu^2),
    R=1511.6, t= 25.4, E=2e11, nu=0.29, F= 221e6
]:

#Abbreviations for common subexpressions:
macro(
    a= alpha, b= beta,
    S = sin(alpha)/sin(beta),
    PB= (3*Pi/2/beta)^2 - 1,
    T= tan(alpha - beta)
):
# Using the abbreviations reduces the chance of typos when entering the equations.
#

eq:= [
    sqrt(PB*(Pi - a + b*S^2)/12/S/(a - Pi/2500 - b*S/(1 + T^2/4)))/S - Rrt,
    PB/S^3 - 12*P*Rrt^3/Ea,
    1000*((1 - 1/S)/2/Rrt + P*Rrt*S/Ea + 4*P*Rrt^2*b*S^2*T/Pi/Ea - F/Ea)
]:
print~(eq): #for neater display
#
# Expressions are implicitly equated to 0.
#

(1/6)*3^(1/2)*(((9/4)*Pi^2/beta^2-1)*(beta*sin(alpha)^2/sin(beta)^2+Pi-alpha)*sin(beta)/(sin(alpha)*(alpha-(1/2500)*Pi-beta*sin(alpha)/(sin(beta)*(1+(1/4)*tan(alpha-beta)^2)))))^(1/2)*sin(beta)/sin(alpha)-Rrt

((9/4)*Pi^2/beta^2-1)*sin(beta)^3/sin(alpha)^3-12*P*Rrt^3/Ea

500*(1-sin(beta)/sin(alpha))/Rrt+1000*P*Rrt*sin(alpha)/(sin(beta)*Ea)+4000*P*Rrt^2*beta*sin(alpha)^2*tan(alpha-beta)/(sin(beta)^2*Pi*Ea)-1000*F/Ea

Eq:= eval[recurse](eq, params):

sol:= fsolve(Eq, {a= 0..Pi/2, b= 0..Pi/2, P= 0..infinity});

{P = 2065112.19495371, alpha = .944098810392359, beta = .934530721839835}

evalf(eval(Eq, sol)); #Check residuals.

[-0.217e-10, -0.2e-12, 0.58e-13]

[a,b]=~ evalf(eval([a,b]*180/Pi, sol)); #Convert angles to degrees.

[alpha = 54.0928772788039, beta = 53.5446661867369]

# Check Jacobian:
J:= Matrix((3,3), (i,j)-> evalf(eval(diff(Eq[i], [a,b,P][j]), sol)));

Matrix(3, 3, {(1, 1) = -5492.36319652914, (1, 2) = 5312.58704415908, (1, 3) = 0., (2, 1) = -51.9581308624461, (2, 2) = -.2740712344686, (2, 3) = -0.115826733650127e-4, (3, 1) = 47.4307787914329, (3, 2) = -47.1591891411326, (3, 3) = 0.4617082147e-6})

LinearAlgebra:-SingularValues(J);

Vector(3, {(1) = 7641.694050783875, (2) = 36.331927336981565, (3) = 0.7550434006e-6})

 

Download CriticalPressureFsolve.mw

If you

  1. use 15 Digits of precision,
  2. use fsolve instead of solve,
  3. use Pi instead of 3.1415, and
  4. search for complex solutions,

then the imaginary parts of those solutions will be very small, and you can ignore them. After you've entered the three equations, do this:

Digits:= 15:
PI:= Pi:
solC:= fsolve((Eq:= {eq||(1..3)}), complex);
         /                        8                      -11    
solC := { P = -1.44914053377011 10  + 1.81361988528669 10    I, 
         \                                                      
                                                 -21    
  alpha = -3.21040506122157 - 2.69567382732802 10    I, 

                                                -21  \ 
  beta = -2.50058386568901 - 1.52201908062012 10    I }
                                                     / 
solR:= eval(solC, I= 0); #Remove imaginary parts
         /                        8                             
solR := { P = -1.44914053377011 10 , alpha = -3.21040506122157, 
         \                                                      

                          \ 
  beta = -2.50058386568901 }
                          / 
evalf(eval(Eq, solR)); #Check residuals
       /       -12              -12             -10     \ 
      { -6.9 10    = 0., -3.3 10    = 0., 1.1 10    = 0. }
       \                                                / 

Red text is your input; blue text is Maple's output..

The command mtaylor does it. The code below assumes that y__i is some analytic expression in the variables x[1], x[2], x[3].

V:= [x[1],x[2],x[3]]:
ord:= 4:
sort(mtaylor(y__i, V, ord+1), V, ascending);

 

First 48 49 50 51 52 53 54 Last Page 50 of 394