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
  • In the book by W.G. Chinn, N.E. Steenrod "First Concepts of Topology" the another remarkable theorem was proved: any two flat bounded regions can be cut by a single straight line so that each of these regions is divided into two regions of equal area (the second  pancake problem). This is an existence theorem which does not provide any way to find this cut. In this post I made an attempt to find such cut for any 2 convex regions on the plane bounded by a piecewise smooth self-non-intersecting curves.
    The Each_Into_2_Equal_Areas procedure returns a list of coordinates of 4 endpoints of the cutting segments. This procedure significantly uses my old procedures  Area  and  Picture , which can be found in detail at the link  https://mapleprimes.com/posts/145922-Perimeter-Area-And-Visualization-Of-A-Plane-Figure-  . The formal arguments of the Each_Into_2_Equal_Areas procedure are the lists  L1  and  L2 specifying the boundaries of the regions to be cut. When specifying  L1  and  L2 , the boundary can be passed clockwise or counterclockwise, but it is necessary that the parameter t (when specifying each link) should go in ascending order. This can always be achieved by replacing  t  with  -t  if necessary. The Pic procedure draws a picture of the source regions and cutting segments. For ease of use, the code for the  Area  and  Picture   procedure is also provided. It is also worth noting that the procedure also works for "not too" non-convex regions (see examples below).

    restart;
    Area := proc(L) 
    local i, var, e, e1, e2, P; 
    for i to nops(L) do 
    if type(L[i], listlist(algebraic)) then 
    P[i] := (1/2)*add(L[i, j, 1]*L[i, j+1, 2]-L[i, j, 2]*L[i, j+1, 1], j = 1 .. nops(L[i])-1) else 
    var := lhs(L[i, 2]); 
    if type(L[i, 1], algebraic) then e := L[i, 1]; 
    if nops(L[i]) = 3 then P[i] := (1/2)*(int(e^2, L[i, 2])) else 
    if var = y then P[i] := (1/2)*simplify(int(e-var*(diff(e, var)), L[i, 2])) else 
    P[i] := (1/2)*simplify(int(var*(diff(e, var))-e, L[i, 2])) end if end if else e1 := L[i, 1, 1]; e2 := L[i, 1, 2]; 
    P[i] := (1/2)*simplify(int(e1*(diff(e2, var))-e2*(diff(e1, var)), L[i, 2])) end if end if end do; 
    abs(add(P[i], i = 1 .. nops(L))); 
    end proc:
    
    Picture := proc(L, C, N::posint := 100, Boundary::list := [linestyle = 1]) 
    local i, var, var1, var2, e, e1, e2, P, Q, h; 
    global Border;
    uses plottools; 
    for i to nops(L) do 
    if type(L[i], listlist(algebraic)) then P[i] := op(L[i]) else 
    var := lhs(L[i, 2]); var1 := lhs(rhs(L[i, 2])); var2 := rhs(rhs(L[i, 2])); h := (var2-var1)/N; 
    if type(L[i, 1], algebraic) then e := L[i, 1]; 
    if nops(L[i]) = 3 then P[i] := seq(subs(var = var1+h*i, [e*cos(var), e*sin(var)]), i = 0 .. N) else 
    P[i] := seq([var1+h*i, subs(var = var1+h*i, e)], i = 0 .. N) fi else e1 := L[i, 1, 1]; e2 := L[i, 1, 2]; P[i] := seq(subs(var = var1+h*i, [e1, e2]), i = 0 .. N) fi; fi; od; 
    Q := [seq(P[i], i = 1 .. nops(L))]; Border := curve([op(Q), Q[1]], op(Boundary)); [polygon(Q, C), Border] 
    end proc:
    
    Each_Into_2_Equal_Areas:=proc(L1::list, L2::list)
    local D, n, m, L10, L20, S1,S2, f, L11, L21, i, j, k, s, A, B, C , sol;
    
    f:=(X,Y)->expand((y-X[2])*(Y[1]-X[1])-(x-X[1])*(Y[2]-X[2]));
    L10:=map(p->`if`(type(p,listlist),[[p[1,1]+t*(p[2]-p[1])[1],p[1,2]+t*(p[2]-p[1])[2]],t=0..1],p), L1);
    L20:=map(p->`if`(type(p,listlist),[[p[1,1]+t*(p[2]-p[1])[1],p[1,2]+t*(p[2]-p[1])[2]],t=0..1],p), L2);
    S1:=Area(L1); S2:=Area(L2);  
    n:=nops(L1); m:=nops(L2);
    
    for i from 1 to n do
    for j from i to n do
    
    for k from 1 to m do
    for s from k to m do
    
    if not ((nops({i,j})=1 and type(L1[i],listlist)) or (nops({k,s})=1 and type(L2[k],listlist))) then
    
    A:=eval(L10[i,1],t=t1): 
    B:=eval(L10[j,1],t=t2):
    C:=eval(L20[k,1],t=t3): 
    D:=eval(L20[s,1],t=t4):
    
    L11:=`if`(j=i,[subsop([2,2]=t1..t2,L10[i]),[B,A]],`if`(j=i+1,[subsop([2,2]=t1..op([2,2,2],L10[i]),L10[i]),subsop([2,2]=op([2,2,1],L10[j])..t2,L10[j]),[B,A]], [subsop([2,2]=t1..op([2,2,2],L10[i]),L10[i]),op(L10[i+1..j-1]),subsop([2,2]=op([2,2,1],L10[j])..t2,L10[j]),[B,A]])):
    
    L21:=`if`(s=k,[subsop([2,2]=t3..t4,L20[k]),[D,C]],`if`(s=k+1,[subsop([2,2]=t3..op([2,2,2],L20[k]),L20[k]),subsop([2,2]=op([2,2,1],L20[s])..t4,L20[s]),[D,C]], [subsop([2,2]=t3..op([2,2,2],L20[k]),L20[k]),op(L20[k+1..s-1]),subsop([2,2]=op([2,2,1],L20[s])..t4,L20[s]),[D,C]])):
    
    sol:=fsolve(simplify({Area(L11)-S1/2,Area(L21)-S2/2,eval(f(A,B),[x=C[1],y=C[2]]),eval(f(A,B),[x=D[1],y=D[2]])}),{t1=op([2,2,1],L10[i])..op([2,2,2],L10[i]),t2=op([2,2,1],L10[j])..op([2,2,2],L10[j]),t3=op([2,2,1],L20[k])..op([2,2,2],L20[k]),t4=op([2,2,1],L20[s])..op([2,2,2],L20[s])});
    
    if type(sol,set(`=`)) then  return eval([A,B,C,D],sol) fi;
    
    fi;
    od: od: od: od:
    end proc:
    
    Pic := proc(L1,L2,col1,col2,Size:=[800,400])
    local P1, P2, P3, T, P;
    uses plots, plottools;
    P1, P2 := Picture(L1, color=col1), Picture(L2, color=col2):
    P3 := line(Sol[1..2][],color=red,thickness=3), line(Sol[3..4][],color=red,thickness=3), line(Sol[1],Sol[4],linestyle=2,thickness=3,color=red):
    T:=textplot([[Sol[1][],"A"],[Sol[2][],"B"],[Sol[3][],"C"],[Sol[4][],"D"]], font=[times,18], align=[left,above]);
    P:=pointplot(Sol, symbol=solidcircle, color=red, symbolsize=10);
    display(P1,P2,P3,T,P, scaling=constrained, size=Size, axes=none);
    end proc: 
    


    Examples of use.

    local D:
    L1:=[[[8,0],[6,7]],[[6,7],[2,5]],[[2,5],[0,2]],[[0,2],[0,0]],[[0,0],[8,0]]]:
    L2:=[[[5*cos(t)+16,5*sin(t)],t=Pi/2..Pi],[[5*cos(t)+16,5*sin(t)/2],t=Pi..2*Pi],[[21,0],[16,5]]]:
    Sol:=Each_Into_2_Equal_Areas(L1,L2): Points:=[A,B,C,D]:
    seq(Points[i]=Sol[i], i=1..4);
    Pic(L1,L2,"Yellow","LightBlue",[900,400]);
    

       

    The specified regions may overlap:

    L1:=[[[8,0],[6,7]],[[6,7],[2,5]],[[2,5],[0,2]],[[0,2],[0,0]],[[0,0],[8,0]]]:
    L2:=[[[5*cos(t)+9,5*sin(t)],t=Pi/2..Pi],[[5*cos(t)+9,5*sin(t)/2],t=Pi..2*Pi],[[14,0],[9,5]]]:
    Sol:=Each_Into_2_Equal_Areas(L1,L2):  Points:=[A,B,C,D]:
    seq(Points[i]=Sol[i], i=1..4);
    Pic(L1,L2,"Yellow","LightBlue");
    

       


    If there is a solution for which the cutting segments intersect the boundary of each of the regions at 2 points, then the procedure also works for such non-convex regions:

    L1:=[[[cos(t),sin(t)],t=Pi/3..2*Pi-Pi/3],[[cos(-t)+1,sin(-t)],t=-Pi-Pi/3..-Pi+Pi/3]]:
    L2:=[[[cos(t)+2,sin(t)],t=-Pi/6..Pi+Pi/6],[[cos(-t)+2,sin(-t)-1],t=-5*Pi/6..-Pi/6]]:
    Sol:=Each_Into_2_Equal_Areas(L1,L2): Points:=[A,B,C,D]:
    seq(Points[i]=Sol[i], i=1..4);
    Pic(L1,L2,"Yellow","LightBlue");
    

       


    A number of other interesting examples can be found in the attached file.

    Each_Into_2_Equal_Areas1.mw

    After a long chat with ChatGPT I finally received a fully working code for a proc for a generalized Woodbury Identity for the inversion of the sum of two or more positive definite matrices.
    I was inspired by a family member who is a trained professional programmer, who told me that in his professional work he uses ChatGTP for an initial draft of his program.  
    I did find out that ChatGTP makes errors: from simple ones like writing 'Simplify' instead of 'simplify' to serious conceptual errors, for example in recursive loops. However, ChatGTP seems to 'understand' the error after given specific feedback. Although, this does not mean that the next proposal does not contain the same logical error. But after a long chat I received a nice proc that seems to work. 
    My second surprise was that Gemini suggested a formula for the generalized Woodbury lemma that was unknown to me, and I was unable to find on Scholar Google or https://math.stackexchange.com. Based on a special case of that formula, I was able to write the second proc myself. 
    In conclusion, to start working it can be helpful to collaborate with AI friend, a little patience may help, AI may not be astute as someone on Mapleprimes wrote, but neither am I. I am now retired, and it is fun to play with Maple and AI. 
    By the way, the search term Woodbury did not give a single hit on Mapleprimes.With_a_little_help_from_my_friends.mw
    kind regards,Harry 

     

    Greetings, dear Maple developers!

    I, Yegor Volovodenko, together with my supervisor, Igor Zinoviev, Associate Professor, Head of the Department of General Mathematics at ZNU, am conducting research on ‘Solving equations and inequalities of elementary mathematics by means of computer mathematics: opportunities, problems and ways to solve them’. I express my sincere gratitude for your work on the development and popularisation of mathematics, for the constant improvement and enhancement of CAS in particular.

    Unfortunately, during the study, we found some, in our opinion, shortcomings in the work of Maxima algorithms for solving elementary equations and inequalities

    1. Solving equations with parameters;



      In these two cases, the solution obtained is formal, without analysing the cases when the coefficient of a variable is zero. Thus, not all solutions of equations with a parameter are obtained. I believe that if the user is not familiar with the methodology for solving equations with parameters, he or she may lose some solutions that may be important for further work. So the solution can be considered incomplete.

     

    1. Solving equations with two variables.
       

    In the equation with two variables, the answer was given in complex numbers, which is incomprehensible to a person who is not familiar with complex numbers. There are also comments on the course of the solution, in this equation it was necessary to select the square of the difference, and then solve the equation x^2+(y-2)^2=0, getting x=0, y=2.

    I hope that the results I have obtained (the identified shortcomings) will help to correct the work of the algorithms and improve the work of the Maple system.

    Sincerely, Yegor Volovodenko, Igor Zinoviev.

     

     

    For Maple 17, in 2013, we introduced the GroupTheory package. It has seen a lot of improvements since its introduction, and I figured I would write something about how you can use it to teach a group theory course.

     

    First of all, I think it would be a great idea to have your students just play with the GroupTheory package in Maple, and get some intuition for what makes group theory tick by getting their hands dirty. But that is not what I want to talk about today. Instead, I want to discuss how you might use it for giving your lectures - to show some visualizations while you show your beamer presentation or write on the black- or whiteboard.

     

    When starting out with the definition of a group, you might want to compare the Cayley table of a group with that of a binary operation that doesn't define a group. A set with any binary operation is called a magma; to find good examples, we might want to use one group; one magma that has an identity and is associative but not invertible; and one magma that is has an identity and is invertible but not associative. Maybe we also want the group to not be cyclic (so the group order will have to not be prime), because those Cayley tables look a little boring. For this we can use the Magma package.

     

    We note that a magma that is invertible and has an identity element is called a loop. We can enumerate all magmas of a given order and with certain properties using the command Magma:-Enumerate, finding either the number of such objects (by default) or a list of the multiplication tables (with the output = list option). Can we find interesting examples of order 4?

     

    with(Magma)

    Enumerate(4, group), Enumerate(4, loop), Enumerate(4, associative, identity)

    2, 2, 35

    (1)

     

    No: all loops of order 4 are groups. Let's try order 6.

     

    Enumerate(6, group), Enumerate(6, loop), Enumerate(6, associative, identity)

    2, 109, 2237

    (2)

     

    Yes, we can find examples here. We find the Cayley tables of three suitable magmas; we call the non-cyclic group one m1, the non-associative loop one m2, and the non-invertible magma m3.

     

    Enumerate(6, group, output = list)

    (3)

    "m1 := ?[2]:"

    Enumerate(6, loop, output = list)[1 .. 5]

    (4)

     

    "m2 := ?[2]:"

    Enumerate(6, associative, identity, output = list)[1 .. 5]

    (5)

     

    Most of these appear to have many more of one value than of another (e.g., many more threes). Let's find one where that is not so extreme. For example, we might want to minimize the standard deviation of the frequencies of the values occurring in the Cayley table.

     

    lst := Enumerate(6, associative, identity, output = list)

    lst := remove(IsLeftInvertible, lst)

    numelems(lst)

    2235

    (6)

    frequencies := map(proc (m) options operator, arrow; map2(numboccur, m, [seq(1 .. 6)]) end proc, lst)``

    with(Statistics)

    sds := map(StandardDeviation, convert(frequencies, 'set'))

    {HFloat(2.449489742783178), HFloat(3.0983866769659336), HFloat(3.1622776601683795), HFloat(3.22490309931942), HFloat(3.286335345030997), HFloat(3.3466401061363027), HFloat(3.4058772731852804), HFloat(3.4641016151377544), HFloat(3.464101615137755), HFloat(3.521363372331802), HFloat(3.5213633723318023), HFloat(3.5777087639996634), HFloat(3.6331804249169903), HFloat(3.687817782917155), HFloat(3.7416573867739413), HFloat(3.794733192202055), HFloat(3.8470768123342687), HFloat(3.847076812334269), HFloat(3.898717737923586), HFloat(3.9496835316262997), HFloat(3.9496835316263), HFloat(3.9999999999999996), HFloat(4.0), HFloat(4.049691346263318), HFloat(4.09878030638384), HFloat(4.147288270665544), HFloat(4.195235392680606), HFloat(4.1952353926806065), HFloat(4.2895221179054435), HFloat(4.33589667773576), HFloat(4.3817804600413295), HFloat(4.427188724235731), HFloat(4.47213595499958), HFloat(4.5166359162544865), HFloat(4.560701700396552), HFloat(4.604345773288535), HFloat(4.604345773288536), HFloat(4.6475800154489), HFloat(4.69041575982343), HFloat(4.732863826479693), HFloat(4.774934554525329), HFloat(4.77493455452533), HFloat(4.8166378315169185), HFloat(4.857983120596447), HFloat(4.898979485566356), HFloat(4.9396356140913875), HFloat(4.939635614091388), HFloat(4.979959839195493), HFloat(5.019960159204453), HFloat(5.059644256269407), HFloat(5.0990195135927845), HFloat(5.138093031466052), HFloat(5.176871642217914), HFloat(5.215361924162119), HFloat(5.253570214625479), HFloat(5.291502622129181), HFloat(5.329165037789691), HFloat(5.366563145999495), HFloat(5.403702434442518), HFloat(5.440588203494177), HFloat(5.477225575051661), HFloat(5.513619500836089), HFloat(5.549774770204643), HFloat(5.585696017507577), HFloat(5.621387729022079), HFloat(5.656854249492381), HFloat(5.692099788303083), HFloat(5.727128425310542), HFloat(5.761944116355173), HFloat(5.796550698475776), HFloat(5.830951894845301), HFloat(5.865151319446072), HFloat(5.8991524815010505), HFloat(5.93295878967653), HFloat(5.932958789676531), HFloat(5.966573556070519), HFloat(6.0), HFloat(6.0332412515993425), HFloat(6.066300355241241), HFloat(6.066300355241242), HFloat(6.099180272790763), HFloat(6.131883886702357), HFloat(6.164414002968976), HFloat(6.196773353931867), HFloat(6.228964600958975), HFloat(6.260990336999411), HFloat(6.29285308902091), HFloat(6.324555320336759), HFloat(6.356099432828282), HFloat(6.418722614352485), HFloat(6.48074069840786), HFloat(6.511528238439883), HFloat(6.542170893518451), HFloat(6.572670690061994), HFloat(6.603029607687671), HFloat(6.603029607687672), HFloat(6.6332495807108), HFloat(6.663332499583073), HFloat(6.6932802122726045), HFloat(6.693280212272605), HFloat(6.723094525588644), HFloat(6.723094525588645), HFloat(6.752777206453653), HFloat(6.782329983125268), HFloat(6.811754546370561), HFloat(6.928203230275509), HFloat(6.957010852370435), HFloat(6.985699678629192), HFloat(7.014271166700073), HFloat(7.042726744663604), HFloat(7.0710678118654755), HFloat(7.127411872482185), HFloat(7.155417527999327), HFloat(7.183313998427188), HFloat(7.18331399842719), HFloat(7.293833011524188), HFloat(7.429670248402684), HFloat(7.4565407529228995), HFloat(7.4565407529229), HFloat(7.483314773547883), HFloat(7.536577472566709), HFloat(7.53657747256671), HFloat(7.563068160475615), HFloat(7.64198926981712), HFloat(7.77174369109018), HFloat(7.8993670632526), HFloat(7.92464510246358), HFloat(7.9498427657407165), HFloat(8.024961059095553), HFloat(8.12403840463596), HFloat(8.366600265340756), HFloat(8.390470785361211), HFloat(8.390470785361213), HFloat(8.414273587185052), HFloat(8.438009243891594), HFloat(8.508818954473059), HFloat(8.854377448471462), HFloat(8.87693640846886), HFloat(8.921883209278185), HFloat(9.338094023943), HFloat(9.338094023943002), HFloat(9.359487165438072), HFloat(9.81835016690686), HFloat(9.818350166906862), HFloat(10.295630140987)}

    (7)

     

    Aha, the smallest standard deviation is a bit under two and a half, and the next possible value is greater than 3. Let's examine the Cayley tables that show this standard deviation.

    NULL

    small_sd_index := select(proc (i) options operator, arrow; StandardDeviation(frequencies[i]) < 3 end proc, [seq(1 .. numelems(frequencies))])

    [1636, 1638, 2234, 2235]

    (8)

    small_sd := lst[small_sd_index]

    (9)

     

    The last of these looks interesting.

     

    m3 := small_sd[-1]

    NULL

    Now we can display these three Cayley tables:

    CayleyColorTable(m1); CayleyColorTable(m2); CayleyColorTable(m3)

     

    It's clear that the multiplication shown in the third Cayley table is not invertible (because multiplying by any element other than 1, on either side, is not a permutation of the elements: rows and columns beyond the first don't have all colors). It's less visually obvious that the second Cayley table doesn't show an associative multiplication, but a quick loop showed that 5*(3*3) = 5*5 and 5*5 = 4 whereas 3*(3*5) = 3 and 3 = 3. I'm not sure if there is something real underpinning this, but to my mind this is a nice parallel to the fact that when you're proving a set with a given operation is a group, it's easier to show that there are inverses than that the operation is associative.

     

    A second nice visualization, also usable in the first week or two of a group theory course, is also named after Cayley: Cayley graphs. Here is a Cayley graph for the dihedral group D[3] of order 6:

     

    with(GroupTheory)

    D3 := DihedralGroup(3)

    _m132248572811840

    (10)

    with(GraphTheory)

    DrawGraph(CayleyGraph(D3), layout = spring)

     

    NULL

    Here is a well-known presentation of the alternating group on 4 letters. I find "grabbing and turning" the 3D plot shows the structure much better than simply an embedding of the graph in the plane.

     

    a4 := `<|>`(`<,>`(a, b), `<,>`(a^3, b^2, a.b.a = b.(a^2).b))

    _m132249105458016

    (11)

    DrawGraph(CayleyGraph(a4), layout = spring, dimension = 3, size = [800, 800])

     

     

    Another great opportunity for a visualization comes a couple of weeks later, when you talk about subgroup lattices. Here are a few examples:

     

    with(GroupTheory)``

    qd := QuasiDihedralGroup(2)

    _m132249751531168

    (12)

    GroupOrder(qd)

    16

    (13)

    DrawSubgroupLattice(qd, normal = false, center = false)

     

     

    This is the plain subgroup lattice. Note how the subgroups in the first and second nontrivial "layer" from the bottom are grouped by conjugacy class. The default visualization of a subgroup lattice highlights the centre in light blue and the (in this case six) other normal subgroups in green.

     

    DrawSubgroupLattice(qd)

     

     

    We see that every conjugacy class of size one is a normal subgroup. We can also highlight other subgroups, if we want. Maybe we want to show which are the (cyclic) subgroups generated by one of the chosen generators:

     

    generators := Generators(qd)

    [_m132249751506336, _m132249751509600]

    (14)

    DrawSubgroupLattice(qd, highlight = [seq({g}, `in`(g, generators))])

     

     

    Of course you can also show more advanced topics in this way. For example, here is the Frattini series of this group.

     

    DrawSubgroupLattice(qd, highlight = FrattiniSeries(qd))

     

    NULL NULL


     

    Download blogpost-algebra.mw

    Recently, a local Math olympiad included the following problem:

     

     

     Compute:Limit(n*(Int(x^n/(x^n+x+2024), x = 0 .. 1)), n = infinity).

     

     

    I was almost sure that Maple can compute it, but unfortunately it needed help!

    restart;

    J:=n->n*int(x^n/(x^n+x+2024),x=0..1);

    proc (n) options operator, arrow; n*(int(x^n/(x^n+x+2024), x = 0 .. 1)) end proc

    (1)

    limit(J(n), n=infinity); # Maple gives up.

    limit(n*(int(x^n/(x^n+x+2024), x = 0 .. 1)), n = infinity)

    (2)

    simplify(IntegrationTools:-Change(J(n), x=t^(1/n), t)) assuming n>1;

    int(t^(1/n)/(t+t^(1/n)+2024), t = 0 .. 1)

    (3)

    ans:=limit(%, n=infinity);

    ln(2)+ln(1013)-4*ln(3)-2*ln(5)

    (4)

    #map(combine,ans, ln);

    combine(ans,ln, integer);

    4*ln((1/15)*2026^(1/4)*5^(1/2))

    (5)

    ln(exp(%)); # should be obtainable with convert

    ln(2026/2025)

    (6)

    evalf(% = J(100)); # sanity check;

    0.4937051076e-3 = 0.488824e-3+0.*I

    (7)


    Download lim-int-vv.mw

    Try it yourself, you will understand what I mean. (MF2024.2.1)

     

    Referring to the screenshots, "J" can be converted to "N m" in MF2024.1, but not in M2024.2.
    Is this some sort of bug in M2024.2?

     

     

    Just around a month after the first release I am glad to announce the second public release of this project.

    Changes from last release:

    • added angled cuts to beam ends
    • fixed bug for bolt connections with thick steel plates
    • rewrite check if fasteners are placed within beams
    • removed some obsolete procedures in NODEFunctions
    • minor changes in XML file headers

    For more information see https://github.com/Anthrazit68/NODEMaple.

    With the new release of Maple Flow 2024.2 the units "Area" and "Speed" don't work.

    I run a MaxBook Pro with macOS Sequoia 15.2 and uninstalled MF2024.2.

     

    Keywords: Intermediate axis theorem, Tennis racket theorem, Dzhanibekov effect, Coriolis force, Euler equations

    In 1988 I witnesses the instability of the rotation about the intermediate axis of a foam brick.

    Since then I have been fascinated by this effect. It was one of the many experiments which enriched a lecture series on kinetics and on that day Euler equations were on the agenda. Colored surfaces of the brick made it possible to observe the effect without micro gravity and slow-motion equipment.

    This post is about reproducing an “intuitive” visualization of an explanation of the effect by Terry Tao from 2011 using 4 rigidly connected point masses. 8 years later the explanation was animated in a YouTube video (The Bizarre Behavior of Rotating Bodies) and considered to be the “best intuitive” explanation.

    Motivated by the video, I wondered whether a similar animation with acting forces is possible with MapleSoft products and whether there might be a better intuitive explanation without the use of centrifugal forces. Initially I saw this more as a good test of MapleSim’s visualization capabilities. Finally, it took over 3 years and numerous attempts (mostly during vacation, kind of a substitute for drawing circles in the sand...) to come to a conclusion on the effect.

    Intermediate_axis_theoreme_with_3_point_masses.msim


    About the model:

    Unlike the YouTube video, I decided to simulate 3 identical point masses because a 3-mass model fits better to a T-handle (overlayed in the animation above), video footage from space experiments and discussions in this forum (221298, 225760, 228066).

    The movement of the model generates acceleration forces on each mass. The clip displays the corresponding opposing forces that act in the model (i.e. act on the massless T-structure). The blue mass, which is not perfectly centered on the axis of rotation at the start of the simulation perturbs the orbits of the red and the green masses. That was my initial intuitive attempt to explain the effect.

    The 3 masses form an isosceles triangle. Here it is helpful to think of a rotating arrowhead where the shape determines stability of the rotation. The aspect ratio (the ratio of the height to the base length) of the triangle determines the stability of rotation about the mirror symmetry axis of the triangle (i.e. the symmetry axis of the T-structure). An obtuse triangle (“blunt”, aspect ratio < sqrt(3)/2) is unstable when rotating about an axis that is slightly inclined with respect to this axis of symmetry. The inclination can be in the plane of the triangle or out of plane. An acute (“pointy”) triangle only wobbles.

    About the MapleSim model:

    A supplementary rigid body component without mass and rotational inertia is used at the center of mass of the three masses to impose initial conditions. Rotating the triangle at the start of the simulation about the center of mass of the 3 masses prevents the triangle from drifting laterally away from its initial position. This effect of lateral drift is visible in video footage from space with the T-handle.

    The rotational inertia of the other rigid body components is set to zero. Without rotational inertia it could be assumed that only Newtonian mechanics are used in the simulation (i.e. no Euler equations are integrated). This is however wrong. MapleSim generates automatically from a system with 3x6=18 coordinates a system with 3 Newtonian equations for translation and 3 Euler equations for rotation.

    Forces and moments are measured with sensor components. Visualization is done with force and moment visualization components. These components are “abused” to display the following other physical quantities:

    The angular momentum of the masses

    The vectors of the angular velocity and the angular acceleration

    Moments of the forces with respect to the center of mass

    Moments of the forces with respect to the center of the base of the triangle

    For a clean model, sensor components and mathematical components to calculate physical quantities are grouped in three subsystems (one per mass, indicated with a colored dot in the image below).

    The model contains parameter sets for in plane and out of plane inclination of the axis of the T with respect to the initial axis of rotation (the x-axis).

    Ein Bild, das Diagramm, Text, Screenshot, Plan enthält.

