MaplePrimes Posts

MaplePrimes Posts are for sharing your experiences, techniques and opinions about Maple, MapleSim and related products, as well as general interests in math and computing.

Latest Post
  • Latest Posts Feed
  • Insertion and processing of data (independent and dependent) with Maple syntax and using traditional equations. In the same way we reach the same result. We can also calculate a, b, Sa, Sb and r (pearson correlation coefficient). It can be used for students and researchers.

    Lenin Araujo Castillo

    Ambassador of Maple

    Hello student friends in this video we trained in vector operations on the plane and in the space using the native Maple syntax as if you were working on your notebook. Then I explain a model biomechanics exercise applying the vectors learned in the training, developed exclusively for students of health sciences.

    Lenin Araujo Castillo

    Ambassador of Maple



    Solving PDEs with initial and boundary conditions:

    Sturm-Liouville problem with RootOf eigenvalues


    Computer algebra systems always failed to compute exact solutions for a linear PDE with initial / boundary conditions when the eigenvalues of the corresponding Sturm-Liouville problem cannot be solved exactly - that is, when they can only be represented at most abstractly, using a RootOf construction.


    This post illustrates then a new Maple development, to tackle this kind of problem (work in collaboration with Katherina von Bülow), including testing and plotting the resulting exact solution. To reproduce the computation below in Maple 2018.1 you need to install the Maplesoft Physics Updates (version 134 or higher).


    As an example, consider

    pde := diff(u(x, t), t) = k*(diff(u(x, t), x, x)); iv := u(x, 0) = 1-(1/4)*x^3, eval(diff(u(x, t), x), x = 0) = 0, eval(diff(u(x, t), x), x = 1)+u(1, t) = 0

    diff(u(x, t), t) = k*(diff(diff(u(x, t), x), x))


    u(x, 0) = 1-(1/4)*x^3, eval(diff(u(x, t), x), {x = 0}) = 0, eval(diff(u(x, t), x), {x = 1})+u(1, t) = 0


    This problem represents the temperature distribution in a thin rod whose lateral surface is insulated over the interval 0 < x and x < 1, with the left end of the rod insulated and the right end experiencing a convection heat loss, as explained in George A. Articolo's Partial Differential Equations and Boundary Value Problems with Maple, example 3.6.4.


    The formulation as a Sturm-Liouville problem starts with solving the PDE by separating the variables by product

    pdsolve(pde, HINT = `*`)

    PDESolStruc(u(x, t) = _F1(x)*_F2(t), [{diff(_F2(t), t) = k*_c[1]*_F2(t), diff(diff(_F1(x), x), x) = _c[1]*_F1(x)}])


    Substituting this separation by product into the last two (out of three) initial/boundary conditions (iv), the original pde and these conditions are transformed into an ODE system with initial conditions

    {_F1(1)+(D(_F1))(1) = 0, diff(_F2(t), t) = -k*_c[1]*_F2(t), diff(_F1(x), x, x) = -_c[1]*_F1(x), (D(_F1))(0) = 0}

    {_F1(1)+(D(_F1))(1) = 0, diff(_F2(t), t) = -k*_c[1]*_F2(t), diff(diff(_F1(x), x), x) = -_c[1]*_F1(x), (D(_F1))(0) = 0}


    This is a problem in actually three variables, including _c[1], and the solution can be computed using dsolve

    dsolve({_F1(1)+(D(_F1))(1) = 0, diff(_F2(t), t) = -k*_c[1]*_F2(t), diff(diff(_F1(x), x), x) = -_c[1]*_F1(x), (D(_F1))(0) = 0}, {_F1, _F2, _c[1]})

    {_c[1] = 0, _F1(x) = 0, _F2(t) = _C5}, {_c[1] = _C2, _F1(x) = 0, _F2(t) = _C5/exp(k*_C2*t)}, {_c[1] = RootOf(tan(_Z)*(_Z^2)^(1/2)-1)^2, _F1(x) = _C4*cos((RootOf(tan(_Z)*(_Z^2)^(1/2)-1)^2)^(1/2)*x), _F2(t) = _C5/exp(k*RootOf(tan(_Z)*(_Z^2)^(1/2)-1)^2*t)}


    We are interested in a solution of the form u(x, t) = _F1(x)*_F2(t) and _F1(x)*_F2(t) <> 0, so discard the first two in the above and keep only the third one

    solution_to_SL := ({_c[1] = 0, _F1(x) = 0, _F2(t) = _C5}, {_c[1] = _C2, _F1(x) = 0, _F2(t) = _C5/exp(k*_C2*t)}, {_c[1] = RootOf(tan(_Z)*(_Z^2)^(1/2)-1)^2, _F1(x) = _C4*cos((RootOf(tan(_Z)*(_Z^2)^(1/2)-1)^2)^(1/2)*x), _F2(t) = _C5/exp(k*RootOf(tan(_Z)*(_Z^2)^(1/2)-1)^2*t)})[3]

    {_c[1] = RootOf(tan(_Z)*(_Z^2)^(1/2)-1)^2, _F1(x) = _C4*cos((RootOf(tan(_Z)*(_Z^2)^(1/2)-1)^2)^(1/2)*x), _F2(t) = _C5/exp(k*RootOf(tan(_Z)*(_Z^2)^(1/2)-1)^2*t)}


    If we were able to express _c[1] in closed form, with a formula depending on an integer parameter identifying one of the roots of the expression, the rest of the method is straightforward, the product u(x, t) = _F1(x)*_F2(t) is a solution that by construction satisfies the boundary conditions in (1) , and we have one of them for each value of _c[1](for each root of the expression within the RootOf construction). The first condition in iv is used to adjust the remaining constant (combine _C4 times _C5 into one) using orthogonality properties , and by linearly superimposing these different solutions we construct an infinite series solution. All this is explained in standard textbooks.


    The problem is what to do when _c[1] cannot be expressed in closed form, as in the example above. To understand the situation clearly, remove that RootOf and plot its contents:

    RootOf(tan(_Z)*sqrt(_Z^2)-1) = lambda[n]

    RootOf(tan(_Z)*(_Z^2)^(1/2)-1) = lambda[n]


    DEtools[remove_RootOf](RootOf(tan(_Z)*(_Z^2)^(1/2)-1) = lambda[n])

    tan(lambda[n])*(lambda[n]^2)^(1/2)-1 = 0


    This equation has infinitely many roots. For instance between -2*Pi and 2*Pi, NULL

    plot(lhs(tan(lambda[n])*(lambda[n]^2)^(1/2)-1 = 0), lambda[n] = -2*Pi .. 2*Pi)


    A closed form solution to represent these values of `&lambda;__n` (also called the eigenvalue of the Sturm-Liouville problem) are necessary in the intermediate solving steps, and to express in closed form the solution to the original problem.


    We cannot do magic to overcome this mathematical limitation, but there are in Maple representational abstract alternatives: we can use, in all the intermediate computations, a RootOf construction with a label  identifying each of the roots and, at the end, remove the RootOf construction, presenting something readable, understandable.


    This is the representation of the solution that we are proposing, whose automatic derivation from given pde and iv is already implemented:

    pdsolve([pde, iv])

    u(x, t) = `casesplit/ans`(Sum(3*exp(-k*lambda[n]^2*t)*cos(lambda[n]*x)*((-lambda[n]^2+2)*cos(lambda[n])-2+(lambda[n]^3+2*lambda[n])*sin(lambda[n]))/(lambda[n]^3*(sin(2*lambda[n])+2*lambda[n])), n = 0 .. infinity), {And(tan(lambda[n])*lambda[n]-1 = 0, 0 <= lambda[n])})


    So an expression restricted by equations, inequations and possibly subject to conditions. This is the same type of representation we use in pdsolve, PDEtools:-casesplit and the FunctionAdvisor.


    Note that, since there are infinitely many roots to the left and to the right of the origin, we assumed for simplicity that `&lambda;__n` >= 0, which suffices to construct the infinite series solution above. The initial value for the summation index n could be 0 or 1, it doesn't matter, since n itself does not appear in the summand, it only identifies one of the values of lambda solving tan(lambda[n])*lambda[n]-1 = 0. This is a very nice development.


    So we can now compute and represent the solution algebraically even when the eigenvalue `&lambda;__n` cannot be expressed in closed form. But how do you test such a solution? Or even plot it?


    For now that needs some human intervention. Start with testing (part of what follows is in the plans for further development of pdetest). Separate the solution expressed in terms of `&lambda;__n`from the equation defining it

    solution := lhs(u(x, t) = `casesplit/ans`(Sum(3*exp(-k*lambda[n]^2*t)*cos(lambda[n]*x)*((-lambda[n]^2+2)*cos(lambda[n])-2+(lambda[n]^3+2*lambda[n])*sin(lambda[n]))/(lambda[n]^3*(sin(2*lambda[n])+2*lambda[n])), n = 0 .. infinity), {And(tan(lambda[n])*lambda[n]-1 = 0, 0 <= lambda[n])})) = op(1, rhs(u(x, t) = `casesplit/ans`(Sum(3*exp(-k*lambda[n]^2*t)*cos(lambda[n]*x)*((-lambda[n]^2+2)*cos(lambda[n])-2+(lambda[n]^3+2*lambda[n])*sin(lambda[n]))/(lambda[n]^3*(sin(2*lambda[n])+2*lambda[n])), n = 0 .. infinity), {And(tan(lambda[n])*lambda[n]-1 = 0, 0 <= lambda[n])})))

    u(x, t) = Sum(3*exp(-k*lambda[n]^2*t)*cos(lambda[n]*x)*((-lambda[n]^2+2)*cos(lambda[n])-2+(lambda[n]^3+2*lambda[n])*sin(lambda[n]))/(lambda[n]^3*(sin(2*lambda[n])+2*lambda[n])), n = 0 .. infinity)


    op([2, 2, 1, 1], u(x, t) = `casesplit/ans`(Sum(3*exp(-k*lambda[n]^2*t)*cos(lambda[n]*x)*((-lambda[n]^2+2)*cos(lambda[n])-2+(lambda[n]^3+2*lambda[n])*sin(lambda[n]))/(lambda[n]^3*(sin(2*lambda[n])+2*lambda[n])), n = 0 .. infinity), {And(tan(lambda[n])*lambda[n]-1 = 0, 0 <= lambda[n])}))

    tan(lambda[n])*lambda[n]-1 = 0


    By inspection, solution has sin(lambda[n]) and cos(lambda[n]), not tan(lambda[n]), so rewrite (10), and on the way isolate cos(lambda[n])

    condition := isolate(convert(tan(lambda[n])*lambda[n]-1 = 0, sincos), cos(lambda[n]))

    cos(lambda[n]) = sin(lambda[n])*lambda[n]


    Start by pdetesting

    pdetest(solution, [pde, iv])

    [0, Sum(3*cos(lambda[n]*x)*((I*lambda[n]^3+(2*I)*lambda[n]-lambda[n]^2+2)*exp(-I*lambda[n])-4+(-I*lambda[n]^3-(2*I)*lambda[n]-lambda[n]^2+2)*exp(I*lambda[n]))/(2*lambda[n]^3*sin(2*lambda[n])+4*lambda[n]^4), n = 0 .. infinity)-1+(1/4)*x^3, 0, Sum(-3*((I*lambda[n]^3+(2*I)*lambda[n]-lambda[n]^2+2)*exp(-I*lambda[n])-4+(-I*lambda[n]^3-(2*I)*lambda[n]-lambda[n]^2+2)*exp(I*lambda[n]))*sin(lambda[n])*exp(-k*lambda[n]^2*t)/(2*lambda[n]^2*sin(2*lambda[n])+4*lambda[n]^3), n = 0 .. infinity)+Sum(3*((I*lambda[n]^3+(2*I)*lambda[n]-lambda[n]^2+2)*exp(-I*lambda[n])-4+(-I*lambda[n]^3-(2*I)*lambda[n]-lambda[n]^2+2)*exp(I*lambda[n]))*cos(lambda[n])*exp(-k*lambda[n]^2*t)/(2*lambda[n]^3*sin(2*lambda[n])+4*lambda[n]^4), n = 0 .. infinity)]


    A further manipulation, substituting condition and combining the sums results in

    simplify(subs(condition, combine([0, Sum(3*cos(lambda[n]*x)*((I*lambda[n]^3+(2*I)*lambda[n]-lambda[n]^2+2)*exp(-I*lambda[n])-4+(-I*lambda[n]^3-(2*I)*lambda[n]-lambda[n]^2+2)*exp(I*lambda[n]))/(2*lambda[n]^3*sin(2*lambda[n])+4*lambda[n]^4), n = 0 .. infinity)-1+(1/4)*x^3, 0, Sum(-3*((I*lambda[n]^3+(2*I)*lambda[n]-lambda[n]^2+2)*exp(-I*lambda[n])-4+(-I*lambda[n]^3-(2*I)*lambda[n]-lambda[n]^2+2)*exp(I*lambda[n]))*sin(lambda[n])*exp(-k*lambda[n]^2*t)/(2*lambda[n]^2*sin(2*lambda[n])+4*lambda[n]^3), n = 0 .. infinity)+Sum(3*((I*lambda[n]^3+(2*I)*lambda[n]-lambda[n]^2+2)*exp(-I*lambda[n])-4+(-I*lambda[n]^3-(2*I)*lambda[n]-lambda[n]^2+2)*exp(I*lambda[n]))*cos(lambda[n])*exp(-k*lambda[n]^2*t)/(2*lambda[n]^3*sin(2*lambda[n])+4*lambda[n]^4), n = 0 .. infinity)], Sum)))

    [0, Sum(3*cos(lambda[n]*x)*((I*lambda[n]^3+(2*I)*lambda[n]-lambda[n]^2+2)*exp(-I*lambda[n])-4+(-I*lambda[n]^3-(2*I)*lambda[n]-lambda[n]^2+2)*exp(I*lambda[n]))/(2*lambda[n]^3*sin(2*lambda[n])+4*lambda[n]^4), n = 0 .. infinity)-1+(1/4)*x^3, 0, 0]


    So from the four elements (one PDE and three iv), three are satisfied without having to specify who is `&lambda;__n` - it sufficed to say that cos(lambda[n]) = sin(lambda[n])*lambda[n], and this is the case of most of the examples we analyzed. You really don't need the exact closed form of `&lambda;__n` in these examples.

    For the one expression which remains to be proven equal to zero, there is no clear way to perform the sum and show that it is equal to 1-(1/4)*x^3 without further information on the value of `&lambda;__n`.  So this part needs to be tested using a plot.


    We need to perform the summation, instead of using infinite terms, using, say, the first 100 of them, and for that purpose we need the first 100 positive values of `&lambda;__n`. These values can be obtained using fsolve. Increase Digits to get a better approximation:

    Digits := 20



    L := [fsolve(condition, lambda[n], 0 .. 10^10, maxsols = 100)]

    [.86033358901937976248, 3.4256184594817281465, 6.4372981791719471204, 9.5293344053619636029, 12.645287223856643104, 15.771284874815882047, 18.902409956860024151, 22.036496727938565083, 25.172446326646664714, 28.309642854452012364, 31.447714637546233553, 34.586424215288923664, 37.725612827776501051, 40.865170330488067836, 44.005017920830842726, 47.145097736761031075, 50.285366337773650463, 53.425790477394666341, 56.566344279821518125, 59.707007305335457045, 62.847763194454453706, 65.988598698490388394, 69.129502973895260447, 72.270467060308959618, 75.411483488848152399, 78.552545984242931733, 81.693649235601687434, 84.834788718042289254, 87.975960552493213068, 91.117161394464748699, 94.258388345039861151, 97.399638879073768561, 100.54091078684231954, 103.68220212628958019, 106.82351118369472752, 109.96483644107604716, 113.10617654902325890, 116.24753030393208866, 119.38889662883081820, 122.53027455715460386, 125.67166321895208822, 128.81306182910932798, 131.95446967725504430, 135.09588611907366660, 138.23731056880233903, 141.37874249272782439, 144.52018140353123171, 147.66162685535436266, 150.80307843948249426, 153.94453578055557821, 157.08599853323391302, 160.22746637925593824, 163.36893902483538786, 166.51041619835300015, 169.65189764830461611, 172.79338314147304750, 175.93487246129575380, 179.07636540640428965, 182.21786178931479917, 185.35936143525164220, 188.50086418108862526, 191.64236987439434602, 194.78387837256989967, 197.92538954206868814, 201.06690325768935430, 204.20841940193396857, 207.34993786442454883, 210.49145854137182078, 213.63298133509084236, 216.77450615355873900, 219.91603291001033966, 223.05756152256797778, 226.19909191390213620, 229.34062401091997921, 232.48215774447913415, 235.62369304912436649, 238.76522986284504017, 241.90676812685147396, 245.04830778536849850, 248.18984878544468993, 251.33139107677590895, 254.47293461154190896, 257.61447934425489811, 260.75602523161904694, 263.89757223240002997, 267.03912030730377471, 270.18066941886366904, 273.32221953133554631, 276.46377061059982966, 279.60532262407027259, 282.74687554060878265, 285.88842933044586060, 289.02998396510622761, 292.17153941733925030, 295.31309566105380609, 298.45465267125726198, 301.59621042399826673, 304.73776889631308125, 307.87932806617519465, 311.02088791244799345]


    For convenience, construct a procedure, as a function of n, that returns each of these values

    Lambda := proc (n) options operator, arrow; if n::nonnegint then L[n+1] else 'procname(args)' end if end proc

    proc (n) options operator, arrow; if n::nonnegint then L[n+1] else 'procname(args)' end if end proc


    Replace `&lambda;__n` by "Lambda(n), "infinity by 99 and the expression to be plotted is

    remain := subs(lambda[n] = Lambda(n), infinity = 99, [0, Sum(3*cos(lambda[n]*x)*((I*lambda[n]^3+(2*I)*lambda[n]-lambda[n]^2+2)*exp(-I*lambda[n])-4+(-I*lambda[n]^3-(2*I)*lambda[n]-lambda[n]^2+2)*exp(I*lambda[n]))/(2*lambda[n]^3*sin(2*lambda[n])+4*lambda[n]^4), n = 0 .. infinity)-1+(1/4)*x^3, 0, 0][2])

    Sum(3*cos(Lambda(n)*x)*((I*Lambda(n)^3+(2*I)*Lambda(n)-Lambda(n)^2+2)*exp(-I*Lambda(n))-4+(-I*Lambda(n)^3-(2*I)*Lambda(n)-Lambda(n)^2+2)*exp(I*Lambda(n)))/(2*Lambda(n)^3*sin(2*Lambda(n))+4*Lambda(n)^4), n = 0 .. 99)-1+(1/4)*x^3


    Perform the sum and plot. The plotting range is the one present in the iv (1), x goes from 0 to 1

    R := eval(remain, Sum = add)

    plot(R, x = 0 .. 1)


    This result is very good. With the first 100 terms (constructed using the first 100 roots of tan(lambda[n])*lambda[n]-1 = 0) we verified that this last of the four testing conditions is sufficiently close to zero, and this concludes the verification.

    To plot the solution, the idea is the same one: in (9), give a value to k - say k = 1/5 - then construct the sum of the first 100 terms as done in (17), but this time using (9) instead of (13)


    subs(k = 1/5, lambda[n] = Lambda(n), infinity = 99, u(x, t) = Sum(3*exp(-k*lambda[n]^2*t)*cos(lambda[n]*x)*((-lambda[n]^2+2)*cos(lambda[n])-2+(lambda[n]^3+2*lambda[n])*sin(lambda[n]))/(lambda[n]^3*(sin(2*lambda[n])+2*lambda[n])), n = 0 .. infinity))

    u(x, t) = Sum(3*exp(-(1/5)*Lambda(n)^2*t)*cos(Lambda(n)*x)*((-Lambda(n)^2+2)*cos(Lambda(n))-2+(Lambda(n)^3+2*Lambda(n))*sin(Lambda(n)))/(Lambda(n)^3*(sin(2*Lambda(n))+2*Lambda(n))), n = 0 .. 99)


    S := eval(u(x, t) = Sum(3*exp(-(1/5)*Lambda(n)^2*t)*cos(Lambda(n)*x)*((-Lambda(n)^2+2)*cos(Lambda(n))-2+(Lambda(n)^3+2*Lambda(n))*sin(Lambda(n)))/(Lambda(n)^3*(sin(2*Lambda(n))+2*Lambda(n))), n = 0 .. 99), Sum = add)

    plot3d(rhs(S), x = 0 .. 1, t = 0 .. 1)


    Compare with the numerical solution one could obtain using pdsolve with the numeric option . So substitute k = 1/5, and from the corresponding help page rewrite the initial/boundary conditions using D notation and this is the syntax and corresponding plot

    pds := pdsolve(subs(k = 1/5, pde), convert({iv}, D), numeric, time = t, range = 0 .. 1)



    pds:-plot3d(t = 0 .. 1, x = 0 .. 1)





    Edgardo S. Cheb-Terrab
    Physics, Differential Equations and Mathematical Functions, Maplesoft

    The Maple help contains a nice example of a puzzle solver named alphametic,  see  ?Iterator,Permute.
    The goal is to determine the distinct digits represented by letters which satisfy a given  equation. The provided solved example is:

            "16540*781 = 12904836 + 12904"
    i.e.  m=1, a=6, p=5 etc.

    It's worth studying the program (written as a module) because it includes a few useful techniques.
    I would suggest the following exercise for a Maple (young) programmer.

    1.  When solving the "classical" puzzle  "FORTY+TEN+TEN=SIXTY", instead of the correct answer "29786+850+850=31486",   you will see
    Try to find what's going on and correct the code.

    2. The solutions given by alphametic include numbers beginning with a zero.
    Execute e.g. .
    Modify the code to produce only standard numbers.


    Here is a simple collection of Python scripts that allows Maple code to be embedded directly within a LaTeX document. The scripts will process the LaTeX document, calling Maple as required, making the Maple output directly accessible in the LaTeX document. The source, including extensive examples, can be found at This  library also supports inclusion of active Mathematica, Matlab, Python and Cadabra code within LaTeX documents.

    Here is a simple example (based on maple/example-01 in the GitHub site)

       ans := diff(x*sin(x),x):                          # mpl (ans.501,ans)
       ans := eval(diff(x*sin(x),x),x=Pi/4):             # mpl (ans.502,ans)
       ans := int(2*sin(x)^2, x=a..b):                   # mpl (ans.503,ans)
       ans := int(2*exp(-x^2),x=0..infinity):            # mpl (ans.504,ans)
       ans := ''int(2*exp(-x^2),x=0..infinity)'':        # mpl (lhs.504,ans)
       ans := int(int(x^2 + y^2,  y=0..x),x=0..1):       # mpl (ans.505,ans)
       ans := ''int(int(x^2 + y^2,  y=0..x),x=0..1)'':   # mpl (lhs.505,ans)

    and here is the corresponding output



    Let us consider

    plots:-inequal(max(1, min(x, 2))+max(1, min(y, 2)) <= 3, x = -4 .. 4, y = -4 .. 4);

    and compare it with

    plots:-implicitplot(max(1, min(x, 2))+max(1, min(y, 2)) = 3, x = -4 .. 4, y = -4 .. 4, gridrefine = 2);

    The latter plot must be a subset of the former plot, but it isn't so.

    Maple users frequently solve differential equations. If you want to use the results later in Maple, you need to deconstruct the solution, and then assign the functions -- something that isn't done automatically in Maple. We wrote a multi-purpose routine to help you out. For instance, suppose you solve a simple linear system of equations:

    eqs := { x + y = 3, x - y = 1 };
    soln := solve( eqs ); # { x = 2, y = 1 }
    x, y; # plain x and y

    To assign the values from the solution to the corresponding variables:

    assign( soln );
    x, y; # 2, 1

    This won't work for solutions of differential equations:

    sys := { D(x)(t) = y(t), D(y)(t) = -x(t), x(0) = 1, y(0) = 0 };
    soln := dsolve( sys ); # { x(t) = cos(t), y(t) = -sin(t) }
    assign( soln );
    x(s), y(s); # plain x(s) and y(s)

    To make this work, we wrote this multi-purpose routine:

    # Type for a variable expression, e.g. x=5.
    TypeTools:-AddType( 'varexpr', u -> type( u, 'And'('name','Non'('constant'))='algebraic' ) ):
    # Type for a function expression, e.g. f(x)=x^2.
    TypeTools:-AddType( 'funcexpr', u -> type( u, 'function'('And'('name','Non'('constant')))='algebraic' ) ):
    # Procedure to assign variable and function expressions.
    my_assign := proc( u :: {
            varexpr, 'list'(varexpr), 'rtable'(varexpr), 'set'(varexpr),
            funcexpr, 'list'(funcexpr), 'rtable'(funcexpr), 'set'(funcexpr)
    }, $ )
            local F, L, R, V:       
            # Map the procedure if input is a data container, or apply regular assign(), where applicable.
            if not u :: {'varexpr','funcexpr'} then
                   map( procname, u ):
                   return NULL:
            elif u :: 'varexpr' then
                   assign( u ):
                   return NULL:
            end if:       
            L, R := lhs(u), rhs(u):
            F := op(0,L): 
            V := [ indets( L, 'And'( 'name', 'Non'('constant') ) )[] ]:    
            map( assign, F, unapply( R, V ) ):
            return NULL:
    end proc:
    # Example 1.
    eqs := { x + y = 3, x - y = 1 };
    my_assign( solve( eqs ) );
    'x' = x, 'y' = y; # x=1, y=2
    # Example 2.
    unassign( 'x', 'y' ):
    E := [ f(x,y) = x + y, g(x,y) = x - y ];
    my_assign( E );
    'f(u,v)' = f(u,v), 'g(u,v)' = g(u,v); # f(u,v)=u+v, g(u,v)=u-v
    # Example 3.
    sys := { D(x)(t) = y(t), D(y)(t) = -x(t), x(0) = 1, y(0) = 0 };
    soln := dsolve( sys );
    my_assign( soln ):
    'x(s)' = x(s); # x(s)=cos(s)
    'y(s)' = y(s); # y(s)=-sin(s)

    Fourteen year old Lazar Paroski is an exceptional student. Not only is he an overachiever academically, but he has a passion to help struggling students, and to think of innovative ways to help them learn. Lazar is particularly fond of Math, and in his interactions with other students, he noticed how students have a hard time with Math.

    Putting on his creative cap, Lazar came up with the idea of an easily accessible “Math Wall” that explains simple math concepts for students in a very visual way.

    “The Music Wall on Pinterest was my inspiration,” says Lazar. “I thought I can use the same idea for Math, and why not a Math Wall”?

    "The math wall is basically all the tools you'll have on the wall in your classroom outside," said Lazar. Making the Math Wall and getting it set up, took time and effort. But he had help along the way, which, fueled by his passion and enthusiasm, helped turn his creative dream into reality. Lazar received a grant of $6000 from the local government to implement the project; his teachers, principal and family helped promote it; and the community of parents provided encouragement.

    The Math Wall covers fundamental math concepts learnt in grades 1 to 6. Lazar engaged with over 450 students in the community to understand what would really be helpful for students to see in this Math Wall, and then he carefully picked the top themes he wanted to focus on.

    The three meter Math Wall is located in the Morrison community park, and was officially inaugurated by the Mayor of Kitchener in July 2018. Many students have already found it to be useful and educative. Parents who bring their children to the park stop by to give their kids a quick math lesson.

    At Maplesoft, we love a math story like this! And that too in our backyard! We wanted to appreciate and encourage Lazar and his efforts in making math fun and easy and accessible to students. So we invited Lazar to our offices, gifted him a copy of Maple, and heard more about his passion and future plans. “In many ways, Lazar embodies the same qualities that Maplesoft stands for – making it easy for students to understand and grasp complex STEM concepts,” said Laurent Bernardin, Maplesoft’s Chief Operating Officer. “We try to impress upon students that math matters, even in everyday life, and they can now use advanced, sophisticated technology tools to make math learning fun and efficient.”

    We wish Lazar all the very best as he thinks up new and innovative ways to spread his love for math to other kids. Well done, Lazar!



    You might recall this image being shared on social media some time ago.


    Look closely and you see Albert Einstein. However, if you move further away (or make the image smaller), you see Marilyn Monroe.

    To create the image, the high spatial frequency data from an image of Albert Einstein was added to the low spatial frequency data from an image of Marilyn Monroe. This approach was pioneered by Oliva et al. (2006) and is influenced by the multiscale processing of human vision.

    • When we view objects near us, we see fine detail (that is, higher spatial frequencies dominate).

    • However, when we view objects at a distance, the broad outline has greater influence (that is, lower spatial frequencies dominate).

    I thought I'd try to create a similar image in Maple (get the complete application here).

    Here's an overview of the approach (as outlined in Oliva et al., 2006). I used different source images of Einstein and Monroe.

    Let's start by loading some packages and defining a few procedures.

    fft_shift := proc(M)
       local nRows, nCols, quad_1, quad_2, quad_3, quad_4, cRows, cCols;
       nRows, nCols := LinearAlgebra:-Dimensions(M):
       cRows, cCols := ceil(nRows/2), ceil(nCols/2):
       quad_1 := M[1..cRows,      1..cCols]:
       quad_2 := M[1..cRows,      cCols + 1..-1]:  
       quad_3 := M[cRows + 1..-1, cCols + 1..-1]:
       quad_4 := M[cRows + 1..-1, 1..cCols]:
       return <<quad_3, quad_2 |quad_4, quad_1>>:
    end proc:
    PowerSpectrum2D := proc(M)
       return sqrt~(abs~(M))
    end proc:
    gaussian_filter := (a, b, sigma) -> Matrix(2 * a, 2 * b, (i, j) -> evalf(exp(-((i - a)^2 + (j - b)^2) / (2 * sigma^2))), datatype = float[8]):

    fft_shift() swaps quadrants of a 2D Fourier transform around so that the zero frequency components are in the center.

    PowerSpectrum2D() returns the spectra of a 2D Fourier transform

    gaussian_filter() will be used to apply a high or low-pass filter in the frequency domain (a and b are the number of rows and columns in the 2D Fourier transform, and sigma is the cut-off frequency.

    Now let's import and display the original Einstein and Monroe images (both are the same size).

    einstein_img := Read("einstein.png")[..,..,1]:

    marilyn_img  := Read("monroe.png")[..,..,1]:

    Let's convert both images to the spatial frequency domain (not many people know that SignalProcessing:-FFT can calculate the Fourier transform of matrices).

    einstein_fourier := fft_shift(FFT(einstein_img)):
    monroe_fourier   := fft_shift(FFT(monroe_img)):

    Visualizing the power spectra of the unfiltered and filtered images isn't necessary, but helps illustrate what we're doing in the frequency domain.

    First the spectra of the Einstein image. Lower frequency data is near the center, while higher frequency data is further away from the center.


    Now the spectra of the Monroe image.


    Now we need to filter the frequency content of both images.

    First, define the cutoff frequencies for the high and low pass Gaussian filters.

    sigma_einstein := 25:
    sigma_monroe   := 10:

    In the frequency domain, apply a high pass filter to the Einstein image, and a low pass filter to the Monroe image.

    nRows, nCols := LinearAlgebra:-Dimension(einstein_img):
    einstein_fourier_high_pass := einstein_fourier *~ (1 -~ gaussian_filter(nRows/2, nCols/2, sigma_einstein)):
    monroe_fourier_low_pass    := monroe_fourier   *~ gaussian_filter(nRows/2, nCols/2, sigma_monroe):

    Here's the spectra of the Einstein and Monroe images after the filtering (compare these to the pre-filtered spectra above).



    Before combining both images in the Fourier domain, let's look the individual filtered images.

    einstein_high_pass_img := Re~(InverseFFT(fft_shift(einstein_fourier_high_pass))):
    monroe_low_pass_img    := Re~(InverseFFT(fft_shift(monroe_fourier_low_pass))):

    We're left with sharp detail in the Einstein image.


    But the Monroe image is blurry, with only lower spatial frequency data.


    For the final image, we're simply going to add the Fourier transforms of both filtered images, and invert to the spatial domain.

    hybrid_image := Create(Re~(InverseFFT(fft_shift(monroe_fourier_low_pass + einstein_fourier_high_pass)))):

    So that's our final image, and has a similar property to the hybrid image at the top of this post.

    • Move close to the computer monitor and you see Albert Einstein.
    • Move to the other side of the room, and Marilyn Monroe swims into vision (if you're myopic, just take off your glasses and don't move back as much).

    To simulate this, here, I've successively reduced the size of the hybrid image

    And just because I can, here's a hybrid image of a cat and a dog, generated by the same worksheet.

    Set of vector mechanics exercises in the plane and space using the result technique in line (combining the key ALT + ENTER) also the unit package using the law of the triangle. It is observed that the solution is totally optimal. I leave your constructive criticism to the community's criteria. I hope that someone will raise an alternative solution using the minimum number of lines but that the students will learn. In spanish.

    Lenin Araujo Castillo

    Ambassador of Maple

    Important use of the embedded components called Shortcut applied to vector mechanics exercises for engineering students. This makes each solution of each problem open independently and thus this way to explain in class. To use this worksheet, first unzip all the files in a single folder. In spanish

    Lenin Araujo Castillo

    Ambassador of Maple

    If one looks in the profile of Rouben Rostamian , then one sees that any search in his Posts, Questions, Answers, and Replies is linked with MaplePrimes only. I informed  MaplePrimes staff about that disturbance without any effect. Using the opportunity, I'd like to pay attention of MaplePrimes users to many clones in the forum. This is a problem for ages: clones vote up themselves and impose one's opinion on  others. Several years ago some clones were deleted. It would be nice to continue that process.

    I have recently visited the Queen's House at Greenwich  (see wiki),  an  important building in British architectural history (17th century).
    I was impressed by the Great Hall Floor, whose central geometric decoration seems to be generated by a Maple program :-)

    Here is my code for this. I hope you will like it.

    with(plots): with(plottools):
    n:=32: m:=3:#    n:=64: m:=7:
    a[0], b[0] := exp(-Pi*I/n), exp(Pi*I/n):
    for k to m+1 do  
      a[k]:=conjugate(b[k])  od:
    seq( map[inplace](evalf@[Re,Im], w), w=[a,b,c] ):
    Q:=polygonplot([seq([a[k],c[k],b[k],c[k+1]],k=0..m-1), [c[m],a[m],b[m]], [a[-1],b[-1],c[0]]]):
    display(seq(rotate(Q, 2*k*Pi/n, [0,0]),k=0..n-1), disk([0,0],c[m][1]/3), axes=none, size=[800,800], color=black);

    Avatar images are displayed with fixed size. When scaling the font, the title is offended by the avatar image. Please change this behaviour.

    In this app you can visualize the location of the points in the different quadrants, also calculate the distance between two points. Finally the calculation of the coordinates of the midpoint. With these applications can be combined to study different cases between distance between two points and midpoint. Generated in Maple for students of secondary education and pre-calculation. In Spanish

    Lenin Araujo Castillo

    Ambassador of Maple


    First 34 35 36 37 38 39 40 Last Page 36 of 297