Applications, Examples and Libraries

Share your work here

Recently I came back on the general problem of drawing the syntactic graph of a mathematical expression.
Probably some of you have already done this as students for it is a classic when you learn recursive procedures, chained lists or graphs.

I wasn't interested in doing this with Maple, because Maple had already done  a part of the job thanks to the procedure ToInert.
More of this, the package GraphTheory seemed to possess all the required features to obtain quickly this syntactic graph.
Nevertheless it took me a lot of time to fix (almost all) the problems.
The issues are mainly of two orders:

  1. ToInert is very verbose: a necessary feature when you want to have a non ambiguous syntax of an expression, but partly useless for simple visualization.
    Here is an example
    ToInert(f(x))
    _Inert_FUNCTION(_Inert_NAME("f"), _Inert_EXPSEQ(_Inert_NAME("x")))

     

  2. GraphTheory 
    Once the inert form of the expression is known, it is necessary to put it in a form that can be manipulated by the procedures of the GraphTheory package.
    More precisely one needs to transform this inert form into a set of lists [a, b], where a and b are two neighboring vertices of the syntactic graph and [a, b] the directed arc from a to b.
    As the syntactic graph is a tree, this implies using edges {a, b} instead of arcs [a, b].
    The problem is that some operators are commutative while others are not: for the latter this means that the edges and vertices on the syntactic graph must appear in an order that respects the non-commutativity.
    Here his a toy example where I manually buid the syntactic graphs of a/b and b/a: the two graphs are identical and this comes from the fact that edges in Graph( edges )  must be a set, thus an ordered structure whose order doesn't care about non-commutativity.

    restart:
    with(GraphTheory):
    # The first is aimed to represent the expression a/b
    # while the second is aimed to represent the expression b/a
    Gdiv := Graph({{"/", "a"}, {"/", "b"}}):
    g1 := DrawGraph(Gdiv, style=tree, root="/", title=a/b):
    
    Gdiv := Graph({{"/", "b"}, {"/", "a"}}):
    g2 :=DrawGraph(Gdiv, style=tree, root="/", title=b/a):
    
    plots:-display(<g1 | g2>)
    

    Download ab_ba.mw

     

After several attempts, I decided to discard the GraphTheory package, that is to deprive myself of all the interesting features one needs to manipulate a graph.

The result is given on the attached file (... and the content of the worksheet can't be loaded as usual).

Download Syntactic_Graph.mw

Here is an example


Twelve test cases are given, all the corresponding syntactic graphs are correct, but one of them (test case iexpr=1) seems incorrect because the right child of a parent P is located to the right of the left child of a parent P', even though P' is to the right of P.
This could be corrected by modifying the way the posiitons are computed in procedure Place.


PS : It doesn't seem that Maple has a built-in procedure to construct the syntactic graph of a mathematical expression.
But maybe I'm wrong?


 

 

In the two examples below (in the second example, the range for the roots is simply expanded), we see bugs in both examples (Maple 2018.2). I wonder if these errors are fixed in Maple 2020?
 

restart;

solve({log[1/3](2*sin(x)^2-3*cos(2*x)+6)=-2,x>=-7*Pi/2,x<=-2*Pi}, explicit, allsolutions); # Example 1 - strange error message
solve({log[1/3](2*sin(x)^2-3*cos(2*x)+6)=-2,x>=-4*Pi,x<=-2*Pi}, explicit, allsolutions);  # Example 2 - two roots missing

Error, (in assume) contradictory assumptions

 

{x = -(11/3)*Pi}, {x = -(10/3)*Pi}

(1)

plot(log[1/3](2*sin(x)^2-3*cos(2*x)+6)+2, x=-7*Pi/2..-2*Pi);
plot(log[1/3](2*sin(x)^2-3*cos(2*x)+6)+2, x=-4*Pi..-2*Pi);

 

 

Student:-Calculus1:-Roots(log[1/3](2*sin(x)^2-3*cos(2*x)+6)=-2, x=-7*Pi/2..-2*Pi);  # OK
Student:-Calculus1:-Roots(log[1/3](2*sin(x)^2-3*cos(2*x)+6)=-2, x=-4*Pi..-2*Pi);  # OK

[-(10/3)*Pi, -(8/3)*Pi, -(7/3)*Pi]

 

[-(11/3)*Pi, -(10/3)*Pi, -(8/3)*Pi, -(7/3)*Pi]

(2)

 


I am glad that  Student:-Calculus1:-Roots  command successfully handles both examples.

 

Download bugs-in-solve.mw

Spectroscopy is both qualitative and quantitative, so one can use spectral data tables of elements to do some fairly accurate Light Engineering.

Some nifty emulation of the spectral distributions of many non-LED popular lamps, which allows for direct utility calculations based on many different parameters including chromaticity, space type, lifetime, occasion, application, cost and efficiency. 7 such parameters are used with constrained weight optimization to fish out some of the more popular lamp types used in many situations today.

References (inline) the following docs:

The Science of Color, the Emission Spectra of the Elements and Some Lamp Engineering Applications

and

The Double Amici Prism Hand-held Spectroscope

First link main Theory, second link experimental verification.

Usage: Maple 18 main document code with library and data files. Download, unzip and run document for some quick results. Don't move library/data files relative to main doc. For further results and particular details, such as particular spectra & lamps, UN-comment the relevant commands in sections and execute individually after you have executed the entire sheet at least once.

Will be modified some time later to deal with LEDs. Based on elemental spectral data published by NIST. Suggestions 4 Improvements/Errors @ followup, here.

Elements.zip

For sample pics generated with the above code, click on the first reference link. All pictures therein were generated using this code.

--

Cheers,

Yiannis

A customer wondered if it was possible to create 2-line tickmarks on Maple plots like so

 

 

We achieved this using typeset, fractions, and backticks. Worksheet follows.

2line-tickmarks-mprimes.mw

 

Hi,
This post is inspired by a recent question maple least square fit error... where the OP was simulating what appeared to be a stochastic process known as the Drunkard's walk (see for instance The_Drunkard's_Walk).


In the case of the PO, the drunk took a step forward or a step backward (say along a narrow, long corridor) with equal probabilities. In addition one assumes that the step the drunkhard takes is independent of all the steps he did before.
His move is what is called a (1D) Random_walk

This little application based on MAPLETS (ok, I know that some people see them as old-fashioned technology).

It draws a sequence of several drunkard's walks, all of identical number of steps, and interactively plots the current histogram of the arrival point (the point where he is at the end of his walk -which should be the door if the same pub he started from if he is an inveterate drunkhard or if he knows a little about statistics- ).

The code contains 2 procedures :

  • f_step_by_step (n, Discrete=false/true) 
    n : number of steps
    Discrete = false (default value) plot the histogram of the arrivals point as if these points were realizarions of a continuous random variable
    In this simple model these arrivals can take only integer values between -n and +n included; the Discrete=true option is recommended but it takes more walks for it to converge to the asymptotic distribution (see below).

    Once launched, f_step_by_step opens a maplet containing a Plotter and 2 buttons. A first walk is displayed, clic the "Plot" button to draw another and repeat the operation as many times as you want.
     
  • f_automatic (n, m, Discrete=false/true) 
    d and Discrete both have the same meaning than for f_step_by_step.
    m is the number of random walk you want to draw
    The code is set to draw 1000 walks of 1000 steps ; this correspong roughly to 250 Mb of memory used.

    f_automatic contains a call to Threads:-Sleep to delay the display, the argument of Sleep is set to 0.25 second and must be modified within the procedure (its value could be passed to f_automatic as an argument).

    In my opinion it is the more interesting of the two procedures.
     

The values of the current mean and standard deviation are displayed as title.

The purpose is before all educative and can be seen as an illustration of the (one of) Central Limit Theorem(s) (CLT)

A little bit of theory:
Let X[n] the position of the drunkhard after n steps; his position X[n+1] is either X[n]-1 or X[n]+1 with equal probabilities.
The displacement X[n+1]-X[n] is a discrete random variable S with outcomes -1 and +1 and it's easy to find its variance is equal to 1.
The position of the trunkard after n steps is just a realization of the n independant and identically distributed, random variables S1, ...Sn whose distribibution is equal to the one of S.
Thus :

  • Expectation (S1 + ... +Sn)  = 0 
  • Variance (S1 + ... +Sn)  = n 
    For n=1000 steps, the standard deviation of the arrivals is about 31.6)

