|
| 1 | +Welcome to MultiVectors documentation! |
| 2 | + |
| 3 | +- [Concepts](#concepts) |
| 4 | + - [Bases and geometric products](#bases-and-geometric-products) |
| 5 | + - [Blades and multivectors](#blades-and-multivectors) |
| 6 | + - [The choose operator, inner (dot) and outer (wedge) products](#the-choose-operator-inner-dot-and-outer-wedge-products) |
| 7 | + - [Euler's formula applied to multivectors](#eulers-formula-applied-to-multivectors) |
| 8 | +- [Applied](#applied) |
| 9 | + - [Blade](#blade) |
| 10 | + - [MultiVector](#multivector) |
| 11 | + |
| 12 | +## Concepts |
| 13 | +Here are some concepts to bear in mind. This is a *very* brief introduction to geometric algebra; a longer one is [here](https://www.youtube.com/watch?v=60z_hpEAtD8). |
| 14 | + |
| 15 | +### Bases and geometric products |
| 16 | +* Every dimension of space comes with a *basis vector*: an arrow of length 1 unit pointed towards the positive end of the axis. |
| 17 | + * In our 3-dimensional world, there are the basis vectors *x̂*, *ŷ*, and *ẑ*, which are pointed towards the positive ends of the *x*, *y*, and *z* axes respectively. |
| 18 | + * The fourth dimensional basis vector is *ŵ*. In higher dimensions, usually all bases are numbered instead of lettered: the fifth dimensional basis vectors are *ê₁*, *ê₂*, *ê₃*, *ê₄*, and *ê₅*. |
| 19 | +* The *geometric product* of two basis vectors is their simple multiplication - not the dot or cross product! The geometric product of *x̂* and *ŷ* is simply *x̂ŷ*. |
| 20 | + * The geometric product of two basis vectors is a *basis plane*. *x̂ŷ* is the basis plane of the *x-y* plane. The other basis planes are *ŷẑ* and *x̂ẑ*. |
| 21 | + * The geometric product of three basis vectors is a *basis volume*. *x̂ŷẑ* is the basis volume of 3D space, which only has one basis volume, but also one of the four basis volumes of 4D space. |
| 22 | +* The geometric product of a basis vector with itself is 1. That is, *x̂x̂* = *x̂*² = *ŷŷ* = *ŷ*² = *ẑẑ* = *ẑ*² = 1 |
| 23 | +* The geometric product of different basis vectors *anticommutes*: *x̂ŷ* = -*ŷx̂* and *x̂ŷẑ* = -*x̂ẑŷ* = *ẑx̂ŷ* = -*ẑŷx̂* |
| 24 | + |
| 25 | +### Blades and multivectors |
| 26 | +* A *blade* is a *scaled basis*: a *scalar* (regular real number) multiplied by a *basis*. For example, 3*x̂ŷ* is a blade. Note that this means all bases are blades scaled by 1. |
| 27 | + * A *k-blade* is a blade of *grade k*: the geometric product of a scalar and *k* different basis vectors. 3*x̂ŷ* has grade 2; it is a 2-blade. |
| 28 | + * Scalars are 0-blades - blades consisting of *no* basis vectors. |
| 29 | +* A *multivector* is a sum of multiple blades. For example, 1 + 2*x̂* - 3*ŷẑ* is a multivector. |
| 30 | + * The sum of multiple (and only) 1-blades is usually called a simple *vector*. For example, 3*x̂* + 2*ŷ* is a vector. |
| 31 | + * The sum of multiple (and only) 2-blades is a *bivector*. Basis planes are also known as *basis bivectors*. For example, 3*x̂ŷ* is a bivector. |
| 32 | +* The rules of linearity, associativity and distributivity in multiplication apply, as long as order of arguments is maintained: |
| 33 | + * (*x̂*)(*aŷ*) = *ax̂ŷ* (linearity, for scalar *a*) |
| 34 | + * (*x̂ŷ*)*ẑ* = *x̂*(*ŷẑ*) (associativity) |
| 35 | + * *x̂*(*ŷ* + *ẑ*) = *x̂ŷ* + *x̂ẑ* (distributivity) |
| 36 | + * (*ŷ* + *ẑ*)(*ax̂*) = *a*(*ŷ* + *ẑ*)(*x̂*) (linearity) = a(*ŷx̂* + *ẑx̂*) (distributivity) = a(-*x̂ŷ* - *x̂ẑ*) (anticommutativity) |
| 37 | +* However, some things which require commutativity break down, such as the binomial theorem. |
| 38 | + |
| 39 | +### The choose operator, inner (dot) and outer (wedge) products |
| 40 | +* ⟨*V*⟩ₙ *chooses* all *n*-blades from the multivector *V*. For example, if *V* = 1 + 2*x̂* + 3*ŷ* + 4*x̂ŷ* + 5*ŷẑ*, then ⟨*V*⟩₀ = 1 and ⟨*V*⟩₁ = 2*x̂* + 3*ŷ* and ⟨*V*⟩₂ = 4*x̂ŷ* + 5*ŷẑ* |
| 41 | +* *U* · *V* = ⟨*UV*⟩ₙ where *U* is of grade *r*, *V* is of grade *s*, and *n* = |*r - s*|. This is the *inner* or *dot product*. |
| 42 | + * The dot product associates and distributes the same way the geometric product does. |
| 43 | + * From this, for arbitrary vectors *ax̂* + *bŷ* and *cx̂* + *dŷ*, we recover the typical meaning of the dot product:<br/> |
| 44 | +* *U* ∧ *V* = ⟨*UV*⟩ₙ where *U* is of grade *r*, *V* is of grade *s*, and *n* = *r + s*. This is the *outer* or *wedge product*. |
| 45 | + * The outer product associates and distributes the same way the geometric product does. |
| 46 | + * From this, for arbitrary vectors *ax̂* + *bŷ* + *cẑ* and *dx̂* + *eŷ* + *fẑ*, we recover something that looks very much like a cross product:<br/> |
| 47 | + |
| 48 | +### Euler's formula applied to multivectors |
| 49 | +* *e* to the power (*θB*) = cos(*θ*) + *B* sin(*θ*) where θ is a scalar in radians and *B* is a basis multivector. |
| 50 | +* For reasons that are beyond my power to explain, the rotation of a multivector *V* by *θ* through the plane *B* is e\*\*(-*θB*/2) * V * e\*\*(*θB*/2) |
| 51 | + |
| 52 | +## Applied |
| 53 | +All of the above concepts are applied in this library. |
| 54 | + |
| 55 | +### Blade |
| 56 | +* `multivectors.Blade(*bases, scalar=a)` represents a blade with **0-indexed bases** `bases` multiplied by a real scalar `a`. For example, `Blade(0, 1, 3)` represents the basis volume *x̂ŷŵ*, with 0 meaning *x̂*. |
| 57 | +* Basis names can be *swizzled* on the `Blade` class itself: the above could have been done with `Blade.xyw`. For basis vectors beyond *ŵ*, use *ê*ₙ: `Blade.e1e3e4e5` is a basis 4-vector in 5D space. `Blade._` is a 0-blade: a scalar, but with `Blade` type. |
| 58 | +* Basis indices can also be used: `Blade[:4]` = `Blade[0, 1, 2, 3]` = `Blade(0, 1, 2, 3)` = `Blade.xyzw` |
| 59 | +* To take it one step further, basis names can be swizzled on the module itself: `multivector.xyz` returns `multivectors.Blade.xyz`. This also works when importing: `from multivectors import x, y, z, xy, xz, yz` will work just fine. |
| 60 | +* The rules of arithmetic with blades as described above apply: |
| 61 | +```python |
| 62 | +>>> from multivectors import x, y, z |
| 63 | +>>> x * 2 + x * 3 |
| 64 | +5.0 * Blade.x |
| 65 | +>>> x * 5 * y |
| 66 | +5.0 * Blade.xy |
| 67 | +>>> (x * y) * z == x * (y * z) |
| 68 | +True |
| 69 | + |
| 70 | +``` |
| 71 | +* You can query the grade of a blade: `Blade.xy.grade` is 2. |
| 72 | + |
| 73 | +### MultiVector |
| 74 | +* `multivectors.MultiVector.from_terms(*terms)` represents a **sum of `terms`**. You normally should not be constructing this class; it is created from summation involving `Blade`s. |
| 75 | +* Basis names can be swizzled on class **instances** to get the coefficient of that basis: |
| 76 | +```python |
| 77 | +>>> from multivectors import x, y |
| 78 | +>>> (x + 2*y).x |
| 79 | +1.0 |
| 80 | + |
| 81 | +``` |
| 82 | +* Basis indices can also be used: |
| 83 | +```python |
| 84 | +>>> from multivectors import xy, yz |
| 85 | +>>> (xy + 2*yz)[0, 1] |
| 86 | +1.0 |
| 87 | + |
| 88 | +``` |
| 89 | +* Choosing by grade is supported: |
| 90 | +```python |
| 91 | +>>> from multivectors import x, y, xy, yz |
| 92 | +>>> V = 1 + 2*x + 3*y + 4*xy + 5*yz |
| 93 | +>>> V % 0 |
| 94 | +1.0 |
| 95 | +>>> V % 1 |
| 96 | +(2.0 * Blade.x + 3.0 * Blade.y) |
| 97 | +>>> V % 2 |
| 98 | +(4.0 * Blade.xy + 5.0 * Blade.yz) |
| 99 | + |
| 100 | +``` |
| 101 | +* The rules of arithmetic with multivectors as described above apply: |
| 102 | +```python |
| 103 | +>>> from multivectors import x, y, z |
| 104 | +>>> x * (y + z) |
| 105 | +(1.0 * Blade.xy + 1.0 * Blade.xz) |
| 106 | +>>> (y + z) * (2 * x) |
| 107 | +(-2.0 * Blade.xy + -2.0 * Blade.xz) |
| 108 | +>>> (1*x + 2*y) * (3*x + 4*y) |
| 109 | +(11.0 + -2.0 * Blade.xy) |
| 110 | + |
| 111 | +``` |
| 112 | +* The extra products apply too: |
| 113 | +```python |
| 114 | +>>> from multivectors import x, y, z |
| 115 | +>>> 1*3 + 2*4 |
| 116 | +11 |
| 117 | +>>> (1*x + 2*y) @ (3*x + 4*y) |
| 118 | +11.0 |
| 119 | +>>> (1*5 - 2*4, 1*6 - 3*4, 2*6 - 3*5) |
| 120 | +(-3, -6, -3) |
| 121 | +>>> (1*x + 2*y + 3*z) ^ (4*x + 5*y + 6*z) |
| 122 | +(-3.0 * Blade.xy + -6.0 * Blade.xz + -3.0 * Blade.yz) |
| 123 | + |
| 124 | +``` |
| 125 | +* A convenience method is provided to rotate multivectors: |
| 126 | +```python |
| 127 | +>>> from math import radians |
| 128 | +>>> from multivectors import x, y, z, xz |
| 129 | +>>> round((3*x + 2*y + 4*z).rotate(radians(90), xz), 2) |
| 130 | +(-4.0 * Blade.x + 2.0 * Blade.y + 3.0 * Blade.z) |
| 131 | + |
| 132 | +``` |
0 commit comments