Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Method .matrix() in module lt.py returns incorrect matrices; suggested correction; method .det() returns incorrect determinant #453

Open
Greg1950 opened this issue Sep 12, 2020 · 7 comments

Comments

@Greg1950
Copy link
Contributor

Greg1950 commented Sep 12, 2020

Let $f$ be an outermorphism on a geometric algebra Ga.  The matrix of $f$ with respect to a basis $b_1, ..., b_n$ is defined by $f(b_j) = \sum\limits_{i=1}^n f_{ij} b_i$.  The definition can be found in virtually any introductory linear algebra book, so call $[ f_{ij} ]$ the standard matrix of $f$ with respect to the indicated basis. The coefficients $f_{ij}$ in the expansion of $f(b_j)$ do not depend on the metric, although they can be computed using the inner product and the reciprocal basis vectors $b^1, ..., b^n$.

(Note in particular that the left index on $f_{ij}$ is the one summed over. GAlgebra's documentation, if it can be trusted, writes the defining equation as $L(b_i) = \sum\limits_{j=1}^n L_{ij} b_j$, with the summed-over index on the right. This would have the effect of defining a matrix $[ L_{ij} ]$ which is the transpose of $L$'s standard matrix.)

Problem #1: I have discovered that the method .matrix(), the code for which appears in the module lt.py, returns a matrix which iis metric dependent and so cannot be the standard matrix. The command f.matrix() returns the standard matrix only when

  • the inner product is Euclidean, and
  • the basis used is orthonormal. 
    I've also discovered that post-multiplication of f.matrix() by Ga.g_inv produces the standard matrix for f with respect to the basis used to generate Ga.  

As evidence I am attaching a file Linear Transformations.zip.  It contains six Jupyter notebooks, which parallel each other in format, that examine the situation using different signature inner products and different bases.  It also contains gprinter.py, a new module from Alan Bromborsky, that aids the construction of formatted output and which was used by the notebooks mentioned.  Lastly, the zip file contains a notebook g2.ipynb which is easier to examine than the other six notebooks.

Suggested Solution for Problem #1: The next-to-last line of the code for the .matrix() method reads

    self.mat = Dictionary_to_Matrix(self.lt_dict, self.Ga) * self.Ga.g

While I have only rudimentary programming skills, it seems to me that simply replacing that line by

    self.mat = Dictionary_to_Matrix(self.lt_dict, self.Ga)

will correct the problem with the transformation method .matrix(). The idea is that the multiplication of the incorrect matrix by Ga.g_inv effectively cancels out the multiplication by self.Ga.g.

Problem #2: If one applies the method .det() to an outermorphismf, strange things can happen. Look at the notebooks, other than g2.ipynb, in the attached zip file. Towards the end of each notebook one will see f.det() returning incorrect answers. Sometimes the correct answer is returned, sometimes a pseudoscalar is returned instead of the scalar which should be returned, and in one instance (hyperbolic plane, polar coordinates.ipynb) an answer is returned which multiplies the pseudoscalar by SymPy's unit imaginary i (geometric algebra doesn't use imaginary numbers, per se).

Solution for Problem #2: I have none. But I suspect the appearance of the unit imaginary arises with an incorrect computation of the unit pseudoscalar Ga.I(). That in turn may be linked to incorrect computation of a blade's norm. (I plan to post separately with regards to a multivector's norm-squared and norm.)

Greg Grunberg

Addendum: The Suggested Solution for Problem #1, described above, sort of worked. I made the change indicated in the suggestion. Afterwards f.matrix() would returned an answer in the form of a matrix with a transposition T as a superscript. Upon carrying out the indicated transposition, the desired standard matrix was obtained. I then restored the code for the method .matrix(), and then wrote a new method as follows:

def std_matrix(self) -> Matrix:
    r"""
    Returns the standard matrix representation :math:`\left[ {{f}^i}_{j} \right]` of 
    the linear transformation :math:`f`, with entries defined by the equations
    :math:`{{f}\lp {{{\eb}}_{j}} \rp} = {{\eb}}_{i} {{f}^i}_{j}`.
    """
    standard_matrix = self.matrix() * self.Ga.g_inv 
    return standard_matrix

Testing f.std_matrix() for all outermorphisms examined in then notebooks contained in the zip file, in each case the metric-independent standard matrix was returned.

Linear Transformations.zip

@Greg1950
Copy link
Contributor Author

The zip file I attached to my original post contained within it a file Euclidean 3-space, spherical coordinates.ipynb with some errors. The attached file corrects those errors.

Euclidean 3-space, spherical coordinates.zip

@eric-wieser
Copy link
Member

Thanks for the report. Here I think is a simpler reproduction (which is built on top of #454):

>>> from galgebra.ga import Ga
>>> g2 = Ga('e_x e_y', g=[1,1])
>>> g2a = Ga('e_x e_y', g=[[1, 0], [0, 2]])
>>> g2b = Ga('e_x e_y', g=[[0, 1], [1, 0]])

>>> g2.lt([[0, 2], [1, 1]]).matrix()  # note: this crashes until #454 is in
Matrix([
[0, 1],
[2, 1]])

>>> g2a.lt([[0, 2], [1, 1]]).matrix()
Matrix([
[0, 2],
[2, 2]])

>>> g2b.lt([[0, 2], [1, 1]]).matrix()
Matrix([
[1, 0],
[1, 2]])

to me, it looks like lt(list) is uniformly broken. You get what looks to me like correct behavior if you use lt(Matrix) instead:

>>> from sympy import Matrix
>>> g2.lt(Matrix([[0, 2], [1, 1]])).matrix()
Matrix([
[0, 2],
[1, 1]])
>>> g2a.lt(Matrix([[0, 2], [1, 1]])).matrix()
Matrix([
[0, 2],
[1, 1]])
>>> g2b.lt(Matrix([[0, 2], [1, 1]])).matrix()
Matrix([
[0, 2],
[1, 1]])

I think this only scratches the surface though. #158 is related.

@eric-wieser
Copy link
Member

#456 is also related.

@eric-wieser
Copy link
Member

You say in your notebooks:

disregard the L on the left side of the equations; each pair of equations corresponds to a different transformation):

Do you have a better suggestion for how to display the transformation without the confusing L?

@Greg1950
Copy link
Contributor Author

Greg1950 commented Sep 14, 2020 via email

@Greg1950
Copy link
Contributor Author

Greg1950 commented Sep 15, 2020 via email

@eric-wieser
Copy link
Member

eric-wieser commented Sep 15, 2020

Thanks @Greg1950, \mapsto sounds totally reasonable to me - I've gone ahead and made that change in #458

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants