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
  • It would be useful if there was a category (or subcategory) of scientific domain (e.g. physics, methematics, economics...)  in which Maple is applied. Thus it would become very convinient for someone who have a question on a specific topic to find a possible answer. 

    I like how the Julia community has been organised in https://discourse.julialang.org, so I would suggest to implement something similar in Maple Primes

    When this question was asked here earlier, I neglected to suggest or to emphasize two further items.  Now, on revising Mathematics for Chemistry with [Maple], I recognise that I should have included these two objectives for inclusion in Maple 2021.

    - an extended and improved spreadsheet with symbolic capability; I suspect that Maple was the only software for symbolic computation to include such a facility, which sadly has become deprecated, for no obvious reason.

    - a much extended capability to solve integral equations; publications dating from 1976 -- i.e. before Maple! -- have shown what is possible; Maple's capabilities for differential equations might still be superior, although the competition is becoming close, so further efforts in the development of both differential and integral equations are timely and appropriate.  Related to differential equations is naturally the extension of capabilities of special functions, both to extend present functions and to produce new functions, such as those of Lame.

    I created a little procedure to automatically size text areas based on content. It sizes the text area based on wraparound and tab characters, something that the autosize for the code edit region does not do. (Hint to Maple developers)

    Enjoy.

        AutosizeTextArea:=proc(TextAreaName, {intMinRows::nonnegint:=5, intMinChars::nonnegint:=50, intMaxChars::nonnegint:=140})
            description "Autosizes the TextArea based on content",
                      "Parameters",
                      "1) TextAreaName__The name of the textarea",
                      "Optional Parameters",
                      "intMinRows________Minimum number of visible rows",
                      "intMinChars_______Minimum character width",
                      "intMaxChars_______Maximum character width";
            uses DocumentTools, StringTools;          
            local strLines, intLongestLine, nLines;
            strLines := Split(GetProperty(TextAreaName,'value'),"\n");
            intLongestLine := max('numelems'~(strLines));
            # Count the characters in each line (add 7 extra characters for each tab). Determine the number of lines to display each line due to wraparound, then add all these together
            #   to determine the number of rows to display.
            nLines := add(ceil~(('numelems'~(strLines) + StringTools:-CountCharacterOccurrences~(strLines, "\t")*~7)/~intMaxChars));
            SetProperty(TextAreaName, 'visibleRows', max(nLines, intMinRows), 'refresh' = true);
            SetProperty(TextAreaName, 'visibleCharacterWidth', min(max(intLongestLine, intMinChars),intMaxChars), 'refresh' = true);
        
        end proc:

    A fascinating race is presently running (even if the latest results seem  to have put an end to it).
    I'm talking of course about the US presidential elections.

    My purpose is not to do politics but to discuss of a point of detail that really left me puzzled: the possibility of an electoral college tie.
    I guess that this possibility seems as an aberration for a lot of people living in democratic countries. Just because almost everywhere at World electoral colleges contain an odd number of members to avoid such a situation!

    So strange a situation that I did a few things to pass the time (of course with the earphones on the head so I don't miss a thing).
    This is done with Maple 2015 and I believe that the amazing Iterator package (that I can't use thanks to the teleworking :-( ) could be used to do much more interesting things.

     

    restart:

    with(Statistics):

    ElectoralCollege := Matrix(51, 2, [

    Alabama,        9,        Kentucky,        8,        North_Dakota,        3,

    Alaska,        3,        Louisiana,        8,        Ohio,        18,

    Arizona,        11,        Maine,        4,        Oklahoma,        7,

    Arkansas,        6,        Maryland,        10,        Oregon,        7,

    California,        55,        Massachusetts,        11,        Pennsylvania,        20,

    Colorado,        9,        Michigan,        16,        Rhode_Island,        4,

    Connecticut,        7,        Minnesota,        10,        South_Carolina,        9,

    Delaware,        3,        Mississippi,        6,        South_Dakota,        3,

    District_of_Columbia,        3,        Missouri,        10,        Tennessee,        11,

    Florida,        29,        Montana,        3,        Texas,        38,

    Georgia,        16,        Nebraska,        5,        Utah,        6,

    Hawaii,        4,        Nevada,        6,        Vermont,        3,

    Idaho,        4,        New_Hampshire,        4,        Virginia,        13,

    Illinois,        20,        New_Jersey,        14,        Washington,        12,

    Indiana,        11,        New_Mexico,        5,        West_Virginia,        5,

    Iowa,        6,        New_York,        29,        Wisconsin,        10,

    Kansas,        6,        North_Carolina,        15,        Wyoming,        3
    ]):
     

    ElectoralCollege := Vector(4, {(1) = ` 51 x 2 `*Matrix, (2) = `Data Type: `*anything, (3) = `Storage: `*rectangular, (4) = `Order: `*Fortran_order})

    (1)

    add(ElectoralCollege[..,2]):
    tie := %/2;

    269

    (2)

    ec := convert(ElectoralCollege, listlist):

    # Sets of states that form an electoral college tie

    R      := 10^5:
    nbties := 0:
    states := NULL:
    for r from 1 to R do
      poll  := combinat:-randperm(ec):
      cpoll := CumulativeSum(op~(2, poll)):
      if tie in cpoll then
        nbties := nbties+1;
        place  := ListTools:-Search(tie, cpoll);
        states := states, op~(1, poll)[1..place]:   # see below
      end if:
    end do:

    # electoral college tie is not so rare an event
    # (prob of occurrence about 9.4 %).
    #
    # Why the hell the US constitution did not decide to have an odd
    # number or electors to avoid ths kind of situation instead of
    # introducing a complex mechanism when tie appears????

    nbties;
    evalf(nbties/R);

    states := [states]:

    9397

     

    0.9397000000e-1

    (3)

    # What states participate to the tie?

    names := sort(ElectoralCollege[..,1]):

    all_states_in_ties := [op(op~(states))]:

    howoften := Vector(
                        51,
                        i -> ListTools:-Occurrences(names[i], all_states_in_ties)
                ):

    ScatterPlot(Vector(51, i->i), howoften);

     

    # All the states seem to appear equally likely in an electoral college tie.
    # Why? Does someone have a guess?
    #
    # The reason is obvious, as each state must appear in the basket of a candidate,
    # then in case of a tie each state is either in op~(1, poll)[1..place] (candidate 1)
    # or either in op~(1, poll)[place+1..51] (candidate 2);
    # So, as we obtained 9397 ties, each states appears exactly 9397 times (with
    # different occurences in the baskets of candidate 1 and 2).

     

    # Lengths of the configurations that lead to a tie.
    #
    # Pleas refer to the answer above to understand why Histogram(lengths) should be
    # symmetric.
    lengths := map(i -> numelems(states[i]), [$1..nbties]):
    sort(Tally(lengths))

    [14 = 1, 15 = 2, 16 = 7, 17 = 36, 18 = 78, 19 = 179, 20 = 341, 21 = 507, 22 = 652, 23 = 849, 24 = 1015, 25 = 1041, 26 = 1056, 27 = 997, 28 = 862, 29 = 657, 30 = 515, 31 = 300, 32 = 158, 33 = 95, 34 = 41, 35 = 6, 36 = 2]

    (4)

    Histogram(lengths, range=min(lengths)..max(lengths), discrete=true)

     

    ShortestConfigurations := map(i -> if lengths[i]=min(lengths) then states[i] end if, [$1..nbties]):
    print~(ShortestConfigurations):

    [New_York, Wisconsin, Illinois, Kentucky, Florida, New_Jersey, Mississippi, Indiana, Virginia, Maryland, California, Massachusetts, North_Carolina, Texas]

    (5)

    LargestConfigurations := map(i -> if lengths[i]=max(lengths) then states[i] end if, [$1..nbties]):
    print~(LargestConfigurations):

    [Alaska, Tennessee, North_Carolina, South_Carolina, District_of_Columbia, Colorado, Minnesota, Georgia, South_Dakota, New_Hampshire, Wyoming, Ohio, Rhode_Island, Arizona, Delaware, Montana, West_Virginia, Vermont, Michigan, Kentucky, Louisiana, Arkansas, Maine, Missouri, New_Mexico, Virginia, Maryland, Oregon, Wisconsin, Iowa, Kansas, Connecticut, North_Dakota, Nevada, Hawaii, Oklahoma]

     

    [West_Virginia, Maryland, Massachusetts, Colorado, South_Dakota, Kentucky, Kansas, Wyoming, North_Dakota, Indiana, Michigan, Utah, Louisiana, Ohio, Alabama, Nebraska, Connecticut, Illinois, Oklahoma, Alaska, New_Jersey, District_of_Columbia, Oregon, Nevada, Missouri, Delaware, Washington, New_Hampshire, Arizona, Maine, South_Carolina, Hawaii, Vermont, Montana, Rhode_Island, Idaho]

    (6)

    # What could be the largest composition of a basket in case of a tie?
    # (shortest composition is the complementary of the largest one)

    ecs   := sort(ec, key=(x-> x[2]));
    csecs := CumulativeSum(op~(2, ecs)):

    # Where would the break locate?

    tieloc := ListTools:-BinaryPlace(csecs, tie);

    csecs[tieloc..tieloc+1]

    [[North_Dakota, 3], [Alaska, 3], [Delaware, 3], [South_Dakota, 3], [District_of_Columbia, 3], [Montana, 3], [Vermont, 3], [Wyoming, 3], [Maine, 4], [Rhode_Island, 4], [Hawaii, 4], [Idaho, 4], [New_Hampshire, 4], [Nebraska, 5], [New_Mexico, 5], [West_Virginia, 5], [Arkansas, 6], [Mississippi, 6], [Utah, 6], [Nevada, 6], [Iowa, 6], [Kansas, 6], [Oklahoma, 7], [Oregon, 7], [Connecticut, 7], [Kentucky, 8], [Louisiana, 8], [Alabama, 9], [Colorado, 9], [South_Carolina, 9], [Maryland, 10], [Minnesota, 10], [Missouri, 10], [Wisconsin, 10], [Arizona, 11], [Massachusetts, 11], [Tennessee, 11], [Indiana, 11], [Washington, 12], [Virginia, 13], [New_Jersey, 14], [North_Carolina, 15], [Michigan, 16], [Georgia, 16], [Ohio, 18], [Pennsylvania, 20], [Illinois, 20], [Florida, 29], [New_York, 29], [Texas, 38], [California, 55]]

     

    40

     

    Array(%id = 18446744078888202358)

    (7)

    # This 40  states coniguration is not a tie.
    #
    # But list all the states in basket of candidate 1 and look to the 41th state (which is
    # in the basket of candidate 2)

    ecs[1..tieloc];
    print():
    ecs[tieloc+1]

    [[North_Dakota, 3], [Alaska, 3], [Delaware, 3], [South_Dakota, 3], [District_of_Columbia, 3], [Montana, 3], [Vermont, 3], [Wyoming, 3], [Maine, 4], [Rhode_Island, 4], [Hawaii, 4], [Idaho, 4], [New_Hampshire, 4], [Nebraska, 5], [New_Mexico, 5], [West_Virginia, 5], [Arkansas, 6], [Mississippi, 6], [Utah, 6], [Nevada, 6], [Iowa, 6], [Kansas, 6], [Oklahoma, 7], [Oregon, 7], [Connecticut, 7], [Kentucky, 8], [Louisiana, 8], [Alabama, 9], [Colorado, 9], [South_Carolina, 9], [Maryland, 10], [Minnesota, 10], [Missouri, 10], [Wisconsin, 10], [Arizona, 11], [Massachusetts, 11], [Tennessee, 11], [Indiana, 11], [Washington, 12], [Virginia, 13]]

     

     

    [New_Jersey, 14]

    (8)

    # It appears that exchanging Virginia and New_Jersey increases by 1 unit the college of candidate 1
    # and produces a tie.

    LargestBasketEver := [ ecs[1..tieloc-1][], ecs[tieloc+1] ];

    add(op~(2, LargestBasketEver))

    [[North_Dakota, 3], [Alaska, 3], [Delaware, 3], [South_Dakota, 3], [District_of_Columbia, 3], [Montana, 3], [Vermont, 3], [Wyoming, 3], [Maine, 4], [Rhode_Island, 4], [Hawaii, 4], [Idaho, 4], [New_Hampshire, 4], [Nebraska, 5], [New_Mexico, 5], [West_Virginia, 5], [Arkansas, 6], [Mississippi, 6], [Utah, 6], [Nevada, 6], [Iowa, 6], [Kansas, 6], [Oklahoma, 7], [Oregon, 7], [Connecticut, 7], [Kentucky, 8], [Louisiana, 8], [Alabama, 9], [Colorado, 9], [South_Carolina, 9], [Maryland, 10], [Minnesota, 10], [Missouri, 10], [Wisconsin, 10], [Arizona, 11], [Massachusetts, 11], [Tennessee, 11], [Indiana, 11], [Washington, 12], [New_Jersey, 14]]

     

    269

    (9)

    # The largest electoral college tie contains 40 states (the shortest 11)


     

    Download ElectoralCollegeTie.mw

    Controlled platform with 6 degrees of freedom. It has three rotary-inclined racks of variable length:

    and an example of movement parallel to the base:

    Perhaps the Stewart platform may not reproduce such trajectories, but that is not the point. There is a way to select a design for those specific functions that our platform will perform. That is, first we consider the required trajectories of the platform movement, and only then we select a driving device that can reproduce them. For example, we can fix the extreme positions of the actuators during the movement of the platform and compare them with the capabilities of existing designs, or simulate your own devices.
    In this case, the program consists of three parts. (The text of the program directly for the first figure : PLATFORM_6.mw) In the first part, we select the starting point for the movement of a rigid body with six degrees of freedom. Here three equations f6, f7, f8 are responsible for the six degrees of freedom. The equations f1, f2, f3, f4, f5 define a trajectory of motion of a rigid body. The coordinates of the starting point are transmitted via disk E for the second part of the program. In the second part of the program, the trajectory of a rigid body is calculated using the Draghilev method. Then the trajectory data is transferred via the disk E for the third part of the program.
    In the third part of the program, the visualization is executed and the platform motion drive device is modeled.
    It is like a sketch of a possible way to create controlled platforms with six degrees of freedom. Any device that can provide the desired trajectory can be inserted into the third part. At the same time, it is obvious that the geometric parameters of the movement of this device with the control of possible emergency positions and the solution of the inverse kinematics problem can be obtained automatically if we add the appropriate code to the program text.
    Equations can be of any kind and can be combined with each other, and they must be continuously differentiable. But first, the equations must be reduced to uniform variables in order to apply the Draghilev method.
    (These examples use implicit equations for the coordinates of the vertices of the triangle.)

    In the study of the Gödel spacetime model, a tetrad was suggested in the literature [1]. Alas, upon entering the tetrad in question, Maple's Tetrad's package complained that that matrix was not a tetrad! What went wrong? After an exchange with Edgardo S. Cheb-Terrab, Edgardo provided us with awfully useful comments regarding the use of the package and suggested that the problem together with its solution be presented in a post, as others may find it of some use for their work as well.

     

    The Gödel spacetime solution to Einsten's equations is as follows.

     

    Physics:-Version()

    `The "Physics Updates" version in the MapleCloud is 858 and is the same as the version installed in this computer, created 2020, October 27, 10:19 hours Pacific Time.`

    (1)

    with(Physics); with(Tetrads)

    _______________________________________________________

     

    `Setting `*lowercaselatin_ah*` letters to represent `*tetrad*` indices`

     

    ((`Defined as tetrad tensors `*`see <a href='http://www.maplesoft.com/support/help/search.aspx?term=Physics,tetrads`*`,' target='_new'>?Physics,tetrads`*`,</a> `*`&efr;`[a, mu]*`, `)*eta[a, b]*`, `*gamma[a, b, c]*`, `)*lambda[a, b, c]

     

    ((`Defined as spacetime tensors representing the NP null vectors of the tetrad formalism `*`see <a href='http://www.maplesoft.com/support/help/search.aspx?term=Physics,tetrads`*`,' target='_new'>?Physics,tetrads`*`,</a> `*l[mu]*`, `)*n[mu]*`, `*m[mu]*`, `)*conjugate(m[mu])

     

    _______________________________________________________

    (2)

    Working with Cartesian coordinates,

    Coordinates(cartesian)

    `Systems of spacetime coordinates are:`*{X = (x, y, z, t)}

     

    {X}

    (3)

    the Gödel line element is

     

    ds^2 = d_(t)^2-d_(x)^2-d_(y)^2+(1/2)*exp(2*q*y)*d_(z)^2+2*exp(q*y)*d_(z)*d_(t)

    ds^2 = Physics:-d_(t)^2-Physics:-d_(x)^2-Physics:-d_(y)^2+(1/2)*exp(2*q*y)*Physics:-d_(z)^2+2*exp(q*y)*Physics:-d_(z)*Physics:-d_(t)

    (4)

    Setting the metric

    Setup(metric = rhs(ds^2 = Physics[d_](t)^2-Physics[d_](x)^2-Physics[d_](y)^2+(1/2)*exp(2*q*y)*Physics[d_](z)^2+2*exp(q*y)*Physics[d_](z)*Physics[d_](t)))

    _______________________________________________________

     

    `Coordinates: `*[x, y, z, t]*`. Signature: `*`- - - +`

     

    _______________________________________________________

     

    Physics:-g_[mu, nu] = Matrix(%id = 18446744078354506566)

     

    _______________________________________________________

     

    `Setting `*lowercaselatin_is*` letters to represent `*space*` indices`

     

    [metric = {(1, 1) = -1, (2, 2) = -1, (3, 3) = (1/2)*exp(2*q*y), (3, 4) = exp(q*y), (4, 4) = 1}, spaceindices = lowercaselatin_is]

    (5)

    The problem appeared upon entering the matrix M below supposedly representing the alleged tetrad.

    interface(imaginaryunit = i)

    M := Matrix([[1/sqrt(2), 0, 0, 1/sqrt(2)], [-1/sqrt(2), 0, 0, 1/sqrt(2)], [0, 1/sqrt(2), -I*exp(-q*y), I], [0, 1/sqrt(2), I*exp(-q*y), -I]])

    Matrix(%id = 18446744078162949534)

    (6)

    Each of the rows of this matrix is supposed to be one of the null vectors [l, n, m, conjugate(m)]. Before setting this alleged tetrad, Maple was asked to settle the nature of it, and the answer was that M was not a tetrad! With the Physics Updates v.857, a more detailed message was issued:

    IsTetrad(M)

    `Warning, the given components form a`*null*`tetrad, `*`with a contravariant spacetime index`*`, only if you change the signature from `*`- - - +`*` to `*`+ - - -`*`. 
You can do that by entering (copy and paste): `*Setup(signature = "+ - - -")

     

    false

    (7)

    So there were actually three problems:

    1. 

    The entered entity was a null tetrad, while the default of the Physics package is an orthonormal tetrad. This can be seen in the form of the tetrad metric, or using the library commands:

    eta_[]

    Physics:-Tetrads:-eta_[a, b] = Matrix(%id = 18446744078354552462)

    (8)

    Library:-IsOrthonormalTetradMetric()

    true

    (9)

    Library:-IsNullTetradMetric()

    false

    (10)
    2. 

    The matrix M would only be a tetrad if the spacetime index is contravariant. On the other hand, the command IsTetrad will return true only when M represents a tetrad with both indices covariant. For  instance, if the command IsTetrad  is issued about the tetrad automatically computed by Maple, but is passed the matrix corresponding to "`&efr;`[a]^(mu)"  with the spacetime index contravariant,  false is returned:

    "e_[a,~mu, matrix]"

    Physics:-Tetrads:-e_[a, `~&mu;`] = Matrix(%id = 18446744078297840926)

    (11)

    "IsTetrad(rhs(?))"

    Typesetting[delayDotProduct](`Warning, the given components form a`*orthonormal*`tetrad only if the spacetime index is contravariant. 
You can construct a tetrad with a covariant spacetime index by entering (copy and paste): `, Matrix(4, 4, {(1, 1) = 1, (1, 2) = 0, (1, 3) = 0, (1, 4) = 0, (2, 1) = 0, (2, 2) = 1, (2, 3) = 0, (2, 4) = 0, (3, 1) = 0, (3, 2) = 0, (3, 3) = sqrt(2)*exp(-q*y), (3, 4) = -sqrt(2), (4, 1) = 0, (4, 2) = 0, (4, 3) = 0, (4, 4) = 1}), true).rhs(g[])

     

    false

    (12)
    3. 

    The matrix M corresponds to a tetrad with different signature, (+---), instead of Maple's default (---+). Although these two signatures represent the same physics, they differ in the ordering of rows and columns: the timelike component is respectively in positions 1 and 4.

     

    The issue, then, became how to correct the matrix M to be a valid tetrad: either change the setup, or change the matrix M. Below the two courses of action are provided.

     

    First the simplest: change the settings. According to the message (7), setting the tetrad to be null, changing the signature to be (+---) and indicating that M represents a tetrad with its spacetime index contravariant would suffice:

    Setup(tetradmetric = null, signature = "+---")

    [signature = `+ - - -`, tetradmetric = {(1, 2) = 1, (3, 4) = -1}]

    (13)

    The null tetrad metric is now as in the reference used.

    eta_[]

    Physics:-Tetrads:-eta_[a, b] = Matrix(%id = 18446744078298386174)

    (14)

    Checking now with the spacetime index contravariant

    e_[a, `~&mu;`] = M

    Physics:-Tetrads:-e_[a, `~&mu;`] = Matrix(%id = 18446744078162949534)

    (15)

    At this point, the command IsTetrad  provided with the equation (15), where the left-hand side has the information that the spacetime index is contravariant

    "IsTetrad(?)"

    `Type of tetrad: `*null

     

    true

    (16)

    Great! one can now set the tetrad M exactly as entered, without changing anything else. In the next line it will only be necessary to indicate that the spacetime index, mu, is contravariant.

    Setup(e_[a, `~&mu;`] = M, quiet)

    [tetrad = {(1, 1) = -(1/2)*2^(1/2), (1, 3) = (1/2)*2^(1/2)*exp(q*y), (1, 4) = (1/2)*2^(1/2), (2, 1) = (1/2)*2^(1/2), (2, 3) = (1/2)*2^(1/2)*exp(q*y), (2, 4) = (1/2)*2^(1/2), (3, 2) = -(1/2)*2^(1/2), (3, 3) = ((1/2)*I)*exp(q*y), (3, 4) = 0, (4, 2) = -(1/2)*2^(1/2), (4, 3) = -((1/2)*I)*exp(q*y), (4, 4) = 0}]

    (17)

     

    The tetrad is now the matrix M. In addition to checking this tetrad making use of the IsTetrad command, it is also possible to check the definitions of tetrads and null vectors using TensorArray.

    e_[definition]

    Physics:-Tetrads:-e_[a, `&mu;`]*Physics:-Tetrads:-e_[b, `~&mu;`] = Physics:-Tetrads:-eta_[a, b]

    (18)

    TensorArray(Physics:-Tetrads:-e_[a, `&mu;`]*Physics:-Tetrads:-e_[b, `~&mu;`] = Physics:-Tetrads:-eta_[a, b], simplifier = simplify)

    Matrix(%id = 18446744078353048270)

    (19)

    For the null vectors:

    l_[definition]

    Physics:-Tetrads:-l_[mu]*Physics:-Tetrads:-l_[`~mu`] = 0, Physics:-Tetrads:-l_[mu]*Physics:-Tetrads:-n_[`~mu`] = 1, Physics:-Tetrads:-l_[mu]*Physics:-Tetrads:-m_[`~mu`] = 0, Physics:-Tetrads:-l_[mu]*Physics:-Tetrads:-mb_[`~mu`] = 0, Physics:-g_[mu, nu] = Physics:-Tetrads:-l_[mu]*Physics:-Tetrads:-n_[nu]+Physics:-Tetrads:-l_[nu]*Physics:-Tetrads:-n_[mu]-Physics:-Tetrads:-m_[mu]*Physics:-Tetrads:-mb_[nu]-Physics:-Tetrads:-m_[nu]*Physics:-Tetrads:-mb_[mu]

    (20)

    TensorArray([Physics:-Tetrads:-l_[mu]*Physics:-Tetrads:-l_[`~mu`] = 0, Physics:-Tetrads:-l_[mu]*Physics:-Tetrads:-n_[`~mu`] = 1, Physics:-Tetrads:-l_[mu]*Physics:-Tetrads:-m_[`~mu`] = 0, Physics:-Tetrads:-l_[mu]*Physics:-Tetrads:-mb_[`~mu`] = 0, Physics[g_][mu, nu] = Physics:-Tetrads:-l_[mu]*Physics:-Tetrads:-n_[nu]+Physics:-Tetrads:-l_[nu]*Physics:-Tetrads:-n_[mu]-Physics:-Tetrads:-m_[mu]*Physics:-Tetrads:-mb_[nu]-Physics:-Tetrads:-m_[nu]*Physics:-Tetrads:-mb_[mu]], simplifier = simplify)

    [0 = 0, 1 = 1, 0 = 0, 0 = 0, Matrix(%id = 18446744078414241910)]

    (21)

    From its Weyl scalars, this tetrad is already in the canonical form for a spacetime of Petrov type "D": only `&Psi;__2` <> 0

    PetrovType()

    "D"

    (22)

    Weyl[scalars]

    psi__0 = 0, psi__1 = 0, psi__2 = -(1/6)*q^2, psi__3 = 0, psi__4 = 0

    (23)

    Attempting to transform it into canonicalform returns the tetrad (17) itself

    TransformTetrad(canonicalform)

    Matrix(%id = 18446744078396685478)

    (24)

    Let's now obtain the correct tetrad without changing the signature as done in (13).

    Start by changing the signature back to "(- - - +)"

    Setup(signature = "---+")

    [signature = `- - - +`]

    (25)

    So again, M is not a tetrad, even if the spacetime index is specified as contravariant.

    IsTetrad(e_[a, `~&mu;`] = M)

    `Warning, the given components form a`*null*`tetrad, `*`with a contravariant spacetime index`*`, only if you change the signature from `*`- - - +`*` to `*`+ - - -`*`. 
You can do that by entering (copy and paste): `*Setup(signature = "+ - - -")

     

    false

    (26)

    By construction, the tetrad M has its rows formed by the null vectors with the ordering [l, n, m, conjugate(m)]. To understand what needs to be changed in M, define those vectors, independent of the null vectors [l_, n_, m_, mb_] (with underscore) that come with the Tetrads package.

    Define(l[mu], n[mu], m[mu], mb[mu], quiet)

    and set their components using the matrix M taking into account that its spacetime index is contravariant, and equating the rows of M  using the ordering [l, n, m, conjugate(m)]:

    `~`[`=`]([l[`~&mu;`], n[`~&mu;`], m[`~&mu;`], mb[`~&mu;`]], [seq(M[j, 1 .. 4], j = 1 .. 4)])

    [l[`~&mu;`] = Vector[row](%id = 18446744078368885086), n[`~&mu;`] = Vector[row](%id = 18446744078368885206), m[`~&mu;`] = Vector[row](%id = 18446744078368885326), mb[`~&mu;`] = Vector[row](%id = 18446744078368885446)]

    (27)

    "Define(op(?))"

    `Defined objects with tensor properties`

     

    {Physics:-D_[mu], Physics:-Dgamma[mu], Physics:-Psigma[mu], Physics:-Ricci[mu, nu], Physics:-Riemann[mu, nu, alpha, beta], Physics:-Weyl[mu, nu, alpha, beta], Physics:-d_[mu], Physics:-Tetrads:-e_[a, mu], Physics:-Tetrads:-eta_[a, b], Physics:-g_[mu, nu], Physics:-gamma_[i, j], Physics:-Tetrads:-gamma_[a, b, c], l[mu], Physics:-Tetrads:-l_[mu], Physics:-Tetrads:-lambda_[a, b, c], m[mu], Physics:-Tetrads:-m_[mu], mb[mu], Physics:-Tetrads:-mb_[mu], n[mu], Physics:-Tetrads:-n_[mu], Physics:-Christoffel[mu, nu, alpha], Physics:-Einstein[mu, nu], Physics:-LeviCivita[alpha, beta, mu, nu], Physics:-SpaceTimeVector[mu](X)}

    (28)

    Check the covariant components of these vectors towards comparing them with the lines of the Maple's tetrad `&efr;`[a, mu]

    l[], n[], m[], mb[]

    l[mu] = Array(%id = 18446744078298368710), n[mu] = Array(%id = 18446744078298365214), m[mu] = Array(%id = 18446744078298359558), mb[mu] = Array(%id = 18446744078298341734)

    (29)

    This shows the [l_, n_, m_, mb_] null vectors (with underscore) that come with Tetrads package

    e_[nullvectors]

    Physics:-Tetrads:-l_[mu] = Vector[row](%id = 18446744078354520414), Physics:-Tetrads:-n_[mu] = Vector[row](%id = 18446744078354520534), Physics:-Tetrads:-m_[mu] = Vector[row](%id = 18446744078354520654), Physics:-Tetrads:-mb_[mu] = Vector[row](%id = 18446744078354520774)

    (30)

    So (29) computed from M is the same as (30) computed from Maple's tetrad.

    But, from (30) and the form of Maple's tetrad

    e_[]

    Physics:-Tetrads:-e_[a, mu] = Matrix(%id = 18446744078297844182)

    (31)

    for the current signature

    Setup(signature)

    [signature = `- - - +`]

    (32)

    we see the ordering of the null vectors is [n, m, mb, l], not [l, n, m, mb] used in [1] with the signature (+ - - -). So the adjustment required in  M, resulting in "M^( ')", consists of reordering M's rows to be [n, m, mb, l]

    `#msup(mi("M"),mrow(mo("&InvisibleTimes;"),mo("&apos;")))` := simplify(Matrix(4, map(Library:-TensorComponents, [n[mu], m[mu], mb[mu], l[mu]])))

    Matrix(%id = 18446744078414243230)

    (33)

    IsTetrad(`#msup(mi("M"),mrow(mo("&InvisibleTimes;"),mo("&apos;")))`)

    `Type of tetrad: `*null

     

    true

    (34)

    Comparing "M^( ')" with the tetrad `&efr;`[a, mu]computed by Maple ((24) and (31), they are actually the same.

    References

    [1]. Rainer Burghardt, "Constructing the Godel Universe", the arxiv gr-qc/0106070 2001.

    [2]. Frank Grave and Michael Buser, "Visiting the Gödel Universe",  IEEE Trans Vis Comput GRAPH, 14(6):1563-70, 2008.


     

    Download Godel_universe_and_Tedrads.mw

    H

    ICs:=u(0,0) =0, D[2](u)(0,0)=1,v(0,0) =1, D[2](v)(0,0)=1,D[1](u)(0,0)=0, D[1](v)(0,0)=0. #(any ics shold be 6)

    num_solution := pdsolve(sys, {ICs}, numeric);

    it might the issue with ICS .. 

    any valuable comments

    The 2020 Maple Conference is coming up fast! It is running from November 2-6 this year, all remotely, and completely free.

    The week will be packed with activities, and we have designed it so that it will be valuable for Maple users of all skill and experience levels. The agenda includes 3 keynote presentations, 2 live panel presentations, 8 Maplesoft recorded presentations, 3 Maple workshops, and 68 contributed recorded presentations.

    There will be live Q&A’s for every presentation. Additionally, we are hosting what we’re calling “Virtual Tables” at every breakfast (8-9am EST) and almost every lunch (12-1 EST). These tables offer attendees a chance to discuss topics related to the conference streams of the day, as well as a variety of special topics and social discussions. You can review the schedule for these virtual tables here.

    Attendance is completely free, and we’re confident that there will be something there for all Maple users. Whether you attend one session or all of them, we’d love to see you there!

    You can register for the Maple Conference here.


    In a recent question in Mapleprimes, a spacetime (metric) solution to Einstein's equations, from chapter 27 of the book of Exact Solutions to Einstein's equations [1] was discussed. One of the issues was about computing a tetrad for that solution [27, 37, 1] such that the corresponding Weyl scalars are in canonical form. This post illustrates how to do that, with precisely that spacetime metric solution, in two different ways: 1) automatically, all in one go, and 2) step-by-step. The step-by-step computation is useful to verify results and also to compute different forms of the tetrads or Weyl scalars. The computation below is performed using the latest version of the Maplesoft Physics Updates.

     

    with(Physics)

    Physics:-Version()

    `The "Physics Updates" version in the MapleCloud is 851 and is the same as the version installed in this computer, created 2020, October 19, 13:47 hours Pacific Time.`

    (1)

    The starting point is this image of page 421 of the book of Exact Solutions to Einstein's equations, formulas (27.37)

     

    Load the solution [27, 37, 1] from Maple's database of solutions to Einstein's equations

    g_[[27, 37, 1]]

    _______________________________________________________

     

    `Systems of spacetime coordinates are:`*{X = (z, zb, r, u)}

     

    `Default differentiation variables for d_, D_ and dAlembertian are:`*{X = (z, zb, r, u)}

     

    `The `*`Robinson and Trautman (1962)`*` metric in coordinates `*[z, zb, r, u]

     

    `Parameters: `*[P(z, zb, u), H(X)]

     

    "`Comments: ` admits geodesic, shearfree, twistfree null congruence, rho=-1/r=rho_b"

     

    `Resetting the signature of spacetime from `*`- - - +`*` to `*`+ + + -`*` in order to match the signature in the database of metrics`

     

    _______________________________________________________

     

    `Setting `*lowercaselatin_is*` letters to represent `*space*` indices`

     

    Physics:-g_[mu, nu] = Matrix(%id = 18446744078276690638)

    (2)

    "CompactDisplay(?)"

    H(X)*`will now be displayed as`*H

     

    P(z, zb, u)*`will now be displayed as`*P

    (3)

    The assumptions on the metric's parameters are

    Assume(P(z, zb, u) > 0, (H(X))::real, r >= 0)

     

    The line element is as shown in the second line of the image above

    g_[lineelement]

    2*r^2*Physics:-d_(z)*Physics:-d_(zb)/P(z, zb, u)^2-2*Physics:-d_(r)*Physics:-d_(u)-2*H(X)*Physics:-d_(u)^2

    (4)

    Load Tetrads

    with(Tetrads)

    _______________________________________________________

     

    `Setting `*lowercaselatin_ah*` letters to represent `*tetrad*` indices`

     

    ((`Defined as tetrad tensors `*`see <a href='http://www.maplesoft.com/support/help/search.aspx?term=Physics,tetrads`*`,' target='_new'>?Physics,tetrads`*`,</a> `*`&efr;`[a, mu]*`, `)*eta[a, b]*`, `*gamma[a, b, c]*`, `)*lambda[a, b, c]

     

    ((`Defined as spacetime tensors representing the NP null vectors of the tetrad formalism `*`see <a href='http://www.maplesoft.com/support/help/search.aspx?term=Physics,tetrads`*`,' target='_new'>?Physics,tetrads`*`,</a> `*l[mu]*`, `)*n[mu]*`, `*m[mu]*`, `)*conjugate(m[mu])

     

    _______________________________________________________

    (5)

    The Petrov type of this spacetime solution is

    PetrovType()

    "II"

    (6)

    The null tetrad computed by the Maple system using a general algorithms is

    Setup(tetrad = null)

    e_[]

    Physics:-Tetrads:-e_[a, mu] = Matrix(%id = 18446744078178770326)

    (7)

     

    According to the help page TransformTetrad , the canonical form of the Weyl scalars for each different Petrov type is

     

    So for type II, when the tetrad is in canonical form, we expect only `&Psi;__2` and `&Psi;__3` different from 0. For the tetrad computed automatically, however, the scalars are

    Weyl[scalars]

    psi__0 = -P(z, zb, u)*(2*(diff(P(z, zb, u), z))*(diff(H(X), z))+P(z, zb, u)*(diff(diff(H(X), z), z)))/(r^2*(H(X)^2+1)^(1/2)), psi__1 = ((1/2)*I)*(-(diff(diff(H(X), r), z))*P(z, zb, u)^2*r+2*P(z, zb, u)^2*(diff(H(X), z))-(diff(P(z, zb, u), u))*(diff(P(z, zb, u), z))*r+(diff(diff(P(z, zb, u), u), z))*r*P(z, zb, u))/(P(z, zb, u)*r^2*(H(X)^2+1)^(1/4)), psi__2 = (1/6)*((diff(diff(H(X), r), r))*r^2+2*(diff(P(z, zb, u), z))*(diff(P(z, zb, u), zb))-2*(diff(H(X), r))*r-2*(diff(diff(P(z, zb, u), z), zb))*P(z, zb, u)+2*H(X))/r^2, psi__3 = 0, psi__4 = 0

    (8)

    The question is, how to bring the tetrad `&efr;`[a, mu] (equation (7)) into canonical form. The plan for that is outlined in Chapter 7, by Chandrasekhar, page 388, of the book "General Relativity, an Einstein centenary survey", edited by S.W. Hawking and W.Israel. In brief, for Petrov type II, use a transformation ofClass[2] to make Psi[0] = `&Psi;__1` and `&Psi;__1` = 0, then a transformation of Class[1] making Psi[4] = 0, finally use a transformation of Class[3] making Psi[3] = 1. For an explanation of these transformations see the help page for TransformTetrad . This plan, however, is applicable if and only if the starting tetrad results in `&psi;__4` <> 0, which we see in (8) it is not the case, so we need, in addition, before applying this plan, to perform a transformation of Class[1] making `&psi;__4` <> 0.

     

    In what follows, the transformations mentioned are first performed automatically, in one go, letting the computer deduce each intermediate transformation, by passing to TransformTetrad the optional argument canonicalform. Then, the same result is obtained by transforming the starting tetrad  one step at at time, arriving at the same Weyl scalars. That illustrates well both how to get the result exploiting advanced functionality but also how to verify the result performing each step, and also how to get any desired different form of the Weyl scalars.

     

    Although it is possible to perform both computations, automatically and step-by-step, departing from the tetrad (7), that tetrad and the corresponding Weyl scalars (8) have radicals, making the readability of the formulas at each step less clear. Both computations, can be presented in more readable form without radicals departing from the tetrad shown in the book, that is

    e_[a, mu] = (Matrix(4, 4, {(1, 1) = 0, (1, 2) = 0, (1, 3) = 0, (1, 4) = -1, (2, 1) = 0, (2, 2) = r/P(z, zb, u), (2, 3) = 0, (2, 4) = 0, (3, 1) = r/P(z, zb, u), (3, 2) = 0, (3, 3) = 0, (3, 4) = 0, (4, 1) = 0, (4, 2) = 0, (4, 3) = -1, (4, 4) = -H(X)}))

    Physics:-Tetrads:-e_[a, mu] = Matrix(%id = 18446744078621688766)

    (9)

    "IsTetrad(?)"

    `Type of tetrad: `*null

     

    true

    (10)

    The corresponding Weyl scalars free of radicals are

    "WeylScalars(?)"

    psi__0 = P(z, zb, u)*(2*(diff(P(z, zb, u), z))*(diff(H(X), z))+P(z, zb, u)*(diff(diff(H(X), z), z)))/r^2, psi__1 = -(1/2)*(-(diff(diff(H(X), r), z))*P(z, zb, u)^2*r+2*P(z, zb, u)^2*(diff(H(X), z))-(diff(P(z, zb, u), u))*(diff(P(z, zb, u), z))*r+(diff(diff(P(z, zb, u), u), z))*r*P(z, zb, u))/(r^2*P(z, zb, u)), psi__2 = -(1/6)*(-(diff(diff(H(X), r), r))*r^2+2*(diff(H(X), r))*r-2*(diff(P(z, zb, u), z))*(diff(P(z, zb, u), zb))+2*(diff(diff(P(z, zb, u), z), zb))*P(z, zb, u)-2*H(X))/r^2, psi__3 = 0, psi__4 = 0

    (11)

    So set this tetrad as the starting point

    "Setup(?)"

    [tetrad = {(1, 4) = -1, (2, 2) = r/P(z, zb, u), (3, 1) = r/P(z, zb, u), (4, 3) = -1, (4, 4) = -H(X)}]

    (12)


    All the transformations performed automatically, in one go

     

    To arrive in one go, automatically, to a tetrad whose Weyl scalars are in canonical form as in (31), use the optional argument canonicalform:

    T__5 := TransformTetrad(canonicalform)

    WeylScalars(T__5)

    psi__0 = 0, psi__1 = 0, psi__2 = -(1/6)*(-(diff(diff(H(X), r), r))*r^2+2*(diff(H(X), r))*r-2*(diff(P(z, zb, u), z))*(diff(P(z, zb, u), zb))+2*(diff(diff(P(z, zb, u), z), zb))*P(z, zb, u)-2*H(X))/r^2, psi__3 = 1, psi__4 = 0

    (13)

    Note the length of T__5

    length(T__5)

    58242

    (14)

    That length corresponds to several pages long. That happens frequently, you get Weyl scalars with a minimum of residual invariance, at the cost of a more complicated tetrad.

     

    The transformations step-by-step leading to the same canonical form of the Weyl scalars

     

    Step 0

     

    As mentioned above, to apply the plan outlined by Chandrasekhar, the starting point needs to be a tetrad with `&Psi;__4` <> 0, not the case of (9), so in this step 0 we use a transformation of Class[1] making `&psi;__4` <> 0. This transformation introduces a complex parameter E and to get `&psi;__4` <> 0 any value of E suffices. We use E = 1:

    TransformTetrad(nullrotationwithfixedl_)

    Matrix(%id = 18446744078634914990)

    (15)

    "`T__0` := eval(?,E=1)"

    Matrix(%id = 18446744078634940646)

    (16)

    Indeed, for this tetrad, `&Psi;__4` <> 0:

    WeylScalars(T__0)[-1]

    psi__4 = ((diff(diff(H(X), r), r))*r^2*P(z, zb, u)+P(z, zb, u)^3*(diff(diff(H(X), z), z))+2*(diff(P(z, zb, u), z))*(diff(H(X), z))*P(z, zb, u)^2+2*(diff(diff(H(X), r), z))*P(z, zb, u)^2*r+2*(diff(P(z, zb, u), z))*(diff(P(z, zb, u), zb))*P(z, zb, u)+2*(diff(P(z, zb, u), u))*(diff(P(z, zb, u), z))*r-4*P(z, zb, u)^2*(diff(H(X), z))-2*(diff(diff(P(z, zb, u), z), zb))*P(z, zb, u)^2-2*(diff(H(X), r))*P(z, zb, u)*r-2*(diff(diff(P(z, zb, u), u), z))*r*P(z, zb, u)+2*H(X)*P(z, zb, u))/(r^2*P(z, zb, u))

    (17)

    Step 1

    Next is a transformation of Class__2 to make `&Psi;__0` = 0, that in the case of Petrov type II also implies on `&Psi;__1` = 0.According to the the help page TransformTetrad , this transformation introduces a parameter B that, according to the plan outlined by Chandrasekhar in Chapter 7 page 388, is one of the two identical roots (out of the four roots) of the principalpolynomial. To see the principal polynomial, or, directly, its roots you can use the PetrovType  command:

    PetrovType(principalroots = 'R')

    "II"

    (18)

    The first two are the same and equal to -1

    R[1 .. 2]

    [-1, -1]

    (19)

    So the transformed tetrad T__1 is

    T__1 := eval(TransformTetrad(T__0, nullrotationwithfixedn_), B = -1)

    Matrix(%id = 18446744078641721462)

    (20)

    Check this result and the corresponding Weyl scalars to verify that we now have `&Psi;__0` = 0 and `&Psi;__1` = 0

    IsTetrad(T__1)

    `Type of tetrad: `*null

     

    true

    (21)

    WeylScalars(T__1)[1 .. 2]

    psi__0 = 0, psi__1 = 0

    (22)

    Step 2

    Next is a transformation of Class__1 that makes `&Psi;__4` = 0. This transformation introduces a parameter E, that according to Chandrasekhar's plan can be taken equal to one of the roots of Weyl scalar `&Psi;__4`that corresponds to the transformed tetrad. So we need to proceed in three steps:

    a. 

    transform the tetrad introducing a parameter E in the tetrad's components

    b. 

    compute the Weyl scalars for that transformed tetrad

    c. 

    take `&Psi;__4` = 0 and solve for E

    d. 

    apply the resulting value of E to the transformed tetrad obtained in step a.

     

    a.Transform the tetrad and for simplicity take E real

    T__2 := eval(TransformTetrad(T__1, nullrotationwithfixedl_), conjugate(E) = E)

    Matrix(%id = 18446744078624751238)

    (23)

    "IsTetrad(?)"

    `Type of tetrad: `*null

     

    true

    (24)

    b. Compute `&Psi;__4` for this tetrad

    simplify(WeylScalars(T__2)[-1])

    psi__4 = (r^2*P(z, zb, u)*(E-1)^2*(diff(diff(H(X), r), r))-2*r*P(z, zb, u)^2*(E-1)*(diff(diff(H(X), r), z))+P(z, zb, u)^3*(diff(diff(H(X), z), z))-2*P(z, zb, u)^2*(E-1)^2*(diff(diff(P(z, zb, u), z), zb))+2*r*P(z, zb, u)*(E-1)*(diff(diff(P(z, zb, u), u), z))-2*r*P(z, zb, u)*(E-1)^2*(diff(H(X), r))+4*P(z, zb, u)^2*(E+(1/2)*(diff(P(z, zb, u), z))-1)*(diff(H(X), z))+2*((P(z, zb, u)*(E-1)*(diff(P(z, zb, u), zb))-(diff(P(z, zb, u), u))*r)*(diff(P(z, zb, u), z))+H(X)*P(z, zb, u)*(E-1))*(E-1))/(r^2*P(z, zb, u))

    (25)

    c. Solve `&Psi;__4` = 0 discarding the case E = 0 which implies on no transformation

    simplify(solve({rhs(psi__4 = (r^2*P(z, zb, u)*(E-1)^2*(diff(diff(H(X), r), r))-2*r*P(z, zb, u)^2*(E-1)*(diff(diff(H(X), r), z))+P(z, zb, u)^3*(diff(diff(H(X), z), z))-2*P(z, zb, u)^2*(E-1)^2*(diff(diff(P(z, zb, u), z), zb))+2*r*P(z, zb, u)*(E-1)*(diff(diff(P(z, zb, u), u), z))-2*r*P(z, zb, u)*(E-1)^2*(diff(H(X), r))+4*P(z, zb, u)^2*(E+(1/2)*(diff(P(z, zb, u), z))-1)*(diff(H(X), z))+2*((P(z, zb, u)*(E-1)*(diff(P(z, zb, u), zb))-(diff(P(z, zb, u), u))*r)*(diff(P(z, zb, u), z))+H(X)*P(z, zb, u)*(E-1))*(E-1))/(r^2*P(z, zb, u))) = 0, E <> 0}, {E}, explicit)[1])

    {E = ((diff(diff(H(X), r), r))*r^2*P(z, zb, u)+(diff(diff(H(X), r), z))*P(z, zb, u)^2*r-2*(diff(H(X), r))*P(z, zb, u)*r-(diff(diff(P(z, zb, u), u), z))*r*P(z, zb, u)+(diff(P(z, zb, u), u))*(diff(P(z, zb, u), z))*r-2*P(z, zb, u)^2*(diff(H(X), z))-2*(diff(diff(P(z, zb, u), z), zb))*P(z, zb, u)^2+2*(diff(P(z, zb, u), z))*(diff(P(z, zb, u), zb))*P(z, zb, u)+2*H(X)*P(z, zb, u)+(-P(z, zb, u)^4*((diff(diff(H(X), r), r))*r^2+2*(diff(P(z, zb, u), z))*(diff(P(z, zb, u), zb))-2*(diff(H(X), r))*r-2*(diff(diff(P(z, zb, u), z), zb))*P(z, zb, u)+2*H(X))*(diff(diff(H(X), z), z))+P(z, zb, u)^4*(diff(diff(H(X), r), z))^2*r^2+(-2*r^2*(diff(diff(P(z, zb, u), u), z))*P(z, zb, u)^3+2*r^2*P(z, zb, u)^2*(diff(P(z, zb, u), u))*(diff(P(z, zb, u), z))-4*r*(diff(H(X), z))*P(z, zb, u)^4)*(diff(diff(H(X), r), z))-2*(diff(P(z, zb, u), z))*(diff(H(X), z))*P(z, zb, u)^3*(diff(diff(H(X), r), r))*r^2+P(z, zb, u)^2*(diff(diff(P(z, zb, u), u), z))^2*r^2+(-2*r^2*P(z, zb, u)*(diff(P(z, zb, u), u))*(diff(P(z, zb, u), z))+4*r*(diff(H(X), z))*P(z, zb, u)^3)*(diff(diff(P(z, zb, u), u), z))+4*(diff(P(z, zb, u), z))*(diff(H(X), z))*P(z, zb, u)^4*(diff(diff(P(z, zb, u), z), zb))+4*(diff(H(X), z))^2*P(z, zb, u)^4+4*P(z, zb, u)^2*(diff(P(z, zb, u), z))*((diff(H(X), r))*P(z, zb, u)*r-(diff(P(z, zb, u), z))*(diff(P(z, zb, u), zb))*P(z, zb, u)-(diff(P(z, zb, u), u))*r-H(X)*P(z, zb, u))*(diff(H(X), z))+(diff(P(z, zb, u), u))^2*(diff(P(z, zb, u), z))^2*r^2)^(1/2))/(P(z, zb, u)*((diff(diff(H(X), r), r))*r^2+2*(diff(P(z, zb, u), z))*(diff(P(z, zb, u), zb))-2*(diff(H(X), r))*r-2*(diff(diff(P(z, zb, u), z), zb))*P(z, zb, u)+2*H(X)))}

    (26)

    d. Apply this result to the tetrad (23). In doing so, do not display the result, just measure its length (corresponds to two+ pages)

    T__3 := simplify(eval(T__2, {E = ((diff(diff(H(X), r), r))*r^2*P(z, zb, u)+(diff(diff(H(X), r), z))*P(z, zb, u)^2*r-2*(diff(H(X), r))*P(z, zb, u)*r-(diff(diff(P(z, zb, u), u), z))*r*P(z, zb, u)+(diff(P(z, zb, u), u))*(diff(P(z, zb, u), z))*r-2*P(z, zb, u)^2*(diff(H(X), z))-2*(diff(diff(P(z, zb, u), z), zb))*P(z, zb, u)^2+2*(diff(P(z, zb, u), z))*(diff(P(z, zb, u), zb))*P(z, zb, u)+2*H(X)*P(z, zb, u)+(-P(z, zb, u)^4*((diff(diff(H(X), r), r))*r^2+2*(diff(P(z, zb, u), z))*(diff(P(z, zb, u), zb))-2*(diff(H(X), r))*r-2*(diff(diff(P(z, zb, u), z), zb))*P(z, zb, u)+2*H(X))*(diff(diff(H(X), z), z))+P(z, zb, u)^4*(diff(diff(H(X), r), z))^2*r^2+(-2*r^2*(diff(diff(P(z, zb, u), u), z))*P(z, zb, u)^3+2*r^2*P(z, zb, u)^2*(diff(P(z, zb, u), u))*(diff(P(z, zb, u), z))-4*r*(diff(H(X), z))*P(z, zb, u)^4)*(diff(diff(H(X), r), z))-2*(diff(P(z, zb, u), z))*(diff(H(X), z))*P(z, zb, u)^3*(diff(diff(H(X), r), r))*r^2+P(z, zb, u)^2*(diff(diff(P(z, zb, u), u), z))^2*r^2+(-2*r^2*P(z, zb, u)*(diff(P(z, zb, u), u))*(diff(P(z, zb, u), z))+4*r*(diff(H(X), z))*P(z, zb, u)^3)*(diff(diff(P(z, zb, u), u), z))+4*(diff(P(z, zb, u), z))*(diff(H(X), z))*P(z, zb, u)^4*(diff(diff(P(z, zb, u), z), zb))+4*(diff(H(X), z))^2*P(z, zb, u)^4+4*P(z, zb, u)^2*(diff(P(z, zb, u), z))*((diff(H(X), r))*P(z, zb, u)*r-(diff(P(z, zb, u), z))*(diff(P(z, zb, u), zb))*P(z, zb, u)-(diff(P(z, zb, u), u))*r-H(X)*P(z, zb, u))*(diff(H(X), z))+(diff(P(z, zb, u), u))^2*(diff(P(z, zb, u), z))^2*r^2)^(1/2))/(P(z, zb, u)*((diff(diff(H(X), r), r))*r^2+2*(diff(P(z, zb, u), z))*(diff(P(z, zb, u), zb))-2*(diff(H(X), r))*r-2*(diff(diff(P(z, zb, u), z), zb))*P(z, zb, u)+2*H(X)))}[1]))

    length(T__3)

    12589

    (27)

    Check the scalars, we expect `&Psi;__0` = `&Psi;__1` and `&Psi;__1` = `&Psi;__4` and `&Psi;__4` = 0

    WeylScalars(T__3); %[1 .. 2], %[-1]

    psi__0 = 0, psi__1 = 0, psi__4 = 0

    (28)

    Step 3

    Use a transformation of Class[3] making Psi[3] = 1. Such a transformation changes Psi[3]^` '` = A*exp(-I*Omega)*Psi[3], where we need to take A*exp(-I*Omega) = 1/`&Psi;__3`, and without loss of generality we can take Omega = 0.

    Check first the value of `&Psi;__3` in the last tetrad computed

    WeylScalars(T__3)[4]

    psi__3 = (1/2)*(-2*(diff(P(z, zb, u), z))*(diff(H(X), z))*P(z, zb, u)^3*(diff(diff(H(X), r), r))*r^2-P(z, zb, u)^4*(diff(diff(H(X), z), z))*(diff(diff(H(X), r), r))*r^2+P(z, zb, u)^4*(diff(diff(H(X), r), z))^2*r^2+4*(diff(P(z, zb, u), z))*(diff(H(X), r))*(diff(H(X), z))*P(z, zb, u)^3*r+2*(diff(H(X), r))*P(z, zb, u)^4*(diff(diff(H(X), z), z))*r-4*(diff(P(z, zb, u), zb))*(diff(P(z, zb, u), z))^2*(diff(H(X), z))*P(z, zb, u)^3+4*(diff(P(z, zb, u), z))*(diff(H(X), z))*P(z, zb, u)^4*(diff(diff(P(z, zb, u), z), zb))-4*(diff(H(X), z))*P(z, zb, u)^4*(diff(diff(H(X), r), z))*r+2*(diff(P(z, zb, u), u))*(diff(P(z, zb, u), z))*P(z, zb, u)^2*(diff(diff(H(X), r), z))*r^2-2*(diff(P(z, zb, u), zb))*(diff(P(z, zb, u), z))*P(z, zb, u)^4*(diff(diff(H(X), z), z))+2*P(z, zb, u)^5*(diff(diff(H(X), z), z))*(diff(diff(P(z, zb, u), z), zb))-2*P(z, zb, u)^3*(diff(diff(P(z, zb, u), u), z))*(diff(diff(H(X), r), z))*r^2+4*(diff(H(X), z))^2*P(z, zb, u)^4-4*(diff(P(z, zb, u), u))*(diff(P(z, zb, u), z))*(diff(H(X), z))*P(z, zb, u)^2*r-4*H(X)*(diff(P(z, zb, u), z))*(diff(H(X), z))*P(z, zb, u)^3+4*(diff(H(X), z))*P(z, zb, u)^3*(diff(diff(P(z, zb, u), u), z))*r+(diff(P(z, zb, u), u))^2*(diff(P(z, zb, u), z))^2*r^2-2*(diff(P(z, zb, u), u))*(diff(P(z, zb, u), z))*P(z, zb, u)*(diff(diff(P(z, zb, u), u), z))*r^2-2*H(X)*P(z, zb, u)^4*(diff(diff(H(X), z), z))+P(z, zb, u)^2*(diff(diff(P(z, zb, u), u), z))^2*r^2)^(1/2)/(r^2*P(z, zb, u))

    (29)

    So, the transformed tetrad T__4 to which corresponds Weyl scalars in canonical form, with `&Psi;__0` = `&Psi;__1` and `&Psi;__1` = `&Psi;__4` and `&Psi;__4` = 0 and `&Psi;__3` = 1, is

    T__4 := simplify(eval(TransformTetrad(T__3, boostsn_l_plane), A = 1/rhs(psi__3 = (1/2)*(-2*(diff(P(z, zb, u), z))*(diff(H(X), z))*P(z, zb, u)^3*(diff(diff(H(X), r), r))*r^2-P(z, zb, u)^4*(diff(diff(H(X), z), z))*(diff(diff(H(X), r), r))*r^2+P(z, zb, u)^4*(diff(diff(H(X), r), z))^2*r^2+4*(diff(P(z, zb, u), z))*(diff(H(X), r))*(diff(H(X), z))*P(z, zb, u)^3*r+2*(diff(H(X), r))*P(z, zb, u)^4*(diff(diff(H(X), z), z))*r-4*(diff(P(z, zb, u), zb))*(diff(P(z, zb, u), z))^2*(diff(H(X), z))*P(z, zb, u)^3+4*(diff(P(z, zb, u), z))*(diff(H(X), z))*P(z, zb, u)^4*(diff(diff(P(z, zb, u), z), zb))-4*(diff(H(X), z))*P(z, zb, u)^4*(diff(diff(H(X), r), z))*r+2*(diff(P(z, zb, u), u))*(diff(P(z, zb, u), z))*P(z, zb, u)^2*(diff(diff(H(X), r), z))*r^2-2*(diff(P(z, zb, u), zb))*(diff(P(z, zb, u), z))*P(z, zb, u)^4*(diff(diff(H(X), z), z))+2*P(z, zb, u)^5*(diff(diff(H(X), z), z))*(diff(diff(P(z, zb, u), z), zb))-2*P(z, zb, u)^3*(diff(diff(P(z, zb, u), u), z))*(diff(diff(H(X), r), z))*r^2+4*(diff(H(X), z))^2*P(z, zb, u)^4-4*(diff(P(z, zb, u), u))*(diff(P(z, zb, u), z))*(diff(H(X), z))*P(z, zb, u)^2*r-4*H(X)*(diff(P(z, zb, u), z))*(diff(H(X), z))*P(z, zb, u)^3+4*(diff(H(X), z))*P(z, zb, u)^3*(diff(diff(P(z, zb, u), u), z))*r+(diff(P(z, zb, u), u))^2*(diff(P(z, zb, u), z))^2*r^2-2*(diff(P(z, zb, u), u))*(diff(P(z, zb, u), z))*P(z, zb, u)*(diff(diff(P(z, zb, u), u), z))*r^2-2*H(X)*P(z, zb, u)^4*(diff(diff(H(X), z), z))+P(z, zb, u)^2*(diff(diff(P(z, zb, u), u), z))^2*r^2)^(1/2)/(r^2*P(z, zb, u)))))

    IsTetrad(T__4)

    `Type of tetrad: `*null

     

    true

    (30)

    WeylScalars(T__4)

    psi__0 = 0, psi__1 = 0, psi__2 = -(1/6)*(-(diff(diff(H(X), r), r))*r^2+2*(diff(H(X), r))*r+2*(diff(diff(P(z, zb, u), z), zb))*P(z, zb, u)-2*(diff(P(z, zb, u), z))*(diff(P(z, zb, u), zb))-2*H(X))/r^2, psi__3 = 1, psi__4 = 0

    (31)

    These are the same scalars computed in one go in (13)

    psi__0 = 0, psi__1 = 0, psi__2 = -(1/6)*(-(diff(diff(H(X), r), r))*r^2+2*(diff(H(X), r))*r-2*(diff(P(z, zb, u), z))*(diff(P(z, zb, u), zb))+2*(diff(diff(P(z, zb, u), z), zb))*P(z, zb, u)-2*H(X))/r^2, psi__3 = 1, psi__4 = 0

    psi__0 = 0, psi__1 = 0, psi__2 = -(1/6)*(-(diff(diff(H(X), r), r))*r^2+2*(diff(H(X), r))*r-2*(diff(P(z, zb, u), z))*(diff(P(z, zb, u), zb))+2*(diff(diff(P(z, zb, u), z), zb))*P(z, zb, u)-2*H(X))/r^2, psi__3 = 1, psi__4 = 0

    (32)

    ``


     

    Download The_metric_[27_37_1]_in_canonical_form.mw

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

    When we plot a curve with the option  style=point  , symbols go evenly not along the length of this curve, but along the range of the independent variable. For this reason the plot often looks unattractive. Here are two examples. In the first example, the default option  adaptive=true  is used, in which Maple adds points in some places.

    restart;
    plot(surd(x,3), x=-2.5..2.5, style=point, scaling=constrained, symbol=solidcircle, symbolsize=8, numpoints=30, size=[800,300]);
    plot(surd(x,3), x=-2.5..2.5, style=point, scaling=constrained, symbol=solidcircle, symbolsize=8, numpoints=30, adaptive=false, size=[800,300]);
    

                    

                               


    The  UniformPointPlot  procedure allows you to plot curves by symbols (as for  style=point), and these symbols go from each other at equal distances, measured along this curve. The procedure uses a well-known formula for the length of a curve in two and three dimensions. The procedure parameters are clear from the three examples below.

    UniformPointPlot:=proc(F::{algebraic,list},eq::`=`,n::posint:=40,Opt::list:=[symbol=solidcircle, symbolsize=8, scaling=constrained])
    local t, R, P, g, L, step, L1, L2;
    uses plots;
    Digits:=4:
    t:=lhs(eq); R:=rhs(eq);
    P:=`if`(type(F,algebraic),[t,F],F); 
    g:=x->`if`(F::algebraic or nops(F)=2,evalf(Int(sqrt(diff(P[1],t)^2+diff(P[2],t)^2), t=lhs(R)..x, epsilon=0.001)),evalf(Int(sqrt(diff(P[1],t)^2+diff(P[2],t)^2+diff(P[3],t)^2), t=lhs(R)..x, epsilon=0.001))):
    L:=g(rhs(R)); step:=L/(n-1);
    L1:=[lhs(R),seq(fsolve(g-k*step, fulldigits),k=1..n-2),rhs(R)];
    L2:=map(s->`if`(type(F,algebraic),[s,eval(F,t=s)],eval(F,t=s)), L1):
    `if`(F::algebraic or nops(F)=2,plot(L2, style=point, Opt[]),pointplot3d(L2, Opt[]));
    end proc:
    

       
    Examples of use:

    UniformPointPlot(surd(x,3), x=-2.5..2.5, 30);

                                 

    UniformPointPlot([5*cos(t),3*sin(t)], t=0..2*Pi, [color=red,symbol=solidcircle,scaling=constrained, symbolsize=8,  size=[800,400]]);

                                 

    UniformPointPlot([cos(t),sin(t),2-2*cos(t)], t=0..2*Pi, 41, [color=red,symbol=solidsphere, symbolsize=8,scaling=constrained, labels=[x,y,z]]);

                                 
    Here's another example of using the same technique as in the procedure. In this example, we are plotting Archimedean spiral uniformly colored with 7 rainbow colors:

    f:=t->[t*cos(t),t*sin(t)]:
    g:=t->evalf(Int(sqrt(diff(f(s)[1],s)^2+diff(f(s)[2],s)^2), s=0..t)):
    h:=s->fsolve(s=g(t), t):
    L:=evalf(g(2*Pi)): step:=L/7:
    L1:=[0,seq(h(k*step), k=1..6),2*Pi]:
    Colors:=convert~([Red,Orange,Yellow,Green,Blue,Indigo,Violet], string):
    plots:-display(seq(plot([f(t)[], t=L1[i]..L1[i+1]], color=Colors[i], thickness=12), i=1..7), scaling=constrained, size=[500,400]);
    

                                 

    Uniform_Point_Plot.mw

    A few weeks ago a television station in Toronto asked me if I’d share some tips on how parents could help their kids stay engaged with remote learning. My initial reaction was to run for the hills – appearing on live TV is not my cup of tea. However my colleagues persuaded me to accept. You can see a clip of that segment here - I’ve included it in this post because otherwise someone on the marketing team would have ;-)

    My tips are based on a wide variety of experiences. My role at Maplesoft requires me to speak with educators at all levels, and remote learning has been a hot topic of conversation lately, as you can imagine. As well, in my past life (i.e. life before kids) I was a high school math tutor, and now as a parent I’m in the thick of it helping my son navigate Kindergarten remotely.

    So here are my 5 tips on how parents of elementary and high-school aged children can help their kids stay engaged with remote learning. If you have other tips, including suggestions for university students, feel free to leave them in the comments sections. And if these tips help you, please let me know. It will have made the stress of my appearance on TV worthwhile!

     

    Tip 1: Look for the positives

    These are unprecedented times for kids, parents and teachers. Over the course of the last 6-7 months, learning as we’ve grown to know it has changed radically. And while the change has been incredibility difficult for everyone, it’s helpful to look for the positives that remote learning can bring to our children:

    • Remote learning can help some kids focus on their work by minimizing the social pressures or distractions they may face at school.
    • Older kids are appreciating the flexibility that remote learning can offer with respect to when and how they complete their work.  
    • Younger kids are loving the experience of learning in the presence of mom and dad. My 4 year old thinks it’s awesome that I now know all the lyrics to the songs that he learns in school.
    • As many remote learning classrooms include students from across the school board, this can provide kids with the opportunity to connect with their peers from different socio-economic backgrounds living across the city.

     

    Tip 2: Don’t shy away from your kid’s teacher

    While some kids are thriving learning from home, we know that others are struggling.

    If your high school student is struggling at school, do whatever it takes to convince them to connect with their teacher. If your child is younger, make the connection yourself.

    In my role, I’ve had the opportunity to work with many teachers, and rest assured, many of them would welcome this engagement.  They want our kids to succeed, but without the face-to-face classroom interaction it’s becoming increasingly more difficult for them to rely on visual cues to see how your child is doing and if they are struggling with a concept.

    So I encourage you to reach out to your kid’s teacher especially if you notice your child is having difficulty.

     

    Tip 3: Get creative with learning

    Another benefit of remote learning is that it presents us with a unique opportunity to get creative with learning.

    Kids, especially those in middle school and high school, now have the time and opportunity to engage with a variety of different online learning resources. And when I say online learning resources, I mean more than just videos. Think interactive tools (such as Maple Learn), that help students visualize concepts from math and science, games that allow students to practice language skills, repositories of homework problems and practice questions that allow kids to practice concepts, the list goes on.

    Best of all, many content providers and organizations, are offerings these resources and tools available for free or at a substantially reduced cost to help kids and parents during this time.

    So if your child is having difficulty with a particular subject or if they are in need of a challenge, make sure to explore what is available online.

     

    Tip 4: Embrace the tech

    To be successful, remote learning requires children to learn a host of new digital skills, such as how to mute/unmute themselves, raise their hands electronically, turn on and off their webcam, toggle between applications to access class content and upload homework, keep track of their schedule via an electronic calendar, etc. This can be daunting for kids who are learning remotely for the first time.

    As a parent you can help your child become more comfortable with remote learning by setting aside some time either before or after class to help them master these new tools. And since this is likely new to you, there are some great videos online that will show you how to use the system your school has mandated be it Microsoft Teams, Google Classroom or something else.  

     

    Tip 5: It’s a skill

    Remember that remote learning is a skill like any other skill, and it takes time and practice to become proficient.

    So remember to be patient with yourself, your kids, and their teachers, as we embark on this new journey of learning. Everyone is trying their best and I truly believe a new rhythm will emerge as we progress through the school year.

    We will find our way.

    Examples of mathematical models for the formation of spline curves based on polynomials of various orders that simulate certain trajectories are given.
    Mathematical models of the formation of a spline curve, taking into account the extreme derivatives of the initial orders, are presented. The construction of the spline curves of the hermit and bezier of various orders, consisting of different segments, is considered. The presented models are systematic and universal, i.e. can be used to generate any polynomial curves with specified extreme derivatives of the vectors.

    100_nodes_not_closed.mwExample_1.mwExample_2.mwExample_3.mwExample_4.mwExample_5.mwExample_6.mwExample_7.mw

    «Формирования линий OC и бриджей по линии MAT для области с островами».OC_MAT_MA_bridge.mw

    As an addition to the post.
    Non-orientable surface in the sequence of orientable surfaces. In the picture we see the equations corresponding to the current surface plot.
    Just entertainment.
    surfaces.mw

    We recently published a paper on multiscale-multidomain simulation of battery models.

    https://iopscience.iop.org/article/10.1149/1945-7111/abb37b

    Some challenges are listed at 

    https://twitter.com/UT_MAPLE/status/1311356957941522438

    Maple and symbolic math can play a critical role in solving many challenging problems. For example, consider a seemingly-trivial problem

    uxx+uyy = 0

    x = 0 and x = 1, ux = 0 for all y

    y = 1, u = 0, for all x

    y = 0, u =1, 0<=x<=0.5

    y = 0, uy = 0, 0.5<x<=1

    There is a singularity at (0.5,0) and most numerical methods will have trouble there. In these equations, uxx means the second derivative of u with respect to x.

    Maple can help solve this problem with conformal mapping to achieve arbitrary precision. As of today, machine precision is not possible with any numerical method even with millions of Degrees of Freedom. The Maple code is given below. A FEM code is given below as well. Models like this can benefit from Maple adding parallel sparse direct and iterative solvers.


     

     

    restart;

    Digits:=15;

    Digits := 15

    (1)

     The domain is tranformed from Z = X+IY to w. The points tranformed are

    Zdomain:=[[0,0],[1,0],[1,1],[0,1]];

    Zdomain := [[0, 0], [1, 0], [1, 1], [0, 1]]

    (2)

    wdomain:=[0,1,1+a,a+2];

    wdomain := [0, 1, 1+a, a+2]

    (3)

    eq1:=diff(Z(w),w)=-I*K1/sqrt(w)/sqrt(w-1)/sqrt(w-a-1)/sqrt(w-a-2);

    eq1 := diff(Z(w), w) = -I*K1/(w^(1/2)*(w-1)^(1/2)*(w-a-1)^(1/2)*(w-a-2)^(1/2))

    (4)

     a is not known apriori. The value of a should be found to make sure [1,1] in the Z coordinate is transformed to [1+a] in the w coordinate.

    a:=sqrt(2)-1;

    a := 2^(1/2)-1

    (5)

     Value of K1 is found using the transformation of [1,0] to 1 in the w coordinate

    eq11:=1=int(rhs(eq1),w=0..1);

    eq11 := 1 = -K1*2^(1/2)*EllipticK(2^(1/2)/2)

    (6)

    K1:=solve(eq11,K1);

    K1 := -(1/2)*(2^(1/2)/EllipticK(2^(1/2)/2))

    (7)

     The height Y in the Z coordinate is found by integrating from 1 to 1+a in the w coordinate.

    simplify(int(rhs(eq1),w=1..1+a));

    (2*I)*2^(1/2)*EllipticK((2^(1/2)-1)/(2^(1/2)+1))/(EllipticK(2^(1/2)/2)*(2^(1/2)+1))

    (8)

    evalf(%);

    1.00000000000000*I

    (9)

     The choice of a = sqrt(2)-1 gives the height of 1 for Z coordinate.

    eval(simplify(int(rhs(eq1),w=0..1+a)));

    (2^(1/2)*EllipticK(2^(1/2)/2)+EllipticK(2^(1/2)/2)+(2*I)*2^(1/2)*EllipticK((2^(1/2)-1)/(2^(1/2)+1)))/(EllipticK(2^(1/2)/2)*(2^(1/2)+1))

    (10)

    evalf(%);

    1.00000000000000+1.00000000000001*I

    (11)

     integration from 0 to 1+a in the w coordinate gives 1,1 in the Z coordinate.

    simplify(int(rhs(eq1),w=0..1/sqrt(2)));

    EllipticF(2^(1/2)/(2+2^(1/2))^(1/2), 2^(1/2)/2)/EllipticK(2^(1/2)/2)

    (12)

    evalf(%);

    .500000000000001

    (13)

     Integrating w from 0 to wmid =1/sqrt(2) gives the point 0.5,0 in the Z coordinate

    wmid:=1/sqrt(2);

    wmid := 2^(1/2)/2

    (14)

     Next w domain is transformed to Z2 domain Z2 = X2+IY2

    Z2domain:=[[0,0],[1,0],[1,H],[0,H]];

    Z2domain := [[0, 0], [1, 0], [1, H], [0, H]]

    (15)

    wdomain2:=[0,1/sqrt(2),1+a,a+2];

    wdomain2 := [0, 2^(1/2)/2, 2^(1/2), 2^(1/2)+1]

    (16)

    eq2:=diff(Z2(w),w)=-I*K2/sqrt(w)/sqrt(w-wmid)/sqrt(w-1-a)/sqrt(w-a-2);

    eq2 := diff(Z2(w), w) = -(2*I)*K2/(w^(1/2)*(4*w-2*2^(1/2))^(1/2)*(w-2^(1/2))^(1/2)*(w-2^(1/2)-1)^(1/2))

    (17)

     K2 is found based on the transformation of wmid to [1,0] in Z2 coordinate.

    eq21:=1=int(rhs(eq2),w=0..wmid);

    eq21 := 1 = -2*K2*EllipticK(1/(((2+2^(1/2))^(1/2))))/(2^(1/2)+1)^(1/2)

    (18)

    K2:=solve(eq21,K2);

    K2 := -(1/2)*((2^(1/2)+1)^(1/2)/EllipticK(1/(((2+2^(1/2))^(1/2)))))

    (19)

     The corner 0,1 in the Z coordinate is mapped by integrating eq2 from 0 to 1 in the w coordinate

     

     

    int(rhs(eq2),w=0..1);

    1+EllipticF((2-2^(1/2))^(1/2), ((2^(1/2)+1)/(2+2^(1/2)))^(1/2))*I/EllipticK(1/(((2+2^(1/2))^(1/2))))

    (20)

    corner:=evalf(%);

    corner := 1.+.559419351518322*I

    (21)

     This is the point 1,0 in the original coordinate.

     The height in the Z2 coorinate is found by integrating eq2 from wmid to 1+a.

    ytot:=int(rhs(eq2),w=wmid..1+a);

    ytot := EllipticK(((2^(1/2)+1)/(2+2^(1/2)))^(1/2))*I/EllipticK(1/(((2+2^(1/2))^(1/2))))

    (22)

    evalf(%);

    1.22004159128347*I

    (23)

     The magnitude in the Y direction is given by the coefficient of I, the imaginary number

    Ytot:=coeff(ytot,I);

    Ytot := EllipticK(((2^(1/2)+1)/(2+2^(1/2)))^(1/2))/EllipticK(1/(((2+2^(1/2))^(1/2))))

    (24)

     The analytial solution in the Z2 corordinate is a line in Y2 to satisfy simple zero flux conditions at X2 = 0 and X2 = 1.

    phianal:=1+b*Y2;

    phianal := 1+b*Y2

    (25)

     The value of phi is zero at Y2 = Ytot (originally the cathode domain in the Z domain)

    bc:=subs(Y2=Ytot,phianal)=0;

    bc := 1+b*EllipticK(((2^(1/2)+1)/(2+2^(1/2)))^(1/2))/EllipticK(1/(((2+2^(1/2))^(1/2)))) = 0

    (26)

    b:=solve(bc,b);

    b := -EllipticK(1/(((2+2^(1/2))^(1/2))))/EllipticK(((2^(1/2)+1)/(2+2^(1/2)))^(1/2))

    (27)

     The analytical solution is given by

    phianal;

    1-EllipticK(1/(((2+2^(1/2))^(1/2))))*Y2/EllipticK(((2^(1/2)+1)/(2+2^(1/2)))^(1/2))

    (28)

    evalf(phianal);

    1.-.819644188480505*Y2

    (29)

     The potential at the corner is given by substituting the imaginary value of corner for Y2 in phinanal)

    phicorner:=subs(Y2=Im(corner),phianal);

    phicorner := 1-.559419351518322*EllipticK(1/(((2+2^(1/2))^(1/2))))/EllipticK(((2^(1/2)+1)/(2+2^(1/2)))^(1/2))

    (30)

    evalf(phicorner);

    .541475179604475

    (31)

    local flux/current density calculation, written in terms of w is

    curr:=b*rhs(eq2)/rhs(eq1);

    curr := -(2^(1/2)+1)^(1/2)*2^(1/2)*EllipticK(2^(1/2)/2)*(w-1)^(1/2)/(EllipticK(((2^(1/2)+1)/(2+2^(1/2)))^(1/2))*(4*w-2*2^(1/2))^(1/2))

    (32)

    average flux/current density calculation for the anode

    currave:=int((curr),w=0..wmid)/wmid;

    currave := -(1/2)*((2^(1/2)+1)^(1/2)*(2^(1/2)-1)*EllipticK(2^(1/2)/2)*(2^(3/4)+2^(1/4)+arctanh(2^(3/4)/2))*2^(1/2)/EllipticK(2^(3/4)/2))

    (33)

    Digits:=25:

     The average current density at Y =0, local current density at X = 0,Y=0 and potential at X=1,Y=0 (Corner) can be used to study convergence of FEM and other numerical methods

    evalf(currave),evalf(subs(w=0,curr)),evalf(phicorner);

    -1.656507648777793388522396, -1.161311530233258689567781, .5414751796044734741869534

    (34)

     


     

    Download Conformalmapping.mws


     

    This FEM code is for solving Laplace's equation with primary current distribution considered in Model 1.
    This code is based on FEM weak-form. Biquadratic Lagrange shape functions (9nodes in an element) are used.

    restart;

    with(LinearAlgebra):

    Lx:=1: #length in X

    Ly:=1: #length in Y

    nx:=10: #number of elements in X (even numbers only)

    ny:=10: #number of elements in Y, to be kept same as nx in this version

    hx:=Lx/nx: #element size x

    hy:=Ly/ny: #element size y

    Procedure to perform numerical integration on shape functions to obtain local matrices (can be replaced with analytical integration for this particular problem)
      -Shape functions are also used as weight functions in applying weak formulation. Numerical integration is done using Simpson's rule.
      -Local cartesian coordinates x,y are converted to natural coordinates zeta and eta. This transformation is not required for this simple geomerty but useful in general. zeta and eta are obtained by scaling x and y with hx/2 and hy/2, respectively, in this code.

     

    localmatrices:=proc(a1,a2,a3,b1,b2,b3,q1,q2)
    global Kx,Ky,Nx,Ny,zeta,eta,c;
    local A,dAdzeta,dAdeta,y,x,J,terms,i,j,k,l,dx,dy,fx,fy,fxy,fyy,dzeta,deta,J1,J2;

    A:=[(1-zeta)*zeta*(1-eta)*eta/4,-(1-(zeta)^2)*(1-eta)*eta/2,-(1+zeta)*zeta*(1-eta)*eta/4,(1-(eta)^2)*(1+zeta)*zeta/2,(1+zeta)*zeta*(1+eta)*eta/4,(1-(zeta)^2)*(1+eta)*eta/2,-(1-zeta)*zeta*(1+eta)*eta/4,-(1-(eta)^2)*(1-zeta)*(zeta)/2,(1-(zeta)^2)*(1-(eta)^2)]; #bi quadratic langrange shape functions

    dAdzeta:=diff(A,zeta);

    dAdeta:=diff(A,eta);

    y:=[-a1,-a2,-a3,0,a3,a2,a1,0,0];x:=[-b1,0,b1,b2,b3,0,-b3,-b2,0];

    J:=simplify(add(dAdzeta[i]*x[i],i=1..9)*add(dAdeta[i]*y[i],i=1..9)-add(dAdzeta[i]*y[i],i=1..9)*add(dAdeta[i]*x[i],i=1..9));

    Nx:=[seq((simplify(add(dAdeta[i]*y[i],i=1..9))*dAdzeta[j]-simplify(add(dAdzeta[i]*y[i],i=1..9))*dAdeta[j])/simplify(J),j=1..9)];

    Ny:=[seq((-dAdzeta[j]*simplify(add(dAdeta[i]*x[i],i=1..9))+dAdeta[j]*simplify(add(dAdzeta[i]*x[i],i=1..9)))/simplify(J),j=1..9)];

    Kx:=Matrix(nops(A),nops(A),datatype=float[8]):

    Ky:=Matrix(nops(A),nops(A),datatype=float[8]):
    c:=Vector(nops(A),datatype=float[8]):

    terms:=20:#number of terms for numerical integration
    dzeta:=2/terms:
    deta:=2/terms:

    for i from 1 to nops(Nx) do #loop to obtain local matrices      

    for j from 1 to nops(Ny) do
    Kx[i,j]:=0;
    Ky[i,j]:=0;

    for k from 0 to terms do #outer loop double integration, integration in zeta

    if k = 0 then fx[k]:= subs(zeta=-1,Nx[i]*Nx[j]*J); fy[k]:= subs(zeta=-1,Ny[i]*Ny[j]*J);  
    elif k = terms then
    fx[k]:= subs(zeta=-1+(k*dzeta),Nx[i]*Nx[j]*J);
    fy[k]:= subs(zeta=-1+(k*dzeta),Ny[i]*Ny[j]*J);  
    elif irem(k,2) = 0 then
    fx[k]:= 2*subs(zeta=-1+(k*dzeta),Nx[i]*Nx[j]*J);
    fy[k]:=     2*subs(zeta=-1+(k*dzeta),Ny[i]*Ny[j]*J);
    else fx[k]:= 4*subs(zeta=-1+(k*dzeta),Nx[i]*Nx[j]*J);
    fy[k]:=     4*subs(zeta=-1+(k*dzeta),Ny[i]*Ny[j]*J);  end if;

    for l from 0 to terms do #inner loop double integration, integration in eta

    if l = 0 then fxy[l]:= subs(eta=-1,fx[k]); fyy[l]:= subs(eta=-1,fy[k]);
    elif l = terms then fxy[l]:= subs(eta=-1+(l*deta),fx[k]); fyy[l]:= subs(eta=-1+(l*deta),fy[k]);
    elif irem(l,2) = 0 then fxy[l]:= 2*subs(eta=-1+(l*deta),fx[k]); fyy[l]:= 2*subs(eta=-1+(l*deta),fy[k]);
    else fxy[l]:=4*subs(eta=-1+(l*deta),fx[k]); fyy[l]:=4*subs(eta=-1+(l*deta),fy[k]); end if;
    Kx[i,j]:=Kx[i,j]+fxy[l];
    Ky[i,j]:=Ky[i,j]+fyy[l];

    end do;
        
    end do;
    Kx[i,j]:=Kx[i,j]*dzeta*deta/9;
    Ky[i,j]:=Ky[i,j]*dzeta*deta/9;
    end do;
    end do:

    end proc:

    n:=nx*ny; #total number of elements

    n := 100

    (1)

    Nx1:=nx*2+1: #number of nodes in x in one row

    N:=Nx1*(2*ny+1); # total number of nodes/equations

    N := 441

    (2)

    K:=Matrix(N,N,storage=sparse): # global K matrix

    C:=Vector(N,storage=sparse): # global c matrix

    L2G:=Matrix(n,9):  #mapping matrix - each row has node numbers for each element

    l:=1:k:=1:
    localmatrices(hy/2,hy/2,hy/2,hx/2,hx/2,hx/2,0,0): kx:=copy(Kx):ky:=copy(Ky):c0:=copy(c):

    for i from 1 to n do #modifying,adding and assembling matrices to get global matrix
     
    if i<=nx/2 then  
    a1:=copy(kx); a2:=copy(ky); a3:=0; a1[1..3,1..9]:=IdentityMatrix(3,9); a2[1..3,1..9]:=Matrix(3,9,shape=zero); a4:=a1+a2; c:=copy(c0); c[1..3]:=1.0;

    elif i=nx/2+1 then  a1:=copy(kx); a2:=copy(ky); a3:=0; a1[1,1..9]:=IdentityMatrix(1,9); a2[1,1..9]:=Matrix(1,9,shape=zero); a4:=a1+a2; c:=copy(c0); c[1]:=1.0;

    elif i>nx*(ny-1) then a1:=copy(kx); a2:=copy(ky); a3:=0; a1[5..7,5..7]:=IdentityMatrix(3,3);
    a1[5..7,1..4]:=ZeroMatrix(3,4);
    a1[5..7,8..9]:=ZeroMatrix(3,2); a2[5..7,1..9]:=Matrix(3,9,shape=zero); a4:=a1+a2; c:=copy(c0); c[5..7]:=0;

    else a1:=kx; a2:=ky; a3:=0;a4:=a1+a2; c:=c0;  end if;

    L2G[i,1..9]:=Matrix([l,l+1,l+2,l+2+Nx1,l+2+Nx1*2,l+1+Nx1*2,l+Nx1*2,l+Nx1,l+1+Nx1]):

    k:=k+1:
     
    if k>nx then k:=1; l:=l+Nx1+3;

    else l:=l+2; end if:

    indx2:=L2G[i,1..9]:
    indx2:=convert(indx2,list):

    C[indx2]:=C[indx2]+c[1..9];
    c[1..9];

    for i1 from 1 to 9 do
    indx1:=L2G[i,i1]:
    K[indx1,indx2]:=K[indx1,indx2]+a4[i1,1..9]:
    end do:

    end do:

    phi:=LinearSolve(K,C,method=SparseLU): #linear set of equations solved using Sparse LU solver

    phi_at(1,0):=phi[Nx1];
     

    phi_at(1, 0) := .546587799122513

    (3)

    dNdy:=copy(Ny):

    dNdy_bottom_left:=subs(eta=-1,zeta=-1,dNdy):

    current_at(0,0):=add(dNdy_bottom_left[i]*phi[L2G[1,i]],i=1..nops(Ny));

    current_at(0, 0) := -1.15773815354626

    (4)

    if irem(nx/2,2)=0
    then current_at(0,0.25):=add(dNdy_bottom_left[i]*phi[L2G[nx/4+1,i]],i=1..nops(Ny));
    else
    dNdy_bottom_center:=subs(eta=-1,zeta=0,dNdy):
    current_at(0,0.25):=add(dNdy_bottom_center[i]*phi[L2G[(nx/2+1)/2,i]],i=1..nops(Ny));
    end if;

    dNdy_bottom_center := [0, -30, 0, 0, 0, -10, 0, 0, 40]

    current_at(0, .25) := -1.26989097821724

    (5)

     

     


     

    Download FEM_2D.mws

    DataFrames: An example from the 2020 U.S. Presidential election

    (Or why DataFrames are more powerful and readable than spreadsheets.)

     

    In this example of working with DataFrames, the goal is to use a spreadsheet from a website, which contains polling data, to estimate the probability each of the two candidates from the major parties will win the US Presidential election in November.  I first tried doing the calculations with a spreadsheet, but I discovered DataFrames was far more powerful. Warning: This worksheet uses live data. Hence the outcome at the end of the worksheet is likely to change daily. A more extensive example with even more common DataFrame operations should be available soon.

     

    How the US Presidential election works - highly simplified version: In the US there are only two parties for which their candidate could win the election:  the Democratic party and Republican party. The Republican party is often referred to as the "Grand Old Party", or GOP. Each state executes its own election. The candidate who receives the most votes wins the states "electoral votes" (EV). The number of the electoral votes for each state is essentially proportional to the population of the state. A candidate who receives a total of 270 or more EVs out of 538, is declared the president of the US for the next term, which starts January 20 of 2021.

     

    Creating DataFrame from web based data:

    First I download the data from the website. It is a CSV spreadsheet.

     

    restart; interface(displayprecision = 3); interface(rtablesize = [6, 8]); web_data := Import("https://www.electoral-vote.com/evp2020/Pres/pres_polls.csv")

    _m2211970420352

    Each row contains information about a poll conducted in one of the states.  The first poll starts on row 2, hence the number of polls are:

    Npolls := upperbound(web_data, 1)-1

    572

    Now I want to create a new DataFrame containing only the most useful information. In web_data, many are the columns are not important. However I do want to keep the column label names from those columns I wish to retain.

     

    web_data_cols := [1, 3, 4, 5, 6]; column_labels := convert(web_data[1, web_data_cols], list)

    ["Day", "State", "EV", "Dem", "GOP"]

     

    Because  the first poll in web_data is labeled 2, I would like to relabel all the polls starting from 1

    row_labels := [seq(1 .. Npolls)]

     

    Creating a DataFrame from a Matrix or another DataFrame:  (with row labels and column labels)

     

    Now I can build the DataFrame that I will be working with:

     

    poll_data := DataFrame(web_data[2 .. (), web_data_cols], 'columns' = column_labels, 'rows' = row_labels)

    _m2211956910784

    What each column means

    * "Day" - day of the year in 2020 when the poll within the state was halfway completed. The larger the value, the more recent the poll.

    * "State" - the state in the US where the poll was conducted. The candidate that receives the most votes "wins the state".

    * "EV" - the number of electoral votes given to the candidate who receives the most votes within the state.

    * "Dem" - the percentage of people who said they are going to vote for the candidate from the Democratic party.

    * "GOP" - the percentage of people who said they are going to vote for the candidate from the Republican party.

    Sorting:

    By using the sort function, using the `>` operator, I can see which polls are the more recent. (If you run the worksheet yourself, the outcome will change as more polls are added to the website spreadsheet.)

    poll_data := sort(poll_data, "Day", `>`)

    _m2211960016288

     

    Selecting Unique entries - by column values:

    For the my simple analysis, I will use only the most recent poll, one from each state. Hence, using AreUnique, I can pull the first row that matches a state name. This new DataFrame called states.

     

    states := poll_data[AreUnique(poll_data["State"])]

    _m2211969565344

    (Note, one of the "states" is the District of Columbia, D.C., which is why there are 51 rows.)

     

    Removing a column: (and relabeling rows)

    This next example isn't necessary, but shows some of the cool features of DataFrames.

     

    Since there is only 1 entry per state, I'm going to remove the "State" column and relabel all the rows with the state names

    state_names := convert(states["State"], list); states := DataFrame(Remove(states, "State"), 'rows' = state_names)

    2

    _m2211957755840

     

    Indexing by row labels:


    This allow me to to display information by individual states. What is the data for California, Maine and Alaska?

    states[["California", "Maine", "Alaska"], () .. ()]

    _m2211977321984

     

    Mathematics with multiple-columns:

     

    My preference is to work with fractions, rather than percentages. Hence I want all the values in the "Dem" and "GOP" to be divided by 100 (or multiplied by 1/100).  Treating each column like a vector, the multiplication is performed individually on each cell. This is what the tilda, "~", symbol performs.

    states[["Dem", "GOP"]] := `~`[`*`](states[["Dem", "GOP"]], 1/100.); states

    _m2211957755840

     

    Mathematics: using a function to calculate a column

     

    For the next action, I want to use the power of the Statistics package to create a "probability of winning the state" function.

     

    For simplicity, I will assume the outcome of the voting in a state is purely random, but is conditional to popularity of each candidate as measured by the polls. I'll assume the likelihood of an outcome follows a normal (Gaussian) distribution with the peak being at point where the difference of the polling of the two candidates is zero. (Note, other than 2016, where there was an unusually larger percentage of undecided voters on election day, this simple model is reasonable accurate. For example, in 2012, of the states which appeared to be the "closest", the winner over-performed his polling in half of them, and under-performed in the other half with a mean difference of nearly zero.)  From previous elections, the standard deviation of differences between polling values and the actual outcome is at most 0.05, however, it does increase with the fraction of undecided voters.

     

    To mathematically model this situation, I have chosen to use the "Cumulative Density Function" CDF in the Statistics package. It will calculate the probability that a candidate polling with fraction f1 wins the election if the other candidate is polling with fraction f2.  The variable u is the fraction of undecided voters. It is included in the calculation to increase the spread of the possible outcomes.

     

    win_prob := Statistics:-CDF(Statistics:-RandomVariable(Normal(0., 0.5e-1+(1/4)*u)), f1-f2)

    1/2+(1/2)*erf((1/2)*(f1-f2)*2^(1/2)/(0.5e-1+(1/4)*u))

     

    Converting this expression into a function using the worst named function in Maple, unapply:

    win_prob_f := unapply(evalf(win_prob), [f1, f2, u])

    proc (f1, f2, u) options operator, arrow; .5000000000+.5000000000*erf(.7071067810*(f1-1.*f2)/(0.5e-1+.2500000000*u)) end proc

     

    Now I can calculate a DataFrames column of the "win probability", in this case, for the candidate from the Democratic platy. By apply the function, individually, using the columns "Dem" and "GOP", I produce:

    dem_win_prob := `~`[win_prob_f](states["Dem"], states["GOP"], `~`[`-`](1, `~`[`+`](states["Dem"], states["GOP"])))

    _m2212010910496

    Appending a column:

     

    I can add this column to the end of the states with the label "DemWinProb":

     

    states := Append(states, dem_win_prob, label = "DemWinProb")

    _m2212009017568

     

    Mathematics of adding the entries of a column:

     

    How many electoral votes are available? add them up.

    Total_EV := add(states["EV"])

    538

     

    While the number of EV a candidate wins is discrete, I can use the "win probability" from each state to estimate the total number of EV each of the candidates might win. This means adding up number of EV in each state times, individually, the probability of winning that state:

    Dem_EV := round(add(`~`[`*`](states["EV"], states["DemWinProb"])))

    354

    Currently, the candidate from the Democratic party is likely to win more then 300 electoral vtes.

     

    What about for the candidate from the Republican / "GOP" party?

    gop_win_prob := `~`[win_prob_f](states["GOP"], states["Dem"], `~`[`-`](1, `~`[`+`](states["Dem"], states["GOP"]))); GOP_EV := round(add(`~`[`*`](states["EV"], gop_win_prob)))

    184

    Summing the two EV values, we obtain the total number of electoral votes.

    Dem_EV+GOP_EV

    538

      NULL

     

    Download DataFrames_Example.mw

    First 22 23 24 25 26 27 28 Last Page 24 of 297