CLT says that the distribution of S1 + ... +Sn  tends to a Gaussian distribution as n tends to infinity.

What is the exact distribution of the arrivals?
Another way to represent S is to write S = 2*B-1 where B is a Bernoulli random variable with parameter 1/2. The random variable "Arrival" is  twice the sum of N indpendent rabdom variables such like S 
and thus its distribution is 2*Binomial(N, 1/2)-N.

What is the rate of convergence of the histogram to the true probability function?
For a sample of size N drawn from a continuous random variables, its histogram has:

  • a bias error of order 1/K (K being the number of bins)
  • a Linfinity error of order  K*sqrt( log(K) / M )  (M number of drunkhard's walks)
    see for instance Lec2_density.pdf

Using the option Discrete=true corresponds to the choice K=2*N+1, in this case the choice with the highest Linfinity error (the larger K the smaller the bias but the larger the  Linfinity error).
This is the reason I introduced the possibility to graw histograms and bar (column) graphs: for the same value of M the Linfinity error of the histogram (for instance with the default number of bins Maple uses) is nuch slower than the one of the comumn graph.



A few "internal" parameters.
I already spoke about the delay to display txo succesive walks.
Other parameters could be:

  • The value of minbins in the case discrete=false (default)
    This value is fixed to 2*sqrt(M).
     
  • The width in the "view" option of the plot: it's left part displays the drunkhard's walk and it's right one the histogram of the arrivals (after a rotation of -Pi/2). 
    This value si fixed to 5/4*M.
    Note that the histogram is dynamically rescaled in order it's height is always 1/4*number_of_steps.
     
  • The height of the view option is set to -Q..Q where Q is equal to 4 standard deviations of the theoritical distribution of the arrivals.
    The continuous envelope of this distribution is red plotted in red (its height is normalized to M/4, see above). 
    One can show this standard deviation iverifies sqrt(M).
    In my opinion using a full vertical scale (-M..M) doesn't give pretty drunkward's walkes because they seem to more concentrated around the value 0.
     



WATCHOUT
Starting from 0 any walk with an odd number of steps will give an odd arrival and any walk with an even number of steps will give an even arrival. Thus the exact number of outcomes for the arrivals are:

  • 2*n if n is odd
  • 2*n-1 if n is even
     


Other application
This maplet can be used as illustration of the Galton Board (also known as the Bean_machine)


Why using maplets?
Another solution could have been to use animate. But to draw the M drunkard's walks, you would have had to use M frames. An excessive task that I'm not even sure Maple would have been able to handle.
I guess that imbeded components could do the job too, but I'm not as comfortable with them as I am with maplets.

To illustrate what the code does an image of the final result is given below.

Drunkard_walk.mw


One forum had a topic related to such a platform. ( Edited: the video is no longer available.)

The manufacturer calls the three-degrees platform, that is, having three degrees of freedom. Three cranks rotate, and the platform is connected to them by connecting rods through ball joints. The movable beam (rocker arm) has torsion springs.  I counted 4 degrees of freedom, because when all three cranks are locked, the platform remains mobile, which is camouflaged by the springs of the rocker arm. Actually, the topic on the forum arose due to problems with the work of this platform. Neither the designers nor those who operate the platform take into account this additional fourth, so-called parasitic degree of freedom. Obviously, if we will to move the rocker with the locked  cranks , the platform will move.
Based on this parasitic movement and a similar platform design, a very simple device is proposed that has one degree of freedom and is, in fact, a spatial linkage mechanism. We remove 3 cranks, keep the connecting rods, convert the rocker arm into a crank and get such movements that will not be worse (will not yield) to the movements of the platform with 6 degrees of freedom. And by changing the length of the crank, the plane of its rotation, etc., we can create simple structures with the required design trajectories of movement and one degree of freedom.
Two examples (two pictures for each example). The crank rotates in the vertical plane (side view and top view)
PLAT_1.mw


and the crank rotates in the horizontal plane (side view and top view).

The program consists of three parts. 1 choice of starting position, 2 calculation of the trajectory, 3 design of the picture.  Similar to the programm  in this topic.

 

 

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

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

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

First 16 17 18 19 20 21 22 Last Page 18 of 76