Automatisch generierte Beschreibung 

    Visualization of physical components can be turned on by enabling the corresponding subsystems which are labeled accordingly (in the image above the display of the angular momentum is enabled). The subsystem “Verification” computes quantities that should either be conserved or should be equal to zero.  Calculation of quantities is done with MapleSim’s mathematical components (i.e. no embedded code or custom components are used).

     

    Some observations

    Kinetic energies are exchanged between the masses.  During a flip of the T (see animation above), the red and green masses “exchange” their energy. The blue mass mediates this exchange.  Depending on the initial conditions (in plane or out of plane), the energy of the red mass decreases first during the flip and the energy of the green mass increases (and vice versa, as seen below for the out of plane case which exhibits symmetric energy distributions).

    Energy peaks are a good measure for the flip frequency. The frequency increases with the initial misalignment of the rotation axis to the symmetry axis of the T.

    Ein Bild, das Text, Reihe, Diagramm, parallel enthält.

Automatisch generierte Beschreibung 

    Tracing the blue perturbing mass reveals that the mass never gets closer to the (initial) rotation axis than its initial off-axis position.

    Ein Bild, das Zeichnung, Kreis, Entwurf, Kunst enthält.

Automatisch generierte Beschreibung

    The angular momenta of the masses vary, but the total angular momentum is, as expected, conserved. In the image below the angular momenta of the three masses are visualized to the left. The change of kinetic energy can be appreciated from the change in magnitude of the angular momenta.

    The vector of the angular velocity (violet, at the origin) wobbles during the flip but does not flip direction. The vector of the angular acceleration (orange) rotates in the yz-plane

    Forces act in the plane of the triangle. There is no component normal to the plane, as in the YouTube video, that could cause a flip. Thus, the displayed forces measured in the inertial reference frame do not provide an intuitive explanation why the flip occurs.

    The same applies for the moments of the forces at the center of mass: They are perfectly balanced. There is no net component that could be attributed to an in-plane rotation.

     

    Why are the animations different: Apparent vs. internal reactive forces.

    The MapleSim animation shows internal reactive forces that illustrate the interplay of the moving masses which are bound to each other. They act in the model and obey actio = reactio, which means that the same vectors of opposite sign pull on the masses when the masses are isolated (they follow Newtons second law and equate to mass times the vector of acceleration; the last image in this post displays an isolated mass and the opposing force). 

    On the contrary, the YouTube animation shows apparent forces (centrifugal forces) that appear when accelerations are described in a reference frame that moves (accelerates or rotates) with respect to the inertial reference frame. They look like external forces acting on the model, but they are not real. Since apparent forces are fictitious (not real), not everyone is satisfied with using them for an intuitive explanation.

     

    Can the MapleSim animation be improved?

    Calculation of apparent forces is possible but less straight forward for the simple reason that the Mathematical components library does not provide operators for coordinate transform and matrix multiplication. Those operators are normally not required for simulation purposes. (It would be interesting to see how calcualtion of apparent forces can be done in MapleSim. Verification of code implementation might not be as easy as in the inertial reference frame.)

    What ultimately prevents a reproduction of the video is the observer/camera view that rotates with the model. This feature does not exist in the current version of MapleSim 2024. To reproduce the video, Maple has to be used. This would also make the implementation of the calculation of apparent forces much easier as compared to, for example, Modelica code implementation (at least for me).

     

    Is the 3-mass model equally intuitive as a 4-mass model?

    The initial idea was to have two orbiting masses that are perturbed by a third mass. The third mass flips like a pointer back and forth while the two masses still follow their orbit. This is in case of 3 identical masses only possible with a short-legged T as shown here:

    Only a reduced mass would allow for a longer leg. Since the T has only one axis of symmetry, the two orbiting masses do not orbit in a plane. They perform a wobbling motion and shift laterally in position during a flip since the rotation is performed about the common center of mass. Only when 4 masses are used in a symmetrical cross configuration, two masses can orbit closer to a plane that contains the common center of mass while the two perturbing masses flip sides of the plane (the wobble is less pronounced but still visible by the enlarging blue trace in the animation below).

    With a mass ratio of 1:100 in the animation below the two orbiting masses create kind of a centrifugal potential field in which the two perturbing masses swing like a pendulum. In this configuration the two perturbing masses can no longer be regarded as strongly disturbing, but rather as oscillating satellites. The sudden flip is created by the increasing accelerating field strength which increases with the distance from the axis of rotation. This lets a pendulum swing with a stronger than expected acceleration and is perhaps a new insight.

    Both models represent the simplest possible implementation to generate the effect in terms of number of parameters. The 4-mass configuration has more objects but is simpler to understand because of the higher degree of symmetry.  Either identical masses at varying distances or identical distances at varying masses can be used in both models. No more reduction of parameters is possible to generate the effect. A two mass object cannot even wobble.

    Out of plane initial inclination makes the acceptance of an explanation easier since the orbiting masses do not generate a momentum as in the case of an in plane inclination. For the latter case an intuitve explanation is more difficult and perhaps there is none.

    Although the pendulum swing of the out of plane case might provide an intuitive explanation of the effect it is not fully satisfying. It does not explain why larger masses than the orbiting masses do not lead to a swing but smaller masses do. Another well-made video provides an explanation for that.

    This newer video also gives an explanation why internal forces must act in the plane of the rotating object but does not display them in the animation. I guess this is because the introduction of real forces would have spoiled the intuitive explanation of the video. Isolating a mass and adding an internal force now as an external force leads to an equivalent system that reproduces the effect of the rotating object. If the same force is applied in the opposite direction on the isolated mass, the isolated mass moves along the same trajectory.

    4_lumped_masses_and_one_single_force_driven_mass.msim

    Isolating only one mass breakes the symmetry of the model. It also gives the false impression that the introduced perturbing force acts primarily on the opposite mass. A 3-mass model does not lead to such a false interpretation. By isolating the opposite mass and introducing a second perturbing force, the discussion shifts more to the analysis of the wobble and the rotational acceleration of the orbiting masses and less to the flip.

    In summary, internal forces describe how the masses interact but their orientation is counterintuitively perpendicular to direction of the flip. On the other hand, centrifugal forces that we intuitively assume acting in a 4-mass model from the perspective of an observer from an inertial reference frame do not exist. This assumption provides an intuitive explanation which is physically wrong. In the same way an accelerating radial force field does not exist. Mathematically and physically correct is a description from a rotating observer which uses fictious forces.

    For me both intuitive explanations of the videos are somehow useable, but both involve centrifugal forces (in one case explicitly and in the other wrongly assumed by an observer). This is not satisfying when the goal is not to use fictious forces.

    Conclusion

    MapleSim visualization components can be used for more than displaying forces and moments. They are very helpful to better understand physical phenomena.

    A camera view observer on a rotating reference frame would have made observation of the direction of the internal forces much easier and might have given more insights. As of now, Maple is required to reproduce the animation in the video.

    There is no better intuitive visualization/explanation with a model of 3 identical masses. A 4-mass configuration provides better insight but does not explain all.

    In reality every freely rotating object with more than two point masses inevitably wobbles.

    Hello,

    I present the result of work on a new project in the field of classical mechanics. It is a grateful and interesting topic that gives a lot of satisfaction. I am attaching the Maple worksheet.

    Best regards

    Rolling_Disk_3D_on_x0y_plane.mw

    I am a new user of Maple Flow 2024.2.

    Since I installed this version I got trouble with the following commands:

    solve(x^3-2x^2+3x-2)=1.00.  Just 1 root is returned

    fsolve((x-2)(x+3)(x-1))=-3.  Just 1 root is returned

    ifactors(3024)=.   Maple Flow latch in and crashes without errot massage

    seq(i^2,i=1..5)=. Sequence not executed

    subs(...)= Substitute not executed

    Optimization:-Minimize(...)=.  Latch in, error


    With the help of the Maplesoft-Team I uninstalled and installed several times MF on a MacBook Pro Sequoia 15.2 and on a MacBook Pro Ventura 13.7.2 with and without Firewall and McAfee. 
    No success, the problems still remain.

    I'll no longer use Maple Flow in this version.
    I expect a new update asap!

    In the excellent book by W.G. Chinn, N.E. Steenrod "First Concepts of Topology" the theorem is proved which states that any bounded planar region can be cut into 4 regions of equal area by 2 perpendicular cuts (the pancake problem). This is an existence theorem which does not provide any way to find these cuts. In this post I made an attempt to find such cuts for any convex region on the plane bounded by a piecewise smooth self-non-intersecting curve.
    The Into_4_Equal_Areas procedure returns a list of coordinates of 5 points: the first 4 points are the endpoints of the cutting segments, the fifth point is the intersection point of these segments. This procedure significantly uses my old procedure Area , which can be found in detail at the link  https://mapleprimes.com/posts/145922-Perimeter-Area-And-Visualization-Of-A-Plane-Figure-  . The formal argument of the Into_4_Equal_Areas procedure is a list  L specifying the boundary of the region to be cut. When specifying  L, the boundary can be passed clockwise or counterclockwise, but it is necessary that the parameter t (when specifying each link) should go in ascending order. This can always be achieved by replacing  t  with  -t  if necessary. The Pic procedure draws a picture of the source region and cutting segments. For ease of use, the code for the  Area  procedure is also provided. It is also worth noting that the procedure also works for "not too" non-convex regions (see examples below).

    restart;
    Area := proc(L) 
    local i, var, e, e1, e2, P; 
    for i to nops(L) do 
    if type(L[i], listlist(algebraic)) then 
    P[i] := (1/2)*add(L[i, j, 1]*L[i, j+1, 2]-L[i, j, 2]*L[i, j+1, 1], j = 1 .. nops(L[i])-1) else 
    var := lhs(L[i, 2]); 
    if type(L[i, 1], algebraic) then e := L[i, 1]; 
    if nops(L[i]) = 3 then P[i] := (1/2)*(int(e^2, L[i, 2])) else 
    if var = y then P[i] := (1/2)*simplify(int(e-var*(diff(e, var)), L[i, 2])) else 
    P[i] := (1/2)*simplify(int(var*(diff(e, var))-e, L[i, 2])) end if end if else e1 := L[i, 1, 1]; e2 := L[i, 1, 2]; 
    P[i] := (1/2)*simplify(int(e1*(diff(e2, var))-e2*(diff(e1, var)), L[i, 2])) end if end if end do; 
    abs(add(P[i], i = 1 .. nops(L))); 
    end proc:
    
    Into_4_Equal_Areas:=proc(L::list,N::symbol:='OneSolution', eps::numeric:=0)
    local D, n, c, L1, L2, L3, f, L0, i, j, k, m, A, B, C, P, S, sol, Sol;
    f:=(X,Y)->expand((y-X[2])*(Y[1]-X[1])-(x-X[1])*(Y[2]-X[2]));
    L0:=map(p->`if`(type(p,listlist),[[p[1,1]+t*(p[2]-p[1])[1],p[1,2]+t*(p[2]-p[1])[2]],t=0..1],p), L);
    S:=Area(L); c:=0;
    n:=nops(L);
    for i from 1 to n do
    for j from i to n do
    for k from j to n do
    for m from k to n do
    if not ((nops({i,j,k})=1 and type(L[i],listlist)) or (nops({j,k,m})=1 and type(L[j],listlist)))then
    A:=convert(subs(t=t1,L0[i,1]),Vector): 
    B:=convert(subs(t=t2,L0[j,1]),Vector):
    C:=convert(subs(t=t3,L0[k,1]),Vector): 
    D:=convert(subs(t=t4,L0[m,1]),Vector):
    P:=eval([x,y], solve({f(A,C),f(B,D)},{x,y})):
    L1:=`if`(j=i,[subsop([2,2]=t1..t2,L0[i]),[convert(B,list),P],[P,convert(A,list)]],`if`(j=i+1,[subsop([2,2]=t1..op([2,2,2],L0[i]),L0[i]),subsop([2,2]=op([2,2,1],L0[j])..t2,L0[j]),[convert(B,list),P],[P,convert(A,list)]], [subsop([2,2]=t1..op([2,2,2],L0[i]),L0[i]),L0[i+1..j-1][],subsop([2,2]=op([2,2,1],L0[j])..t2,L0[j]),[convert(B,list),P],[P,convert(A,list)]])):
    L2:=`if`(k=j,[subsop([2,2]=t2..t3,L0[j]),[convert(C,list),P],[P,convert(B,list)]],`if`(k=j+1,[subsop([2,2]=t2..op([2,2,2],L0[j]),L0[j]),subsop([2,2]=op([2,2,1],L0[k])..t3,L0[k]),[convert(C,list),P],[P,convert(B,list)]], [subsop([2,2]=t2..op([2,2,2],L0[j]),L0[j]),L0[j+1..k-1][],subsop([2,2]=op([2,2,1],L0[k])..t3,L0[k]),[convert(C,list),P],[P,convert(B,list)]])):
    L3:=`if`(m=k,[subsop([2,2]=t3..t4,L0[k]),[convert(D,list),P],[P,convert(C,list)]],`if`(m=k+1,[subsop([2,2]=t3..op([2,2,2],L0[k]),L0[k]),subsop([2,2]=op([2,2,1],L0[m])..t4,L0[m]),[convert(D,list),P],[P,convert(C,list)]], [subsop([2,2]=t3..op([2,2,2],L0[k]),L0[k]),L0[k+1..m-1][],subsop([2,2]=op([2,2,1],L0[m])..t4,L0[m]),[convert(D,list),P],[P,convert(C,list)]])):
    sol:=fsolve({Area(L1)-S/4,Area(L2)-S/4,Area(L3)-S/4,LinearAlgebra:-DotProduct(D-B,C-A, conjugate=false)},{t1=op([2,2,1],L0[i])-eps..op([2,2,2],L0[i])+eps,t2=op([2,2,1],L0[j])-eps..op([2,2,2],L0[j])+eps,t3=op([2,2,1],L0[k])-eps..op([2,2,2],L0[k])+eps,t4=op([2,2,1],L0[m])-eps..op([2,2,2],L0[m])+eps}) assuming real:
    if type(sol,set(`=`)) then if N='OneSolution' then return convert~(eval([A,B,C,D,P],sol),list) else c:=c+1; Sol[c]:=convert~(eval([A,B,C,D,P],sol),list) fi;
     fi; fi;
    od: od: od: od:
    convert(Sol,list);
    end proc:
    
    Pic:=proc(L,Sol)
    local P1, P2, T;
    uses plots, plottools;
    P1:=seq(`if`(type(s,listlist),line(s[],color=blue, thickness=2),plot([s[1][],s[2]],color=blue, thickness=2)),s=L):
    P2:=line(Sol[1],Sol[3],color=red, thickness=2), line(Sol[2],Sol[4],color=red):
    T:=textplot([[Sol[1][],"A"],[Sol[2][],"B"],[Sol[3][],"C"],[Sol[4][],"D"],[Sol[5][],"P"]], font=[times,18], align=[left,above]);
    display(P1,P2,T, scaling=constrained, size=[800,500], axes=none);
    end proc: 
    


    Examples of use:

    L:=[[[0,0],[1,4]],[[1,4],[6,7]],[[6,7],[12,0]],[[12,0],[0,0]]]:
    Sol:=Into_4_Equal_Areas(L);
    Pic(L, Sol);
    
    # Check (areas of all 4 regions)
    Area([[L[1,1],Sol[4],Sol[5],Sol[1],L[1,1]]]),
    Area([[Sol[4],Sol[5],Sol[3],L[4,1],Sol[4]]]),
    Area([[Sol[5],Sol[2],L[3,1],Sol[3],Sol[5]]]),
    Area([[Sol[5],Sol[2],L[1,2],Sol[1],Sol[5]]]);
    
    

            


     

    L:=[[[1+cos(-t),1+sin(-t)],t=-3*Pi/2..-Pi],[[0,1],[-1,0]],[[cos(t),sin(t)],t=Pi..2*Pi]]:
    Sol:=Into_4_Equal_Areas(L);
    Pic(L,Sol);
    

        

    # The boundary is the Archimedes spiral and the arc of a circle
    
    L:=[[[t*cos(t),t*sin(t)],t=0..2*Pi],[[Pi+5*cos(-t),sqrt(25-Pi^2)+5*sin(-t)],t=arccos(Pi/5)..Pi-arccos(Pi/5)]]:
    Sol:=evalf(Into_4_Equal_Areas(L));
    Pic(L,Sol);
    

         

     

    L:=[[[0,0],[2,0]],[[2,0],[1,sqrt(3)]],[[1,sqrt(3)],[0,0]]]:
    Sol:=evalf[5](Into_4_Equal_Areas(L, AllSolutions, 0.1)); # All 3 solutions
    plots:-display(<Pic(L, Sol[1]) | Pic(L, Sol[2])  | Pic(L, Sol[3])>, size=[300,300]);  
    


     

    L:=[[[-t,-sin(-t)],t=-5*Pi/4..0],[[cos(t),sin(t)-1],t=Pi/2..3*Pi/2],[[t,cos(t)-3],t=0..3*Pi/2],[[3*Pi/2,-3],[5*Pi/4,sqrt(2)/2]]]:
    Sol:=evalf(Into_4_Equal_Areas(L));
    Pic(L,Sol);
    

    More examples can be found in the attached file.

    4_Equal_Area1.mw

    [Edit]. The post has been edited. One inaccuracy in the code has been corrected, which could sometimes lead to errors. Two options have been added to the code of Into_4_Equal_Areas procedure. The first option is the formal argument  N . If N=OneSolution  (by default), the procedure returns one solution. If  N=AllSolutions , the procedure returns all solutions that it can find. The  eps  option has also been added (by default, eps=0). It is advisable to use it when we are looking for all solutions, and the ends of the cutting segments fall on the boundaries of intervals (this option slightly expands the boundaries of intervals, otherwise the  fsolve  command sometimes misses solutions). Two new examples have also been added.

     

     

    Maple Transactions Volume 4 Issue 4 has now been published.

     

    This issue has two Featured Contributions by people who have been plenary speakers at Maple Conferences in the past, namely Veselin Jungić and Juana Sendra. We hope you enjoy both articles.  There is an accompanying video by Professor Sendra, which we will add a link to when it becomes ready.

    As usual, there is an article in the Editor's Corner, but this one is a bit different.  In this one, Michelle Hatzell (the new copyeditor for Maple Transactions, who is also a Masters' student working with me at Western) and I have written about a fun use of Maple's colour contour plots to make an image that might be used as the cover of an upcoming book, namely Perturbation Methods using backward error, which I'm just finishing now with Nic Fillion and which SIAM will publish next year.  So, while there's some math in that paper, it's more about Maple's utilities for colour plotting; so you might find it useful.  We also hope you like at least some of the images.  Some are more attractive than others!

    We have several Refereed Contributions, not all of which are ready at this time of publication but which will be added as they are revised and sent in.  We have a nice paper on using continued fractions in a high school context, another on code generation, and another on using Digital Signal Processing in Engineering courses.

    Finally we have a first publication in French, by Jalale Soussi.  Actually we have the paper also in English: we chose to publish both, in our Communications section, each with links to the other.  It is possible to publish in Maple Transactions solely in French, of course, but the author provided both, so why not?

    Happy reading, and best wishes for 2025. 

    In this activity, we are trying to simulate an outbreak of a new infectious disease that our population of 10^6people has not been exposed to before. This means that we are starting with a single case, everyone else is susceptible to the disease, and no one is yet immune or recovered. This can for example reflect a situation where an infected person introduces a new disease into a geographically isolated population, like on an island, or even when an infections "spill over" from other animals into a human population. In terms of the initial conditions for our model, we can define: "S=10^(6) -1=999999," I = 0and R = 0. NULL

    Remember, the differential equations for the simple SIR model look like this:

    dS/dt = `&lambda;S`*dI/dt and `&lambda;S`*dI/dt = `&lambda;S`-I*gamma, dR/dt = I*gamma

    Initial number of people in each compartment
    S = 10^6-1",I=0  "and R = 0.

    NULL

    Parameters:

    gamma = .1*recovery*rate*beta and .1*recovery*rate*beta = .4*the*daily*infection*rate

    restart; with(plots); _local(gamma)

    sys := diff(s(t), t) = -lambda*s(t), diff(i(t), t) = lambda*s(t)-gamma*i(t), diff(r(t), t) = gamma*i(t)

    diff(s(t), t) = -lambda*s(t), diff(i(t), t) = lambda*s(t)-gamma*i(t), diff(r(t), t) = gamma*i(t)

    (1)

    ic := s(0) = s__0, i(0) = i__0, r(0) = r__0

    gamma := .1; beta := .4; n := 10^6

    .1

     

    .4

     

    1000000

    (2)

    lambda := beta*i(t)/n

    s__0, i__0, r__0 := 10^6-1, 1, 0

    NULL

    sols := dsolve({ic, sys}, numeric, output = listprocedure)

    display([odeplot(sols, [t, s(t)], 0 .. 100, color = red), odeplot(sols, [t, i(t)], 0 .. 100, color = blue), odeplot(sols, [t, r(t)], 0 .. 100, color = green)], labels = ["Time [day]", "Population"], labeldirections = [horizontal, vertical], legend = ["Susceptible", "Infected", "Recovered"], legendstyle = [location = right])

     

    Remember that in a simple homogenous SIR model, `R__eff  `is directly related to the proportion of the population that is susceptible:

    R__eff = R__0*S/N

    Reff := proc (t) options operator, arrow; beta*s(t)/(gamma*n) end proc

    odeplot(sols, [[t, Reff(t)]], t = 0 .. 100, size = [500, 300], labels = ["Time [day]", "Reff"], labeldirections = [horizontal, vertical])

     

    The effective reproduction number is highest when everyone is susceptible: at the beginning, `R__eff  ` = R__0. At this point in our example, every infected cases causes an average of 4 secondary infections. Over the course of the epidemic, `R__eff  ` declines in proportion to susceptibility.

    The peak of the epidemic happens when `R__eff  ` goes down to 1 (in the example here, after 50 days). As `R__eff  `decreases further below 1, the epidemic prevalence goes into decline. This is exactly what you would expect, given your understanding of the meaning of `R__eff  ` once the epidemic reaches the point where every infected case cannot cause at least one more infected case (that is, when `R__eff  ` < 1), the epidemic cannot sustain itself and comes to an end.

    susceptible := eval(s(t), sols); infected := eval(i(t), sols); recovered := eval(r(t), sols)

    susceptible(51)

    HFloat(219673.04834159758)

    (3)

    infected(51)

    HFloat(401423.4112878752)

    (4)

    recovered(51)

    HFloat(378903.54037052736)

    (5)

    Reffe := proc (t) options operator, arrow; beta*susceptible(t)/(gamma*n) end proc

    proc (t) options operator, arrow; beta*susceptible(t)/(gamma*n) end proc

    (6)

    Reffe(51)

    HFloat(0.8786921933663903)

    (7)

    Prevalence is simply the value of Iat a given point in time. Now we can see that the incidence is the number of new cases arriving in the I compartment in a given interval of time. The way we represent this mathematically is by taking the integral of new cases over a given duration.

    For example, if we wanted to calculate the incidence from day 7 to 14,

    int(`&lambda;S`(t), t = 7 .. 14)

    lamda := proc (t) options operator, arrow; beta*infected(t)/n end proc

    proc (t) options operator, arrow; beta*infected(t)/n end proc

    (8)

    inflow := proc (t) options operator, arrow; lamda(t)*susceptible(t) end proc

    proc (t) options operator, arrow; lamda(t)*susceptible(t) end proc

    (9)

    int(inflow(t), t = 7 .. 14)

    HFloat(78.01804723222038)

    (10)

    incidence_plot := plot(inflow(t), t = 0 .. 14, color = orange, labels = ["Time (days)", "Incidence Rate"], labeldirections = [horizontal, vertical], title = "Incidence Rate between t=7 and t=14")

     

    s, i, r := eval(s(t), sols), eval(i(t), sols), eval(r(t), sols); T := 100; dataArr := Array(-1 .. T, 1 .. 4); dataArr[-1, () .. ()] := `<,>`("Day", "Susceptible", "Infected", "Recovered")


    Assign all the subsequent rows

    for t from 0 to T do dataArr[t, () .. ()] := `~`[round](`<,>`(t, s(t), i(t), r(t))) end do

     

    Tabulate through the DocumentTools

    DocumentTools:-Tabulate(dataArr, alignment = left, width = 50, fillcolor = (proc (A, n, m) options operator, arrow; ifelse(n = 1, "DeepSkyBlue", "LightBlue") end proc))

    Download dynamics_of_novel_disease_outbreak.mw

    1 2 3 4 5 6 7 Last Page 3 of 305