Product Tips & Techniques

Tips and Tricks on how to get the most about Maple and MapleSim

The Maple command line interface (cmaple), often referred to as the "TTY interface" for its original use on Teletype terminals, is still the tool of choice for many Maple developers and power users. Maple 2018.1 introduces several new capabilities to this long-lived interface:

This post, the first in a series of three, will address color syntax highlighting. We'll start with a very short sample session:

    |\^/|     Maple 2018.1 (X86 64 LINUX)
._|\|   |/|_. Copyright (c) Maplesoft, a division of Waterloo Maple Inc. 2018
 \  MAPLE  /  All rights reserved. Maple is a trademark of
 <____ ____>  Waterloo Maple Inc.
      |       Type ? for help.
> piecewise(4 < x^2 and x < 8, f(x));
                            {                  2
                            { f(x)        4 < x  and x < 8
                            {
                            {  0             otherwise

> p := unapply(%,x);
                                               2
                      p := x -> piecewise(4 < x  and x < 8, f(x))

> 1/p(1);
Error, numeric exception: division by zero
> quit
memory used=5.3MB, alloc=41.3MB, time=0.07

In the above example, you can see that general keywords are in bold blue, variables in italics (not supported by all terminals), error messages in bold red, control flow interrupting keywords in bold magenta, and memory usage messages in normal blue.

Color syntax highlighting is turned on by default in cmaple for Linux and OS/X if the terminal you are using (as specified by the TERM environment variable) is known to support it. It is currently turned off by default under Windows. It can be explicitly turned on or off for 2D and message output using interface(ansi=) where is true or false (under Windows, you can put interface(ansi=true) in your maple.ini file to automatically turn it on). Likewise, interface(ansilprint=) controls highlighting for 1D output (such as that produced by lprint), and interface(ansiedit=) for input.

Not all terminals support all possible highlighting modes. The following two commands show what colors your terminal can display, and how they are used by Maple's syntax highlighting:

> interface(showtermcolors):

ANSI X3.64 Standard Attributes

Normal  Bold  Italic  Underlined  Reverse  

System Colors (0-15) Using ANSI Escape Sequences

Color00  Color01  Color02  Color03  Color04  Color05  Color06  Color07  
Color08  Color09  Color10  Color11  Color12  Color13  Color14  Color15  

System Colors (0-15) Using Extended Escape Sequences

  0    0    1    1    2    2    3    3    4    4    5    5    6    6    7    7  
  8    8    9    9   10   10   11   11   12   12   13   13   14   14   15   15  

Extended 6x6x6 Color Cube (16-231)

 16   16   17   17   18   18   19   19   20   20   21   21  
 22   22   23   23   24   24   25   25   26   26   27   27  
 28   28   29   29   30   30   31   31   32   32   33   33  
 34   34   35   35   36   36   37   37   38   38   39   39  
 40   40   41   41   42   42   43   43   44   44   45   45  
 46   46   47   47   48   48   49   49   50   50   51   51  

 52   52   53   53   54   54   55   55   56   56   57   57  
 58   58   59   59   60   60   61   61   62   62   63   63  
 64   64   65   65   66   66   67   67   68   68   69   69  
 70   70   71   71   72   72   73   73   74   74   75   75  
 76   76   77   77   78   78   79   79   80   80   81   81  
 82   82   83   83   84   84   85   85   86   86   87   87  

 88   88   89   89   90   90   91   91   92   92   93   93  
 94   94   95   95   96   96   97   97   98   98   99   99  
100  100  101  101  102  102  103  103  104  104  105  105  
106  106  107  107  108  108  109  109  110  110  111  111  
112  112  113  113  114  114  115  115  116  116  117  117  
118  118  119  119  120  120  121  121  122  122  123  123  

124  124  125  125  126  126  127  127  128  128  129  129  
130  130  131  131  132  132  133  133  134  134  135  135  
136  136  137  137  138  138  139  139  140  140  141  141  
142  142  143  143  144  144  145  145  146  146  147  147  
148  148  149  149  150  150  151  151  152  152  153  153  
154  154  155  155  156  156  157  157  158  158  159  159  

160  160  161  161  162  162  163  163  164  164  165  165  
166  166  167  167  168  168  169  169  170  170  171  171  
172  172  173  173  174  174  175  175  176  176  177  177  
178  178  179  179  180  180  181  181  182  182  183  183  
184  184  185  185  186  186  187  187  188  188  189  189  
190  190  191  191  192  192  193  193  194  194  195  195  

196  196  197  197  198  198  199  199  200  200  201  201  
202  202  203  203  204  204  205  205  206  206  207  207  
208  208  209  209  210  210  211  211  212  212  213  213  
214  214  215  215  216  216  217  217  218  218  219  219  
220  220  221  221  222  222  223  223  224  224  225  225  
226  226  227  227  228  228  229  229  230  230  231  231  

Extended 24-Level Grayscale (232-255)

232  232  233  233  234  234  235  235  236  236  237  237  238  238  239  239  
240  240  241  241  242  242  243  243  244  244  245  245  246  246  247  247  
248  248  249  249  250  250  251  251  252  252  253  253  254  254  255  255  

If your terminal does not support 256 color mode, then many of the colored blocks shown above will appear differently or not at all.

> interface(showcolors):

 1 Normal output:           evalf(1/2) = 0.5
 2 Italics (variables):     x, y, z
 3 Symbol text (not used):  symbol
 4 Bold (fallback):         Begin, be bold, and venture to be wise.
 5 Underlined (fallback):   Morality, like art, means drawing a line someplace.
 6 Reversed (not used):      The reverse side also has a reverse side. 
 7 Input prompts:           >  DBG>
 8 User input:              1/(x^4+1);
 9 Userinfo output:         message, x, y
10 Trace output:            {--> enter f, args = x, y
11 Warning messages:        Warning, x is implicitly declared local
12 Error messages:          Error, (in f) invalid subscript selector
13 Debugger output:         No breakpoints set
14 General Maple keywords:  for  from  to  while  do  until
15 Declaration keywords:    local  option  description
16 Flow interruptions:      break  return
17 Exception keywords:      error  try  catch
18 Subexpression labels:    %1  %2
19 Special & quoted names:  thisproc  `diff/sin`
20 String literals:         "Hello, world!"
21 Maple startup message:   Maple 2019
22 Output from printf:      x=1.234 y=5.678
23 Status messages:         memory used=1.7MB, alloc=8.3MB, time=0.03
24 System command output:   1466  4739  43140  myprog.mpl
25 Maple comments:          # Comments are free but facts are sacred.

The colors used for the different categories of output as listed by the command above are user selectable. The default is to use only the sixteen ANSI X3.64 standard colors (or Windows command prompt standard colors). These may appear differently than shown here depending on the color palette of your terminal window.

The color settings can be queried or set as follows:

> currentColors := interface(ansicolor);
currentColors := [-1, -1, -1, -1, -1, -1, 2, -1, 2, 3, 11, 9, 6, 12, 10, 13, 9, 14, 6,

    5, 2, 136, 4, 134, 3]

# Individual colours, as numbered in the output of interface(showcolors), can
# be changed. Let's make keywords bright yellow:
> myColors := subsop(14=226,currentColors);
myColors := [-1, -1, -1, -1, -1, -1, 2, -1, 2, 3, 11, 9, 6, 226, 10, 13, 9, 14, 6, 5,

    2, 136, 4, 134, 3]

> interface(ansicolor=myColors);
[-1, -1, -1, -1, -1, -1, 2, -1, 2, 3, 11, 9, 6, 12, 10, 13, 9, 14, 6, 5, 2, 136, 4,

    134, 3]

> piecewise(4 < x^2 and x < 8, f(x));
                            {                  2
                            { f(x)        4 < x  and x < 8
                            {
                            {  0             otherwise

There are several predefined color schemes that can be selected using interface(ansicolor=), where is an integer from 0 to 6. Scheme 0, the default, should work on any terminal. Of the remaining schemes, the odd numbered ones are designed to look good on light backgrounds, and the even numbered ones on dark backgrounds.

There is also a new character plot driver, selectable using interface(plotdevice=colorchar), which supports character plotting in color. Colors are mapped to the nearest color supported by the terminal:

> interface(plotdevice=colorchar):
> p1 := plot(sin(x),x=-Pi..Pi,thickness=1,color="DeepPink"):
> p2 := plot(sin(x)+sin(3*x)/3,x=-Pi..Pi,thickness=2,color="LawnGreen"):
> p3 := plot(sin(x)+sin(5*x)/5,x=-Pi..Pi,thickness=3,color="DodgerBlue"):
> plots[display](p1,p2,p3);

                                                                                       
                                           |                                           
                                           |                  @@@@@                    
                                           |                 @@   @@                   
                                           |                 @     @                   
                                         1 |                *.......*                  
                                           |       *******.*@       @*..******         
                                           |      **    .**@         @**.    **        
                                           |     **   ..  ***       ***  ..   **       
                                           |    **   ..  @@ **** **** @@  ..   **      
                                           |    *   ..  @@     ***     @@  ..   *      
                                           |   *@@@**@@@                 @@@**@@@*     
                                       0.5 |  **@ ..                         .. @**    
                                           |  *@ ..                           .. @*    
                                           | ** .                               . **   
                                           | * .                                 . *   
                                           |**..                                 ..**  
                                           |*..                                   ..*  
                                           |*.                                     .*  
                                           *.                                       .* 
 **---------------------------------------**-----------------------------------------* 
  -3           -2            -1          0*|            1             2            3   
  *..                                   ..*|                                           
  **..                                 ..**|                                           
   * .                                 . * |                                           
   ** ..                              . ** |                                           
    *@ ..                           .. @*  |                                           
    **@ ..                         .. -0.5 |                                           
     *@@@**@@@                 @@@**@@@*   |                                           
      *   ..  @@     ***     @@  ..   *    |                                           
      **   ..  @@ **** **** @@  ..   **    |                                           
       **   ..  @**       **@  ..   **     |                                           
        **    .**@         @**.    **      |                                           
         *******.*@       @*.*******       |                                           
                  *.......*             -1 |                                           
                   @     @                 |                                           
                   @@   @@                 |                                           
                    @@@@@                  |                                           
                                           |                                           
                                                                                       

> plot3d([1,x,y],x=0..2*Pi,y=0..2*Pi,coords=toroidal(10));

                                                                                       
                                  -------------------                                  
                             --------\\\-|-|-|-///--------                             
                          ---------\\\-\-|-|-|-/-///---------                          
                        ----------\\\-\-||-|-||-/-///----------                        
                      /-/-/-/-----\\\\\-|||||-|-/////------------                      
                     -//-/-/-/---\-\\-\||-|||-||/-//-/---\-\-\-\--                     
                   --//-|||-/-/--\\\\\\|||||||-|//////--\-\-|||\|\-\                   
                  /---||-||||-|--\\-\\\|||||||||///-//--|-||||--|---\                  
                 /--|--\-\-\-\\--\\/\\|||||||||||//-//-|-///-/-/--|--\                 
                //-//--\\-\-----\-\\\\|||||||||||////-///////-//--\\-\\                
                |//\/\------------\\\|||||||||||||////-------//--/\\\\|                
               /// / / -- /--- -----\|||||||||||||/---------\ --/\ \\\\\               
               //\/ /-//-/-//-//-/--/-/--/-|-\--\-\--\-\\-\\-\-\\/\ \/\\               
               ///\/ /--/ //-// /--/--/-|--|--|-\--\--\ \\-\\ \--\ \/\\\               
               /||/-// /--/  /--/-//-|  |  |  |  |-\\-\--\  \\-\ \\/\||\               
               || |-/ /  /--/  /  | -|--|--|--|--|- |  \ -\--\  \ \/| |||              
              |||| | -/ /  ||--/-||- |  |  |  |  | -||--\  | \\-\- | |/|               
               |||-| | -/--|  |  |  -|--|--|--|---|  |  |  |--\  | |/|||               
               |\| |-|  | ||--|- |  |   |  |  |   |  | -|--|| |  |-- |/|               
               |\||  |-|  |  |  -|--|---|--|---|--|--|-  |  |  |-|  ||/|               
               \|-| |  |--|- |   |  |  |   |   |  |  |   | -|--| |  |/|/               
                \||-|- |  |--|--|-  |  |   |   |  |  -|--|--|  | -|-||/                
                \|-|||-|- |  |  | --|--|---|---|--|-- |  |  |  |-|||/|/                
                 \\|-| |--|--|  |   |  |   |   |  |   |  |--|--| |-|//                 
                  \\ |-|  |  |--|---|  |   |   |  |---|--|  |  |-| //                  
                   -\| |--|  |  |   |--|---|---|--|   |  |  |--| |//                   
                     \|-| |--|--|   |  |   |   |  |   |--|--| |-|/                     
                      \\|\|| |  |---|--|---|---|--|---|  | ||-|//                      
                        -\----|--|  |  |   |   |  |  |--|----/-                        
                          --\-\\ |--|--||--|---|--|--|  /-/--                          
                             ----\\-||--|--|--|---|--///--                             
                                  \--\--|--|--|--/--/                                  
                                                                                       

For more details, please refer to the help page, ?ansicolor.

Hi MaplePrimes Users!

It’s your friendly, neighborhood tech support team; here to share some tips and tricks from issues we help users with on a daily basis.

A customer contacted us through a Help Page feedback form, asking how to add a row or column in a Matrix. The form came from the Row Operations help page, but the wording of the message suggested that the customer actually wanted to insert a new row or column altogether. Such manipulations can often be accomplished by a command in the ArrayTools package, but the only Insert command currently available is the one for Vectors and 1-D Arrays. Using the Concatenate command from that package, and various commands from the LinearAlgebra package (including the SubMatrix command), we were able to write two custom procedures to perform these manipulations:

InsertRow := proc (A::rtable, n::integer, v::Vector[row])
    local R, C, top, bottom;
    uses LinearAlgebra;
    R := RowDimension(A); C := ColumnDimension(A);
    top := SubMatrix(A, [1 .. n-1], [1 .. C]);
    bottom := SubMatrix(A, [n .. R], [1 .. C]);
    return ArrayTools:-Concatenate(1, top, v, bottom);
end proc:

InsertColumn := proc (A::rtable, n::integer, v::Vector[column])
    local R, C, left, right;
    uses LinearAlgebra;
    R := RowDimension(A); C := ColumnDimension(A);
    left := SubMatrix(A, [1 .. R], [1 .. n-1]);
    right := SubMatrix(A, [1 .. R], [n .. C]);
    return ArrayTools:-Concatenate(2, left, v, right)
end proc:

# test cases:

M := Matrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]]):
v := Vector[row]([2, 2, 2]):
v2 := Vector[column]([2, 2, 2]):
seq(InsertRow(M, i, v), i = 1 .. 4);
seq(InsertColumn(M, i, v2), i = 1 .. 4);

We then reworked this problem using some handy indexing and construction notation that allows our previous procedures to save on the variable constructions and syntax:

InsertRow := proc( A :: rtable, V :: Vector[row], r :: posint )
    return < A[1..r-1,..]; V; A[r..-1,..] >:
end proc:

InsertColumn := proc( A :: rtable, V :: Vector[column], c :: posint )
    return < A[..,1..c-1] | V | A[..,c..-1] >:
end proc:

M := Matrix(3, 3, [seq(i, i = 1 .. 9)]);
A := convert(M, Array);
U := Vector[row]( [ a, b, c ] );
V := convert( U, 'Vector[column]' );
seq(InsertRow( A, U, i ), i=1..4);
seq(InsertColumn( A, V, i ), i=1..4);
seq(InsertRow( M, U, i ), i=1..4);
seq(InsertColumn( M, V, i ), i=1..4);

We have released an update to Maple, Maple 2018.1. This release provides enhancements to the mathematical computation engine, including physics and DEs.  It also provides substantial improvements to the command line version, easier access to group management tools in the MapleCloud, and a few other interface improvements.

This update is available through Tools>Check for Updates in Maple, and is also available from our website on the Maple 2018.1 download page, where you can also find more details.

There is a bug in inttrans:-hilbert:

restart;

inttrans:-hilbert(sin(a)*sin(t+b), t, s);
# should be:
sin(a)*cos(s+b);   expand(%);

sin(a)*cos(s)

 

sin(a)*cos(s+b)

 

sin(a)*cos(s)*cos(b)-sin(a)*sin(s)*sin(b)

(1)

########## correction ##############

`inttrans/expandc` := proc(expr, t)
local xpr, j, econst, op1, op2;
      xpr := expr;      
      for j in indets(xpr,specfunc(`+`,exp)) do
          econst := select(type,op(j),('freeof')(t));
          if 0 < nops(econst) and econst <> 0 then
              xpr := subs(j = ('exp')(econst)*combine(j/('exp')(econst),exp),xpr)
          end if
      end do;
      for j in indets(xpr,{('cos')(linear(t)), ('sin')(linear(t))}) do
          if type(op(j),`+`) then
              op1:=select(has, op(j),t); ##
              op2:=op(j)-op1;            ##
              #op1 := op(1,op(j));
              #op2 := op(2,op(j));
              if op(0,j) = sin then
                  xpr := subs(j = cos(op2)*sin(op1)+sin(op2)*cos(op1),xpr)
              else
                  xpr := subs(j = cos(op1)*cos(op2)-sin(op1)*sin(op2),xpr)
              end if
          end if
      end do;
      return xpr
end proc:

#######################################

inttrans:-hilbert(sin(a)*sin(t+b), t, s); expand(%);

-(1/2)*cos(a-b)*sin(s)+(1/2)*sin(a-b)*cos(s)+(1/2)*cos(a+b)*sin(s)+(1/2)*sin(a+b)*cos(s)

 

sin(a)*cos(s)*cos(b)-sin(a)*sin(s)*sin(b)

(2)

 


Download hilbert.mw

 


Minimum:
1. Maple Tour
2. Maple Quick Start
3. Quick Help
4. Quick Reference Card
5. Math Apps
6. Plotting Guide
...
https://drive.google.com/file/d/1ZAlFQ8_MbuKNsr2PDIyEHmIoogKInBmE/view?usp=sharing

Is that only for my students?

In worksheets:
https://drive.google.com/file/d/1cfA8WKPXSQQxJQR7KbyYHBY6g4OjHaSn/view?usp=sharing

This is about the recent implementation of tensor products of quantum state spaces in the Physics package, in connection with an exchange with the Physics of Information Lab of the University of Waterloo. As usual this development is available to everybody from the Maplesoft R&D Physics webpage. This is the last update for Maple 2017. The updates for Maple 2018, starting with this same material, will begin being distributed through the MapleCloud next week.

Tensor Product of Quantum State Spaces

 

Basic ideas and design

 

 

Suppose A and B are quantum operators and Ket(A, n), et(B, m) are, respectively, their eigenkets. The following works since the introduction of the Physics package in Maple

with(Physics)

Setup(op = {A, B})

`* Partial match of  'op' against keyword 'quantumoperators'`

 

[quantumoperators = {A, B}]

(1)

A*Ket(A, alpha) = A.Ket(A, alpha)

Physics:-`*`(A, Physics:-Ket(A, alpha)) = alpha*Physics:-Ket(A, alpha)

(2)

B*Ket(B, beta) = B.Ket(B, beta)

Physics:-`*`(B, Physics:-Ket(B, beta)) = beta*Physics:-Ket(B, beta)

(3)

where on the left-hand sides the product operator `*` is used as a sort of inert form (it has all the correct mathematical properties but does not perform the contraction) of the dot product operator `.`, used on the right-hand sides.

 

Suppose now that A and B act on different, disjointed, Hilbert spaces.

 

1) To represent that, a new keyword in Setup , is introduced, to indicate which spaces are disjointed, say as in disjointedhilbertspaces = {A, B}.  We want this notation to pop up at some point as {`&Hscr;`[A], `&Hscr;`[B]} where the indexation indicates all the operators acting on that Hilbert space. The disjointedspaces keyword has for synonyms disjointedhilbertspaces and hilbertspaces. The display `&Hscr;`[A] is not yet implemented.

 

NOTE: noncommutative quantum operators acting on disjointed spaces commute between themselves, so after setting  - for instance - disjointedspaces = {A, B}, automatically, A, B become quantum operators satisfying (see comment (ii) on page 156 of ref. [1])

 

"[A,B][-]=0"

 

2) Product of Kets and Bras (KK, BB, KB and BK) where K and B belong to disjointed spaces, are understood as tensor products satisfying, for instance with disjointed spaces A and B (see footnote on page 154 of ref. [1]),

 

`&otimes;`(Ket(A, alpha), Ket(B, beta)) = `&otimes;`(Ket(B, beta), Ket(A, alpha)) 

 

`&otimes;`(Bra(A, alpha), Ket(B, beta)) = `&otimes;`(Ket(B, beta), Bra(A, alpha)) 

 

while of course

Bra(A, alpha)*Ket(A, alpha) <> Bra(A, alpha)*Ket(A, alpha)

 

Details

   

 

3) All the operators of one disjointed space act transparently over operators, Bras and Kets of the other disjointed spaces, for example

 

A*Ket(B, n) = A*Ket(B, n)

and the same for the Dagger of this equation, that is

Bra(B, n)*Dagger(A) = Bra(B, n)*Dagger(A)

 

And this happens automatically. Hence, when we write the left-hand sides and press enter, they are automatically rewritten (returned) as the right-hand sides.

 

Note that for the product of an operator times a Bra or a Ket we are not using the notation that expresses the product with the symbol 5.

 

Regarding the display of Bras and Kets and their tensor products, two enhancements are happening:

 

• 

A new Setup option hideketlabel makes all the labels in Kets and Bras to be hidden when displaying Kets, Bras and Bracket(s), with the indices presented one level up, as if they were a sequence of labels, so that:

 "Ket(A,m,n,l"  

is displayed as

Ket(A, m, n, l)

 

  

This is the notation used more frequently when working in quantum information. This hideketlabel option is already implemented entering Setup(hideketlabel = true)

• 

Tensor products formed with operators, or Bras and Kets, that belong to disjointed spaces (set as such using Setup ), are displayed with the symbol 5 in between, as in Ket(A, n)*Ket(B, n) instead of Ket(A, n)*Ket(B, n), and `&otimes;`(A, B) instead of A*B.

Tensor product notation and the hideketlabel option

   

The implementation of tensor products using `*` and `.`

   

Basic exercising with the new functionality

   

Related functionality already in place before these changes

   

Reference

 

[1] Cohen-Tannoudji, Diue, Laloe, Quantum Mechanics, Chapter 2, section F.

[2] Griffiths Robert B., Hilbert Space Quantum Mechanics, Quantum Computation and Quantum Information Theory Course, Physics Department, Carnegie Mellon University, 2014.

See also

   

 


 

Download TensorProductDesign.mw
 

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

Carmichael's lambda(n) function (as it relates to Euler's Totient Function).....this is just one of 8 stages of animation. 

 

Here's the complete animation with supporting music by the mighty Stormtroopers Of Death....

https://youtu.be/QN-s3EpZICs

 

 

 

 

 

Automatic handling of collision of tensor indices in products

 

 

The design of products of tensorial expressions that have contracted indices got enhanced. The idea: repeated indices in certain subexpressions are actually dummies. So suppose T[a, b] and B[b] are tensors, then in T[trace] = T[a, `~a`], a is just a dummy, therefore T[a, `~a`]*B[a] = T[b, `~b`]*B[a] is a well defined object. The new design automatically maps input like T[a, `~a`]*B[a] into T[b, `~b`]*B[a]. This significantly simplifies the manipulation of indices when working with products of tensorial expressions: each tensorial expression being multiplied has its repeated indices automatically transformed into different ones when they would collide with the free or repeated indices of the other expressions being multiplied.

 

This functionality is available within the Physics update distributed at the Maplesoft R&D Physics webpage (but for what you see under Preview that makes use of a new kernel feature of the Maple version under development).

 

restart

with(Physics); Setup(spacetimeindices = lowercaselatin, quiet)

[spacetimeindices = lowercaselatin]

(1)

Define(T[a, b], B[b])

`Defined objects with tensor properties`

 

{B[b], Physics:-Dgamma[a], Physics:-Psigma[a], T[a, b], Physics:-d_[a], Physics:-g_[a, b], Physics:-KroneckerDelta[a, b], Physics:-LeviCivita[a, b, c, d]}

(2)

This shows the automatic handling of collision of indices

T[a, a]*B[a]

T[b, `~b`]*B[a]

(3)

T[a, a]^2

T[a, `~a`]*T[b, `~b`]

(4)

``

Preview only in the upcomming version under development

 

Consider now the case of three tensors

Define(A[a], C[a])

`Defined objects with tensor properties`

 

{A[a], B[b], C[a], Physics:-Dgamma[a], Physics:-Psigma[a], T[a, b], Physics:-d_[a], Physics:-g_[a, b], Physics:-KroneckerDelta[a, b], Physics:-LeviCivita[a, b, c, d]}

(5)

A[a]*B[a]*C[a]

A[a]*B[a]*C[a]

(6)

The product above has indeed the index a repeated more than once, therefore none of its occurrences got automatically transformed into contravariant in the output, and Check  detects the problem interrupting with an error  message

Check(A[a]*B[a]*C[a])

Error, (in Physics:-Check) wrong use of the summation rule for repeated indices: `a repeated 3 times`, in A[a]*B[a]*C[a]

 

 

However, it is now also possible to indicate, using parenthesis, that the product of two of these tensors actually form a subexpression, so that the following two tensorial expressions are well defined, and the colliding dummy is automatically replaced making that explicit

A[a]*B[a]*C[a]

A[b]*B[`~b`]*C[a]

(7)

A[a]*B[a]*C[a]

A[a]*B[b]*C[`~b`]

(8)

 

 

This change in design makes concretely simpler the use of indices in that it eliminates the need for manually replacing dummies. For example, consider the tensorial expression for the angular momentum in terms of the coordinates and momentum vectors, in 3 dimensions

 

Setup(coordinates = cartesian, dimension = 3, metric = euclidean, quiet)

[coordinatesystems = {X}, dimension = 3, metric = {(1, 1) = 1, (2, 2) = 1, (3, 3) = 1}]

(9)

Define L[j], p[k] respectively representing angular and linear momentum

Define(L[j], p[k])

`Defined objects with tensor properties`

 

{Physics:-Dgamma[a], L[j], Physics:-Psigma[a], Physics:-d_[a], Physics:-g_[a, b], p[k], Physics:-KroneckerDelta[a, b], Physics:-LeviCivita[a, b, c], Physics:-SpaceTimeVector[a](X)}

(10)

Introduce the tensorial expression for L[a]

L[a] = LeviCivita[a, b, c]*X[b]*p[c]

L[a] = Physics:-LeviCivita[a, b, c]*Physics:-SpaceTimeVector[b](X)*p[c]

(11)

The left-hand side has one free index, a, while the right-hand side has two dummy indices b and c

Check(L[a] = Physics[LeviCivita][a, b, c]*Physics[SpaceTimeVector][b](X)*p[c], all)

`The repeated indices per term are: `[{`...`}, {`...`}, `...`]*`; the free indices are: `*{`...`}

 

([{}], {a}) = ([{b, c}], {a})

(12)

If we want to compute`#mrow(msup(mfenced(mover(mi("L"),mo("&rarr;")),open = "&Vert;",close = "&Vert;"),mn("2")),mo("&equals;"),msubsup(mi("L"),mi("a"),mn("2")))`we can now take the square of (11) directly, and the dummy indices on the right-hand side are automatically handled, there is now no need to manually substitute the repeated indices to avoid their collision

(L[a] = Physics[LeviCivita][a, b, c]*Physics[SpaceTimeVector][b](X)*p[c])^2

L[a]^2 = Physics:-LeviCivita[a, b, c]*Physics:-SpaceTimeVector[b](X)*p[c]*Physics:-LeviCivita[a, d, e]*Physics:-SpaceTimeVector[d](X)*p[e]

(13)

The repeated indices on the right-hand side are now a, b, c, d, e

Check(L[a]^2 = Physics[LeviCivita][a, b, c]*Physics[SpaceTimeVector][b](X)*p[c]*Physics[LeviCivita][a, d, e]*Physics[SpaceTimeVector][d](X)*p[e], all)

`The repeated indices per term are: `[{`...`}, {`...`}, `...`]*`; the free indices are: `*{`...`}

 

([{a}], {}) = ([{a, b, c, d, e}], {})

(14)

NULL


 

Download AutomaticHandlingCollisionOfTensorIndices.mw

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

 

Minimize the number of tensor components according to its symmetries
(and relabel, redefine or count the number of independent tensor components)

 

 

The nice development described below is work in collaboration with Pascal Szriftgiser from Laboratoire PhLAM, Université Lille 1, France, used in the Mapleprimes post Magnetic traps in cold-atom physics

 

A new keyword in Define  and Setup : minimizetensorcomponents, allows for automatically minimizing the number of tensor components taking into account the tensor symmetries. For example, if a tensor with two indices in a 4D spacetime is defined as antisymmetric using Define with this new keyword, the number of different tensor components will be exactly 6, and the elements of the diagonal are automatically set equal to 0. After setting this keyword to true with Setup , all subsequent definitions of tensors automatically minimize the number of components while using this keyword with Define  makes this minimization only happen with the tensors being defined in the call to Define .

 

Related to this new functionality, 4 new Library routines were added: MinimizeTensorComponents, NumberOfIndependentTensorComponents, RelabelTensorComponents and RedefineTensorComponents

 

Example:

restart; with(Physics)

 

Define an antisymmetric tensor with two indices

Define(F[mu, nu], antisymmetric)

`Defined objects with tensor properties`

 

{Physics:-Dgamma[mu], F[mu, nu], Physics:-Psigma[mu], Physics:-d_[mu], Physics:-g_[mu, nu], Physics:-KroneckerDelta[mu, nu], Physics:-LeviCivita[alpha, beta, mu, nu]}

(1.1)

Although the system knows that F[mu, nu] is antisymmetric, you need to use Simplify to apply the (anti)symmetry

F[mu, nu]+F[nu, mu]

F[mu, nu]+F[nu, mu]

(1.2)

 

Simplify(F[mu, nu]+F[nu, mu])

0

(1.3)

so by default the components of F[mu, nu] do not automatically reflect the (anti)symmetry; likewise

F[1, 2]+F[2, 1]

F[1, 2]+F[2, 1]

(1.4)

Simplify(F[1, 2]+F[2, 1])

0

(1.5)

and computing the array form of F[mu, nu]we do not see the elements of the diagonal equal to zero nor the lower-left triangle equal to the upper-right triangle but for a different sign:

TensorArray(F[mu, nu])

Matrix(%id = 18446744078270093062)

(1.6)

 

On the other hand, this new functionality, here called minimizetensorcomponents, makes the symmetries of the tensor be explicitly reflected in its components.

 

There are three ways to use it. First, one can minimize the number of tensor components of a tensor previously defined. For example

 

Library:-MinimizeTensorComponents(F)

Matrix(%id = 18446744078270064630)

(1.7)

After this, both (1.2) and (1.3) are automatically equal to 0 without having to use Simplify

F[mu, nu]+F[nu, mu]

0

(1.8)

0

0

(1.9)

And the output of TensorArray  in (1.6) becomes equal to (1.7).

 

NOTE: in addition, after using minimizetensorcomponents in the definition of a tensor, say F, all the keywords implemented for Physics tensors are available for F:

 

F[]

F[mu, nu] = Matrix(%id = 18446744078247910206)

(1.10)

F[trace]

0

(1.11)

F[nonzero]

F[mu, nu] = {(1, 2) = F[1, 2], (1, 3) = F[1, 3], (1, 4) = F[1, 4], (2, 1) = -F[1, 2], (2, 3) = F[2, 3], (2, 4) = F[2, 4], (3, 1) = -F[1, 3], (3, 2) = -F[2, 3], (3, 4) = F[3, 4], (4, 1) = -F[1, 4], (4, 2) = -F[2, 4], (4, 3) = -F[3, 4]}

(1.12)

"F[~1,mu,matrix]"

F[`~1`, mu] = Vector[row](%id = 18446744078247885990)

(1.13)

Alternatively, one can define a tensor, specifying that the symmetries should be taken into account to minimize the number of its components passing the keyword minimizetensorcomponents to Define .

 

Example:

 

Define a tensor with the symmetries of the Riemann  tensor, that is, a tensor of 4 indices that is symmetric with respect to interchanging the positions of the 1st and 2nd pair of indices and antisymmetric with respect to interchanging the position of its 1st and 2nd indices, or 3rd and 4th indices, and define it minimizing the number of tensor components

 

Define(R[alpha, beta, mu, nu], symmetric = {[[1, 2], [3, 4]]}, antisymmetric = {[1, 2], [3, 4]}, minimizetensorcomponents)

`Defined objects with tensor properties`

 

{Physics:-Dgamma[mu], F[mu, nu], Physics:-Psigma[mu], R[mu, nu, alpha, beta], Physics:-d_[mu], Physics:-g_[mu, nu], Physics:-KroneckerDelta[mu, nu], Physics:-LeviCivita[alpha, beta, mu, nu]}

(1.14)

We now have

R[1, 2, 3, 4]+R[2, 1, 3, 4]

0

(1.15)

R[alpha, beta, mu, nu]-R[mu, nu, alpha, beta]

0

(1.16)
• 

One can always retrieve the symmetry properties in the abstract notation used by the Define command using the new Library:-GetTensorSymmetryProperties, its output is ordered, first the symmetric then the antisymmetric properties

 

Library:-GetTensorSymmetryProperties(R)

{[[1, 2], [3, 4]]}, {[1, 2], [3, 4]}

(1.17)
• 

After making the symmetries explicit (and also before that), it is frequently useful to know the number of independent components of a given tensor. For this purpose you can use the new Library:-NumberOfIndependentTensorComponents

 

Library:-NumberOfIndependentTensorComponents(R)

21

(1.18)

and besides taking into account the symmetries, in the case of the Riemann  tensor, after taking into account the first Bianchi identity this number of components is further reduced to 20.

 

A third way of using the new minimizetensorcomponents functionality is using Setup , so that, automatically, every subsequent definition of tensors with symmetries is performed minimizing the number of its components using the indicated symmetries

 

Example:

Setup(minimizetensorcomponents = true)

[minimizetensorcomponents = true]

(1.19)

So from hereafter you can define tensors taking into account their symmetries explicitly and without having to include the keyword minimizetensorcomponents at each definition

 

Define(C[alpha, beta], antisymmetric)

`Defined objects with tensor properties`

 

{C[mu, nu], Physics:-Dgamma[mu], F[mu, nu], Physics:-Psigma[mu], R[mu, nu, alpha, beta], Physics:-d_[mu], Physics:-g_[mu, nu], Physics:-KroneckerDelta[mu, nu], Physics:-LeviCivita[alpha, beta, mu, nu]}

(1.20)

 

C[]

C[mu, nu] = Matrix(%id = 18446744078408747598)

(1.21)
• 

Two new related functionalities are provided via Library:-RelabelTensorComponents and Library:-RedefineTensorComponent, the first one to have the number of tensor components directly reflected in the names of the components, the second one to redefine only one of these components

Library:-RelabelTensorComponents(C)

Matrix(%id = 18446744078408729774)

(1.22)

 

Suppose now we want to make one of these components equal to 1, say C__2

Library:-RedefineTensorComponent(C[1, 2] = 1)

C[mu, nu] = Matrix(%id = 18446744078270104390)

(1.23)

This nice development is work in collaboration with Pascal Szriftgiser from Laboratoire PhLAM, UMR CNRS 8523, Université Lille 1, F-59655, France.

``

 

Download MinimizeTensorComponents.mw

 

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

Lesson_on_functions.mws

As the title says, a lesson on functions:  eg the -> operator, f(2), eval, evalf etc 

This post is devoted to the rigorous proof of Miquel's five circles theorem, which I learned about from this question. The proof is essentially very simple and takes only 15 lines of code. The figure below, in which all the labels coincide with the corresponding names in the code, illustrates the basic ideas of the code. First, we symbolically define common points of intersection of blue circles with a red unit circle  (these parameters  s1 .. s5  are the polar coordinates of these points). All other parameters of this configuration can be expressed through them. Then we find the centers  M  and  N  of two circles. Then we find the coordinates of the point  K  from the condition that  CK  is perpendicular to  MN . Then we find the point  and using the result obtained, we easily find the coordinates  of all the points  A1 .. A5. Then we find the coordinates of the point   P  as the point of intersection of the lines  A1A2  and  A3A4 . Finally, we verify that the point  P  lies on a circle with center at the point  N , which completes the proof.

                      

 

Below - the code of the proof. Note that the code does not use any special (in particular geometric) packages, only commands from the Maple kernel. I usually try any geometric problems to solve in this style, it is more reliable,  and often shorter.

restart;
t1:=s1/2+s2/2: t2:=s2/2+s3/2:
M:=[cos(t1),sin(t1)]: N:=[cos(t2),sin(t2)]:
C:=[cos(s2),sin(s2)]: K:=(1-t)*~M+t*~N:
CK:=K-C: MN:=M-N:
t0:=simplify(solve(CK[1]*MN[1]+CK[2]*MN[2]=0, t)):
E:=combine(simplify(C+2*eval(CK,t=t0))):
s0:=s5-2*Pi: s6:=s1+2*Pi:
assign(seq(A||i=eval(E,[s2=s||i,s1=s||(i-1),s3=s||(i+1)]), i=1..5)):
Dist:=(p,q)->sqrt((p[1]-q[1])^2+(p[2]-q[2])^2):
LineEq:=(P,Q)->(y-P[2])*(Q[1]-P[1])=(x-P[1])*(Q[2]-P[2]):
Line1:=LineEq(A1,A2):
Line2:=LineEq(A3,A4):
P:=combine(simplify(solve({Line1,Line2},[x,y])))[]:
Circle:=(x-N[1])^2+(y-N[2])^2-Dist(N,C)^2:
is(eval(Circle, P)=0);  
# The final result

                                                                    true


It may seem that this proof is easy to repeat manually. But this is not so. Maple brilliantly coped with very cumbersome trigonometric transformations. Look at the coordinates of point  , expressed through the initial parameters  s1 .. s5 :

simplify(eval([x,y], P));  # The coordinates of the point  P

  

  

 

ProofMiquel.mw

A few days ago, I drew attention to the question in which OP talked about the generation of triangles in a plane, for which the lengths of all sides, the area and radius of the inscribed circle are integers. In addition, all vertices must have different integer coordinates (6 different integers), the lengths of all sides are different and the triangles should not be rectangular. I prepared the answer to this question, but the question disappeared somewhere, so I designed my answer as a separate post.

The triangles in the plane, for which the lengths of all sides and the area  are integers, are called as Heronian triangles. See this very interesting article in the wiki about such triangles
https://en.wikipedia.org/wiki/Integer_triangle#Heronian_triangles

The procedure finds all triangles (with the fulfillment of all conditions above), for which the lengths of the two sides are in the range  N1 .. N2 . The left side of the range is an optional parameter (by default  N1=5). It is not recommended to take the length of the range more than 100, otherwise the operating time of the procedure will greatly increase. The procedure returns the list in which each triangle is represented by a list of  [list of coordinates of the vertices, area, radius of the inscribed circle, list of lengths of the sides]. Without loss of generality, one vertex coincides with the origin (obviously, by a shift it is easy to place it at any point). 

The procedure works as follows: one vertex at the origin, then the other two must lie on circles with integer and different radii  x^2+y^2=r^2. Using  isolve  command, we find all integer points on these circles, and then in the for loops we select the necessary triangles.


 

 

restart;
HeronianTriangles:=proc(N2::posint,N1::posint:=5)
local k, r, S, L, Ch, Dist, IsOnline, c, P, p, A, B, C, a, b, s, ABC, cc, s1, T ;
uses combinat, geometry;
if N2<N1 then error "Should be N2>=N1" fi;
if N2<34 then return [] fi;
k:=0:
for r from max(N1,5) to N2 do
S:=[isolve(x^2+y^2=r^2)];
if nops(S)>4 then k:=k+1; L[k]:=select(s->s[1]<>0 and s[2]<>0,map(t->rhs~(convert(t,list)), S)); fi;
od:
L:=convert(L, list):
if type(L[1],symbol) then return [] fi;

Ch:=combinat:-choose([$1..nops(L)], 2):
Dist:=(A::list,B::list)->simplify(sqrt((A[1]-B[1])^2+(A[2]-B[2])^2));
IsOnline:=(A::list,B::list)->`if`(A[1]*B[2]-A[2]*B[1]=0, true, false);
k:=0:
for c in Ch do
for A in L[c[1]] do
for B in L[c[2]] do
if not IsOnline(A,B) and nops({A[],B[]})=4 then if type(Dist(A,B),posint) then
 k:=k+1; P[k]:=[A,B] fi; fi;
od: od: od:
P:=convert(P, list):
if type(P[1],symbol) then return [] fi;

k:=0:
for p in P do
point('A',0,0), point('B',p[1]), point('C',p[2]);
a:=simplify(distance('A','B')); b:=simplify(distance('A','C')); c:=simplify(distance('B','C'));
s:=sort([a,b,c]); s1:={a,b,c};
triangle(ABC,['A','B','C']);
incircle(cc,ABC);
r:=radius(cc);
if type(r,integer) and s[3]^2<>s[1]^2+s[2]^2 and nops(s1)=3 then k:=k+1; T[k]:=[[[0,0],p[]],area(ABC),r, [a,b,c]] fi;
od:
T:=convert(T,list);
if type(T[1],symbol) then return [] fi;
T;
end proc:

Examples of use of the procedure  HeronianTriangles

T:=HeronianTriangles(100): # All the Geronian triangles, whose lengths of two sides do not exceed 100
nops(T);

256

(1)

Tp:=select(p->p[1,2,1]>0 and p[1,2,2]>0 and p[1,3,1]>0 and p[1,3,2]>0, T);

[[[[0, 0], [16, 30], [28, 21]], 252, 6, [34, 35, 15]], [[[0, 0], [30, 16], [21, 28]], 252, 6, [34, 35, 15]], [[[0, 0], [21, 28], [15, 36]], 168, 4, [35, 39, 10]], [[[0, 0], [28, 21], [36, 15]], 168, 4, [35, 39, 10]], [[[0, 0], [27, 36], [13, 84]], 900, 10, [45, 85, 50]], [[[0, 0], [36, 27], [84, 13]], 900, 10, [45, 85, 50]], [[[0, 0], [33, 44], [48, 36]], 462, 7, [55, 60, 17]], [[[0, 0], [44, 33], [36, 48]], 462, 7, [55, 60, 17]], [[[0, 0], [33, 44], [96, 28]], 1650, 15, [55, 100, 65]], [[[0, 0], [44, 33], [28, 96]], 1650, 15, [55, 100, 65]], [[[0, 0], [16, 63], [72, 21]], 2100, 20, [65, 75, 70]], [[[0, 0], [63, 16], [21, 72]], 2100, 20, [65, 75, 70]], [[[0, 0], [39, 52], [18, 80]], 1092, 12, [65, 82, 35]], [[[0, 0], [52, 39], [80, 18]], 1092, 12, [65, 82, 35]], [[[0, 0], [32, 60], [56, 42]], 1008, 12, [68, 70, 30]], [[[0, 0], [60, 32], [42, 56]], 1008, 12, [68, 70, 30]], [[[0, 0], [42, 56], [30, 72]], 672, 8, [70, 78, 20]], [[[0, 0], [56, 42], [72, 30]], 672, 8, [70, 78, 20]]]

(2)

Tr:=map(p->p+[2,1],Tp[1,1]);
with(geometry):
point(A,Tr[1]), point(B,Tr[2]), point(C,Tr[3]):
triangle(ABC,[A,B,C]):
simplify(distance(A,B)), simplify(distance(A,C)), simplify(distance(B,C));
local O:
incircle(c,ABC, centername=O):
draw([A,B,C, ABC, c(color=blue)], color=red, thickness=2, symbol=solidcircle, tickmarks = [spacing(1)$2], gridlines, scaling=constrained, view=[0..31,0..33], size=[800,550], printtext=true, font=[times, 18], axesfont=[times, 10]);

[[2, 1], [18, 31], [30, 22]]

 

34, 35, 15

 

 



Examples of triangles with longer sides

T:=HeronianTriangles(1000,980):  # All the Geronian triangles, whose lengths of two sides lie in the range  980..1000
nops(T);

56

(3)

Tp:=select(p->p[1,2,1]>0 and p[1,2,2]>0 and p[1,3,1]>0 and p[1,3,2]>0, T);  # Triangles lying in the first quarter x>0, y>0
nops(%);

[[[[0, 0], [540, 819], [680, 714]], 85680, 80, [981, 986, 175]], [[[0, 0], [819, 540], [714, 680]], 85680, 80, [981, 986, 175]], [[[0, 0], [216, 960], [600, 800]], 201600, 168, [984, 1000, 416]], [[[0, 0], [960, 216], [800, 600]], 201600, 168, [984, 1000, 416]], [[[0, 0], [380, 912], [324, 945]], 31806, 31, [988, 999, 65]], [[[0, 0], [912, 380], [945, 324]], 31806, 31, [988, 999, 65]], [[[0, 0], [594, 792], [945, 324]], 277992, 216, [990, 999, 585]], [[[0, 0], [792, 594], [324, 945]], 277992, 216, [990, 999, 585]]]

 

8

(4)

 


 

Download Integer_Triangle1.mw

Edit.

In the beginning, Maple had indexed names, entered as x[abc]; as early as Maple V Release 4 (mid 1990s), this would display as xabc. So, x[1] could be used as x1, a subscripted variable; but assigning a value to x1 created a table whose name was x. This had, and still has, undesirable side effects. See Table 0 for an illustration in which an indexed variable is assigned a value, and then the name of the concomitant table is also assigned a value. The original indexed name is destroyed by these steps.
 

 

At one time this quirk could break commands such as dsolve. I don't know if it still does, but it's a usage that those "in the know" avoid. For other users, this was a problem that cried out for a solution. And Maplesoft did provide such a solution by going nuclear - it invented the Atomic Variable, which subsumed the subscript issue by solving a larger problem.

The larger problem is this: Arbitrary collections of symbols are not necessarily valid Maple names. For example, the expression  is not a valid name, and cannot appear on the left of an assignment operator. Values cannot be assigned to it. The Atomic solution locks such symbols together into a valid name originally called an Atomic Identifier but now called an Atomic Variable. Ah, so then xcan be either an indexed name (table entry) or a non-indexed literal name (Atomic Variable). By solving the bigger problem of creating assignable names, Maplesoft solved the smaller problem of subscripts by allowing literal subscripts to be Atomic Variables.

It is only in Maple 2017 that all vestiges of "Identifier" have disappeared, replaced by "Variable" throughout. The earliest appearance I can trace for the Atomic Identifier is in Maple 11, but it might have existed in Maple 10. Since Maple 11, help for the Atomic Identifier is found on the page 

 

In Maple 17 this help could be obtained by executing help("AtomicIdentifier"). In Maple 2017, a help page for AtomicVariables exists.

In Maple 17, construction of these Atomic things changed, and a setting was introduced to make writing literal subscripts "simpler." With two settings and two outcomes for a "subscripted variable" (either indexed or non-indexed), it might be useful to see the meaning of "simpler," as detailed in the worksheet AfterMath.mw.

It passed through my mind it would be interesting to collect the links to the most relevant Mapleprimes posts about Quantum Mechanics using the Physics package of the last couple of years, to have them all accessible from one place. These posts give an idea of what kind of computation is already doable in quantum mechanics, how close is the worksheet input to what we write with paper and pencil, and how close is the typesetting of the output to what we see in textbooks.

At the end of each page linked below, you will see another link to download the corresponding worksheet, that you can open using Maple (say the current version or the version 1 or 2 years ago).

This other set of three consecutive posts develops one problem split into three parts:

This other link is interesting as a quick and compact entry point to the use of the Physics package:

There is an equivalent set of Mapleprimes posts illustrating the Physics package tackling problems in General Relativity, collecting them is for one other time.

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

December 2017: This is, perhaps, one of the most complicated computations done in this area using the Physics package. To the best of my knowledge never before performed on a computer algebra worksheet. It is exciting to present a computation like this one. At the end the corresponding worksheet is linked so that it can be downloaded and the sections be opened, the computation be reproduced. There is also a link to a pdf with everything open.  Special thanks to Pascal Szriftgiser for bringing this problem. To reproduce the computations below, please update the Physics library with the one distributed from the Maplesoft R&D Physics webpage.

June 17, 2020: updated taking advantage of new features of Maple 2020.1 and Physics Updates v.705. Submitted to arxiv.org

January 25, 2021: updated in the arXiv and submitted for publication in Computer Physics Communications

 

 

Quantum Runge-Lenz Vector and the Hydrogen Atom,

the hidden SO(4) symmetry using Computer Algebra

 

Pascal Szriftgiser1 and Edgardo S. Cheb-Terrab2 

(1) University of Lille, CNRS, UMR 8523 - PhLAM - Physique des Lasers, Atomes et Molécules, F-59000 Lille, France

(2) Maplesoft

NULL

 

Abstract

 

Pauli first noticed the hidden SO(4) symmetry for the Hydrogen atom in the early stages of quantum mechanics [1]. Departing from that symmetry, one can recover the spectrum of a spinless hydrogen atom and the degeneracy of its states without explicitly solving Schrödinger's equation [2]. In this paper, we derive that SO(4) symmetry and spectrum using a computer algebra system (CAS). While this problem is well known [3, 4], its solution involves several steps of manipulating expressions with tensorial quantum operators, simplifying them by taking into account a combination of commutator rules and Einstein's sum rule for repeated indices. Therefore, it is an excellent model to test the current status of CAS concerning this kind of quantum-and-tensor-algebra computations. Generally speaking, when capable, CAS can significantly help with manipulations that, like non-commutative tensor calculus subject to algebra rules, are tedious, time-consuming and error-prone. The presentation also shows a pattern of computer algebra operations that can be useful for systematically tackling more complicated symbolic problems of this kind.

 

Introduction

 

The primary purpose of this work is to derive, step-by-step, the SO(4) symmetry of the Hydrogen atom and its spectrum using a computer algebra system (CAS). To the best of our knowledge, such a derivation using symbolic computation has not been shown before. Part of the goal was also to see whether this computation can be performed entering only the main definition formulas, followed by only simplification commands, and without using previous knowledge of the result. The intricacy of this problem is in the symbolic manipulation and simplification of expressions involving noncommutative quantum tensor operators. The simplifications need to take into account commutator rules, symmetries under permutation of indices of tensorial subexpressions, and use Einstein's sum rule for repeated indices.

We performed the derivation using the Maple 2020 system with the Maplesoft Physics Updates v.705. Generally speaking, the default computational domain of CAS doesn't include tensors, noncommutative operators nor related simplifications. On the other hand, the Maple system is distributed with a Physics package that extends that default domain to include those objects and related operations. Physics includes a Simplify command that takes into account custom algebra rules and the sum rule for repeated indices, and uses tensor-simplification algorithms [5] extended to the noncommutative domain.

 

A note about notation: when working with a CAS, besides the expectation of achieving a correct result for a complicated symbolic calculation, readability is also an issue. It is desired that one be able to enter the definition formulas and computational steps to be performed (the input, preceded by a prompt >, displayed in black) in a way that resembles as closely as possible their paper and pencil representation, and that the results (the output, computed by Maple, displayed in blue) use textbook mathematical-physics notation. The Physics package implements such dedicated typesetting. In what follows, within text and in the output, noncommutative objects are displayed using a different color, e.g. H, vectors and tensor indices are displayed the standard way, as in `#mover(mi("L",mathcolor = "olive"),mo("&rarr;"))`, and L[q], and commutators are displayed with a minus subscript, e.g. "[H,L[q]][-]". Although the Maple system allows for providing dedicated typesetting also for the input, we preferred to keep visible the Maple input syntax, allowing for comparison with paper and pencil notation. We collected the names of the commands used and a one line description for them in an Appendix at the end. Maple also implements the concept of inert representations of computations, which are activated only when desired. We use this feature in several places. Inert computations are entered by preceding the command with % and are displayed in grey. Finally, as is usual in CAS, every output has an equation label, which we use throughout the presentation to refer to previous intermediate results.

 

In Sec.1, we recall the standard formulation of the problem and present the computational goal, which is the derivation of the formulas representing the SO(4) symmetry and related spectrum.

 

In Sec.2, we set tensorial non-commutative operators representing position and linear and angular momentum, respectively X[a], p[a] and L[a], their commutation rules used as departure point, and the form of the quantum Hamiltonian H. We also derive a few related identities used in the sections that follow.

 

In Sec.3, we derive the conservation of both angular momentum and the Runge-Lenz quantum operator, respectively "[H,L[q]][-]=0" and "[H,Z[k]][-]=0". Taking advantage of the differentialoperators functionality in the Physics package, we perform the derivation exploring two equivalent approaches; first using only a symbolic tensor representation p[j] of the momentum operator, then using an explicit differential operator representation for it in configuration space, p[j] = -i*`&hbar;`*`&PartialD;`[j].  With the first approach, expressions are simplified only using the departing commutation rules and Einstein's sum rule for repeated indices. Using the second approach, the problem is additionally transformed into one where the differentiation operators are applied explicitly to a test function G(X). Presenting both approaches is of potential interest as it offers two partly independent methods for performing the same computation, which is helpful to provide confidence on in the results when unknown, a relevant issue when using computer algebra.

 

In Sec. 4, we derive %Commutator(L[m], Z[n]) = I*`&hbar;`*`&epsilon;`[m, n, u]*Z[u] and show that the classical relation between angular momentum and the Runge-Lenz vectors,  "L *"`#mover(mi("Z"),mo("&rarr;"))` = 0, due to the orbital momentum being perpendicular to the elliptic plane of motion while the Runge-Lenz vector lies in that plane, still holds in quantum mechanics, where the components of these quantum vector operators do not commute but "L *"`#mover(mi("Z",mathcolor = "olive"),mo("&rarr;"))` = "(Z) *"`#mover(mi("L",mathcolor = "olive"),mo("&rarr;"))` = 0.

 

In Sec. 5, we derive "[Z[a],Z[b]][-]=-(2 i `&hbar;` `&epsilon;`[a,b,c] (H L[c]))/`m__e`" using the two alternative approaches described for Sec.3.

In Sec. 6, we derive the well-known formula for the square of the Runge-Lenz vector, Z[k]^2 = 2*H*(`&hbar;`^2+L[a]^2)/m__e+kappa^2.

 

Finally, in Sec. 7, we use the SO(4) algebra derived in the previous sections to obtain the spectrum of the Hydrogen atom. Following the literature, this approach is limited to the bound states for which the energy is negative.

 

Some concluding remarks are presented at the end, and input syntax details are summarized in an Appendix.

 

1. The hidden SO(4) symmetry of the Hydrogen atom

 

 

Let's consider the Hydrogen atom and its Hamiltonian

H = LinearAlgebra[Norm](`#mover(mi("p"),mo("&rarr;"))`)^2/(2*m__e)-kappa/r,

 

where `#mover(mi("p"),mo("&rarr;"))`is the electron momentum, m__e its mass, κ a real positive constant, r = `&equiv;`(LinearAlgebra[Norm](`#mover(mi("r"),mo("&rarr;"))`), sqrt(X[a]^2)) the distance of the electron from the proton located at the origin, and X[a] is its tensorial representation with components ["x, y,z]". We assume that the proton's mass is infinite. The electron and nucleus spin are not taken into account. Classically, from the potential -kappa/r, one can derive a central force `#mover(mi("F"),mo("&rarr;"))` = -kappa*`#mover(mi("r"),mo("&and;"))`/r^2 that drives the electron's motion. Introducing the angular momentum

 

`#mover(mi("L"),mo("&rarr;"))` = `&x`(`#mover(mi("r"),mo("&rarr;"))`, `#mover(mi("p"),mo("&rarr;"))`),

 

one can further define the Runge-Lenz vector `#mover(mi("Z"),mo("&rarr;"))`

 

"Z=1/(`m__e`) (L)*(p)+kappa ( r)/r."

 

It is well known that `#mover(mi("Z"),mo("&rarr;"))` is a constant of the motion, i.e. diff(`#mover(mi("Z"),mo("&rarr;"))`(t), t) = 0. Switching to Quantum Mechanics, this condition reads

 

%Commutator(H, Z_) = 0.

 

where, for hermiticity purpose, the expression of `#mover(mi("Z",mathcolor = "olive"),mo("&rarr;"))` must be symmetrized

 

`#mover(mi("Z",mathcolor = "olive"),mo("&rarr;"))` = (`&x`(`#mover(mi("L",mathcolor = "olive"),mo("&rarr;"))`, `#mover(mi("p",mathcolor = "olive"),mo("&rarr;"))`)-`&x`(`#mover(mi("p",mathcolor = "olive"),mo("&rarr;"))`, `#mover(mi("L",mathcolor = "olive"),mo("&rarr;"))`))/(2*m__e)+kappa*`#mover(mi("r",mathcolor = "olive"),mo("&rarr;"))`/r.

 

In what follows, departing from the Hamiltonian H, the basic commutation rules between position`#mover(mi("r",mathcolor = "olive"),mo("&rarr;"))`, momentum `#mover(mi("p",mathcolor = "olive"),mo("&rarr;"))` and angular momentum `#mover(mi("L",mathcolor = "olive"),mo("&rarr;"))` in tensor notation, we derive the following commutation rules between the quantum Hamiltonian, angular momentum and Runge-Lenz vector `#mover(mi("Z",mathcolor = "olive"),mo("&rarr;"))`

 

 

"[H,L[n]][-]"

=

0

"[H,Z[n]][-]"

=

0

" [L[m],Z[n]][-]"

=

I*`&hbar;`*`&epsilon;`[m, n, o]*Z[o]

" [Z[m],Z[n]][-]"

=

-(2*(I*`&hbar;`/m__e))*H*`&epsilon;`[m, n, o]*L[o]

 

 

Since H commutes with both `#mover(mi("L",mathcolor = "olive"),mo("&rarr;"))`NULL and `#mover(mi("Z",mathcolor = "olive"),mo("&rarr;"))`, defining

 

"`M__n`=sqrt(-(`m__e`)/(2 H)) `Z__n`,"

these commutation rules can be rewritten as

 

"[L[m],L[n]][-]"

=

I*`&hbar;`*`&epsilon;`[m, n, o]*L[o]

" [L[m],M[n]][-]"

=

I*`&hbar;`*`&epsilon;`[m, n, o]*M[o]

"[M[m],M[n]][-]"

=

I*`&hbar;`*`&epsilon;`[m, n, o]*L[o]

 

 

  

This set constitutes the Lie algebra of the SO(4) group.

  

 

2. Setting the problem, commutation rules and useful identities

   

3. Commutation rules between the Hamiltonian and each of the angular momentum and Runge-Lenz tensors

   

4. Commutation rules between the angular momentum L[q]and the Runge-Lenz Z[k]tensors

   

5.  Commutation rules between the components of the Runge-Lenz tensor

   

6. The square of the norm of the Runge-Lenz vector

   

7. The atomic hydrogen spectrum

   

Conclusions

 

 

In this presentation, we derived, step-by-step, the SO(4) symmetry of the Hydrogen atom and its spectrum using the symbolic computer algebra Maple system. The derivation was performed without departing from the results, entering only the main definition formulas in eqs. (1), (2) and (5), followed by using a few simplification commands - mainly Simplify, SortProducts and SubstituteTensor - and a handful of Maple basic commands, subs, lhs, rhs and isolate. The computational path that was used to get the results of sections 2 to 7 is not unique. Instead of searching for the shortest path, we prioritized clarity and illustration of the techniques that can be used to crack problems like this one.

This problem is mainly about simplifying expressions using two different techniques. First, expressions with noncommutative operands in products need reduction with respect to the commutator algebra rules that have been set. Second, products of tensorial operators require simplification using the sum rule for repeated indices and the symmetries of tensorial subexpressions. Those techniques, which are part of the Maple Physics simplifier, together with the SortProducts and SubstituteTensor commands for sorting the operands in products to apply tensorial identities, sufficed. The derivations were performed in a reasonably small number of steps.

Two different computational strategies - with and without differential operators - were used in sections 3 and 5, showing an approach for verifying results, a relevant issue in general when performing complicated algebraic manipulations. The Maple Physics ability to handle differential operators as noncommutative operands in products (as frequently done in paper and pencil computations) facilitates readability and ease in entering the computations. The complexity of those operations is then handled by one Physics:-Library command, ApplyProductsOfDifferentialOperators (see eqs. (47) and (83)).

Besides the Maple Physics ability to handle noncommutative tensor operators and simplify such operators using commutator algebra rules, it is interesting to note: a) the ability of the system to factorize expressions involving products of noncommutative operands (see eqs. (90) and (108)) and b) the extension of the algorithms for simplifying tensorial expressions [5] to the noncommutativity domain, used throughout this presentation.

It is also worth mentioning how equation labels can reduce the whole computation to entering the main definitions, followed by applying a few commands to equation labels. That approach helps to reduce the chance of typographical errors to a very strict minimum. Likewise, the fact that commands and equations distribute over each other allows cumbersome manipulations to be performed in simple ways, as done, for instance, in eqs. (8), (9) and (13).

Finally, it was significantly helpful for us to have the typesetting of results using standard mathematical physics notation, as shown in the presentation above.

 

Appendix

 

 

In this presentation, the input lines are preceded by a prompt > and the commands used are of three kinds: some basic Maple manipulation commands, the main Physics package commands to set things and simplify expressions, and two commands of the Physics:-Library to perform specialized, convenient, operations in expressions.

 

The basic Maple commands used

 

• 

interface is used once at the beginning to set the letter used to represent the imaginary unit (default is I but we used i).

• 

isolate is used in several places to isolate a variable in an expression, for example isolating x in a*x+b = 0 results in x = -b/a

• 

lhs and rhs respectively get the left-hand side Aand right-hand side Bof an equation A = B

• 

subs substitutes the left-hand side of an equation by the righ-hand side in a given target, for example subs(A = B, A+C) results in B+C

• 

@ is used to compose commands. So(`@`(A, B))(x) is the same as A(B(x)). This command is useful to express an abstract combo of manipulations, for example as in (108) ≡ lhs = `@`(Factor, rhs).

 

The Physics commands used

 

• 

Setup is used to set algebra rules as well as the dimension of space, type of metric, and conventions as the kind of letter used to represent indices.

• 

Commutator computes the commutator between two objects using the algebra rules set using Setup. If no rules are known to the system, it outputs a representation for the commutator that the system understands.

• 

CompactDisplay is used to avoid redundant display of the functionality of a function.

• 

d_[n] represents the `&PartialD;`[n] tensorial differential operator.

• 

Define is used to define tensors, with or without specifying its components.

• 

Dagger  computes the Hermitian transpose of an expression.

• 

Normal, Expand, Factor respectively normalizes, expands and factorizes expressions that involve products of noncommutative operands.

• 

Simplify performs simplification of tensorial expressions involving products of noncommutative factors taking into account Einstein's sum rule for repeated indices, symmetries of the indices of tensorial subexpressions and custom commutator algebra rules.

• 

SortProducts uses the commutation rules set using Setup to sort the non-commutative operands of a product in an indicated ordering.

 

The Physics:-Library commands used

 

• 

Library:-ApplyProductsOfDifferentialOperators applies the differential operators found in a product to the product operands that appear to its right. For example, applying this command to  p*V(X)*m__e results in m__e*p(V(X))

• 

Library:-EqualizeRepeatedIndices equalizes the repeated indices in the terms of a sum, so for instance applying this command to L[a]^2+L[b]^2 results in 2*L[a]^2

 

References

 

[1] W. Pauli, "On the hydrogen spectrum from the standpoint of the new quantum mechanics,” Z. Phys. 36, 336–363 (1926)

[2] S. Weinberg, "Lectures on Quantum Mechanics, second edition, Cambridge University Press," 2015.

[3] Veronika Gáliková, Samuel Kováčik, and Peter Prešnajder, "Laplace-Runge-Lenz vector in quantum mechanics in noncommutative space", J. Math. Phys. 54, 122106 (2013)

[4] Castro, P.G., Kullock, R. "Physics of the so__q(4) hydrogen atom". Theor. Math. Phys. 185, 1678–1684 (2015).

[5] L. R. U. Manssur, R. Portugal, and B. F. Svaiter, "Group-Theoretic Approach for Symbolic Tensor Manipulation," International Journal of Modern Physics C, Vol. 13, No. 07, pp. 859-879 (2002).

 

Download Hidden_SO4_symmetry_of_the_hydrogen_atom.mw

Download Hidden_SO4_symmetry_submitted_to_CPC.pdf (all sections open)


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

First 13 14 15 16 17 18 19 Last Page 15 of 65