Created
November 5, 2021 14:04
-
-
Save arsenovic/b9cb44796a4d54e25ea3704a00f65cb8 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"cells": [ | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"# The Cross Ratio in GA, a Lorentz Invariant " | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"This notebook gives a formula for the complex cross-ratio in Conformal Geometric Algebra (CGA) and a numerical proof that it is equilent to the conventional complex form. Previous authors have given the cross ratio only for colinear points[1], while it is known that the cross ratio is a conformal invariant for any four points in the complex plane. The GA-version of the cross-ratio of four vectors can be interpreted as a Lorentz invariant.\n", | |
"\n", | |
"*[1] \"The design of linear algebra and geometry\", David Hestenes*\n", | |
"\n", | |
"### Invariance \n", | |
"\n", | |
"Given a set of 4 vectors in STA, $(a,b,c,d)$ which are transformed by a lorentz transformation $R$ into $(w,x,y,z)$ as \n", | |
"\n", | |
"$$(w,x,y,z) = R(a,b,c,d)\\tilde{R}$$\n", | |
"\n", | |
"the function \n", | |
"\n", | |
"$$f(a,b,c,d)\\equiv 1 + \\frac{\\langle acdb\\rangle _{(0,4)}}{\\langle adcb\\rangle_{ (0,4)}}$$\n", | |
"\n", | |
"is a lorentz invariant, meaning, \n", | |
"$$f(a,b,c,d) =f(w,x,y,z) $$\n", | |
"\n", | |
"This is obvious due to the commutation relations of scalars and psuedoscalars in the algebra. What is less obvious is that this expression is equivalent to the cross-ratio in complex algebra. \n", | |
"\n", | |
"### Equivalence\n", | |
"It is justifiable to call this function $f$ the cross ratio because this function produces the same values as the complex cross-ratio, when computed in CGA for the plane. This means given four complex numbers $(a,b,c,d)$, this set can be converted to vectors in $G_2$, then up-projected into null vectors in CGA, $G_{3,1}$. The cross ratio defined above can be computed, which yields a scalar+psuedoscalar. This invariant can be mapped directly back onto the complex plane, and the result is equivalent to the classic cross-ratio. \n", | |
"\n", | |
"$$ \\text{d2c} (f(\\uparrow(\\text{c2v}(a,b,c,d)) = \\frac{(a-b)(c-d)}{(a-d)(c-b)}$$\n", | |
"\n", | |
"where c2v() is complex-to-vector, and d2c() is duality-to-complex, and $\\uparrow$() is the standard CGA mapping of a vector up into CGA.\n", | |
"\n", | |
"\n", | |
"$$ \\text{c2v}(z)\\equiv \\text{Re}(z)e_1 + \\text{Im} (z)e_2 $$\n", | |
"$$ \\text{d2c}(Z)\\equiv \\langle Z\\rangle_{0} + \\langle Z\\rangle_{ 4}j $$\n", | |
"\n", | |
"\n", | |
"### Another form \n", | |
"Another form for the cross-ratio which is equivalent to the complex version, can be found by using the projective split. \n", | |
" \n", | |
"\n", | |
"$$ f(a,b,c,d) = \\frac{1}{2}(1- \\frac{a\\wedge d}{a \\cdot d} \\frac{b\\wedge c}{b \\cdot c}) = \\frac{1}{2}(1-B_{ad}B_{cd}) $$\n", | |
"\n", | |
"Where $B_{ad}$ and $B_{cd}$ are bivectors generated from the split between the vectors in their subscripts. \n", | |
"\n" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"## Numerical Proof with [clifford](https://clifford.readthedocs.io/en/latest/)\n", | |
"\n", | |
"### invariance" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 9, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"(0.65711 - (0.00198^d0123), 0.65711 - (0.00198^d0123))" | |
] | |
}, | |
"execution_count": 9, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"from pylab import * \n", | |
"from clifford.sta import * # imports the spacetime algebra\n", | |
"isclose = lambda x,y:abs(x-y)< 1e-9 # numerical test for equality\n", | |
"I = d0123\n", | |
"\n", | |
"\n", | |
"def cr_ga(a,b,c,d):\n", | |
" '''cross ration in GA'''\n", | |
" return 1+(a*c*d*b)(0,4)/(a*d*c*b)(0,4)\n", | |
"\n", | |
"\n", | |
"abcd = D.randomV(4) # 4 random vectors \n", | |
"R = e**(D.randomMV()(2)) # exponentiate a random bivector, to create `R`\n", | |
"wxyz = [R*k*~R for k in abcd] # (w,x,y,z) = R(a,b,c,d)~R \n", | |
"cr_ga(*abcd), cr_ga(*wxyz) # compute cross-ratio for both vector sets" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 10, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"assert(isclose( cr_ga(*abcd), cr_ga(*wxyz)))" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"### Equivalence \n", | |
"A proof that the GA-version of the cross ratio defined above, `cr_ga`, is equivalent to the conventional cross ratio of complex analysis. \n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 21, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"(7.098834917399649-2.457553146316387j)" | |
] | |
}, | |
"execution_count": 21, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"import numpy as np\n", | |
"from clifford.cga import CGA\n", | |
"from numpy.random import rand \n", | |
"\n", | |
"N=2\n", | |
"cga = CGA(N)\n", | |
"locals().update(cga.blades)\n", | |
"\n", | |
"v2c = lambda x: float(x|e1) + float(x|e2)*1j\n", | |
"d2c = lambda x: float(x(0)) + float(x|x.pseudoScalar)*1j\n", | |
"c2v = lambda x: x.real*e1 + x.imag*e2\n", | |
"\n", | |
" \n", | |
"def cr(a,b,c,d):\n", | |
" '''The traditional cross ratio'''\n", | |
" return (a-b)*(c-d)/((a-d)*(c-b))\n", | |
"\n", | |
"abcd = rand(4) + rand(4)*1j \n", | |
"cr(*abcd)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 22, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"(7.098834917399661-2.4575531463163727j)" | |
] | |
}, | |
"execution_count": 22, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"# as read from inside-out:\n", | |
"# convert complex to vector, up-project into cga, compute cr_ga, convert duality to complex\n", | |
"d2c(cr_ga(*map(cga.up, map(c2v, abcd))))" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 23, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"assert(isclose(d2c(cr_ga(*map(cga.up, map(c2v, abcd)))), cr(*abcd)))" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"### Other Form, using a split " | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 24, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"(7.098834917399595-2.4575531463163713j)" | |
] | |
}, | |
"execution_count": 24, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"split = lambda Z,x,y: (Z[x]^Z[y])/float((Z[x]|Z[y])(0))\n", | |
"a = list(map(cga.up, map(c2v, abcd)))\n", | |
"Ai = split(a,0,3)\n", | |
"Aj = split(a,1,2)\n", | |
"d2c(.5*(1 - Ai*Aj)(0,4)).conjugate() " | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 25, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"assert(isclose(d2c(.5*(1 - Ai*Aj)(0,4)).conjugate(), cr(*abcd)))" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [] | |
} | |
], | |
"metadata": { | |
"kernelspec": { | |
"display_name": "Python 3", | |
"language": "python", | |
"name": "python3" | |
}, | |
"language_info": { | |
"codemirror_mode": { | |
"name": "ipython", | |
"version": 3 | |
}, | |
"file_extension": ".py", | |
"mimetype": "text/x-python", | |
"name": "python", | |
"nbconvert_exporter": "python", | |
"pygments_lexer": "ipython3", | |
"version": "3.8.8" | |
}, | |
"toc": { | |
"nav_menu": {}, | |
"number_sections": true, | |
"sideBar": true, | |
"skip_h1_title": false, | |
"toc_cell": false, | |
"toc_position": {}, | |
"toc_section_display": "block", | |
"toc_window_display": false | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 4 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment