Geometric algebra: Difference between revisions

Added FreeBASIC
(Added FreeBASIC)
 
(38 intermediate revisions by 11 users not shown)
Line 1:
{{draft task}}
 
'''Geometric algebra''' is an otheranother name for [[wp:Clifford algebra|Clifford algebra]]s and it's basically an algebra containing a vector space <math>\mathcal{V}</math> and obeying the following axioms:
 
:<math>\begin{array}{c}
Line 13:
The product operation in such algebra is called the ''geometric product''. Elements are called ''multivectors'', while multivectors in <math>\mathcal{V}</math> are just called ''vectors''.
 
There are a few simple examples of geometric algebras. A trivial one for instance is simply <math>\R</math>, where <math>\mathcal{V} = \R</math>. The complex numbers also form a geometric algebra, where the vector space is the one-dimensional space of all purely imaginary numbers. An otherAnother example is the space of [[Quaternion type|quaternions]], where the vector space is the three-dimensional space of all linear combinations of <math>(i, j, k)</math>.
 
The purpose of this task is to implement a geometric algebra with a vector space <math>\mathcal{V}</math> of dimension ''n'' of at least five, but for extra-credit you can implement a version with ''n'' arbitrary large. Using a dimension five is useful as it is the dimension required for the so-called ''conformal model'' which will be the subject of a derived task.
Line 49:
* verify the axioms for three rarndom multivectors ''a'', ''b'', ''c'' and a random vector '''x'''.
 
<br>
Optionally, you will repeat the last step a large number of times, in order to increase confidence in the result.
<br><br>
 
=={{header|C sharp|C#}}==
{{trans|D}}
<syntaxhighlight lang="csharp">using System;
using System.Text;
 
namespace GeometricAlgebra {
struct Vector {
private readonly double[] dims;
 
public Vector(double[] da) {
dims = da;
}
 
public static Vector operator -(Vector v) {
return v * -1.0;
}
 
public static Vector operator +(Vector lhs, Vector rhs) {
var result = new double[32];
Array.Copy(lhs.dims, 0, result, 0, lhs.Length);
for (int i = 0; i < result.Length; i++) {
result[i] = lhs[i] + rhs[i];
}
return new Vector(result);
}
 
public static Vector operator *(Vector lhs, Vector rhs) {
var result = new double[32];
for (int i = 0; i < lhs.Length; i++) {
if (lhs[i] != 0.0) {
for (int j = 0; j < lhs.Length; j++) {
if (rhs[j] != 0.0) {
var s = ReorderingSign(i, j) * lhs[i] * rhs[j];
var k = i ^ j;
result[k] += s;//there is an index out of bounds here
}
}
}
}
return new Vector(result);
}
 
public static Vector operator *(Vector v, double scale) {
var result = (double[])v.dims.Clone();
for (int i = 0; i < result.Length; i++) {
result[i] *= scale;
}
return new Vector(result);
}
 
public double this[int key] {
get {
return dims[key];
}
 
set {
dims[key] = value;
}
}
 
public int Length {
get {
return dims.Length;
}
}
 
public Vector Dot(Vector rhs) {
return (this * rhs + rhs * this) * 0.5;
}
 
private static int BitCount(int i) {
i -= ((i >> 1) & 0x55555555);
i = (i & 0x33333333) + ((i >> 2) & 0x33333333);
i = (i + (i >> 4)) & 0x0F0F0F0F;
i += (i >> 8);
i += (i >> 16);
return i & 0x0000003F;
}
 
private static double ReorderingSign(int i, int j) {
int k = i >> 1;
int sum = 0;
while (k != 0) {
sum += BitCount(k & j);
k >>= 1;
}
return ((sum & 1) == 0) ? 1.0 : -1.0;
}
 
public override string ToString() {
var it = dims.GetEnumerator();
 
StringBuilder sb = new StringBuilder("[");
if (it.MoveNext()) {
sb.Append(it.Current);
}
while (it.MoveNext()) {
sb.Append(", ");
sb.Append(it.Current);
}
 
sb.Append(']');
return sb.ToString();
}
}
 
class Program {
static double[] DoubleArray(uint size) {
double[] result = new double[size];
for (int i = 0; i < size; i++) {
result[i] = 0.0;
}
return result;
}
 
static Vector E(int n) {
if (n > 4) {
throw new ArgumentException("n must be less than 5");
}
 
var result = new Vector(DoubleArray(32));
result[1 << n] = 1.0;
return result;
}
 
static readonly Random r = new Random();
 
static Vector RandomVector() {
var result = new Vector(DoubleArray(32));
for (int i = 0; i < 5; i++) {
var singleton = new double[] { r.NextDouble() };
result += new Vector(singleton) * E(i);
}
return result;
}
 
static Vector RandomMultiVector() {
var result = new Vector(DoubleArray(32));
for (int i = 0; i < result.Length; i++) {
result[i] = r.NextDouble();
}
return result;
}
 
static void Main() {
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
if (i < j) {
if (E(i).Dot(E(j))[0] != 0.0) {
Console.WriteLine("Unexpected non-null sclar product.");
return;
}
} else if (i == j) {
if ((E(i).Dot(E(j)))[0] == 0.0) {
Console.WriteLine("Unexpected null sclar product.");
}
}
}
}
 
var a = RandomMultiVector();
var b = RandomMultiVector();
var c = RandomMultiVector();
var x = RandomVector();
 
// (ab)c == a(bc)
Console.WriteLine((a * b) * c);
Console.WriteLine(a * (b * c));
Console.WriteLine();
 
// a(b+c) == ab + ac
Console.WriteLine(a * (b + c));
Console.WriteLine(a * b + a * c);
Console.WriteLine();
 
// (a+b)c == ac + bc
Console.WriteLine((a + b) * c);
Console.WriteLine(a * c + b * c);
Console.WriteLine();
 
// x^2 is real
Console.WriteLine(x * x);
}
}
}</syntaxhighlight>
{{out}}
<pre>[-2.7059639813936, -2.65443237395364, -1.03355975191747, 5.431067101183, 9.57183741787636, 7.41390675997241, -8.09043009371666, -7.30180304927878, -1.50642825479215, -4.14594595273162, -1.78857280373918, -0.484382016930444, -7.42401696794793, -4.78491995868705, -8.43252648860165, -4.47485336471182, -2.3458119817208, 3.6184495826099, -7.50802924695147, -2.10106278080463, 7.15782745037037, 7.60049996423655, -10.6945339837475, -6.9874232887485, -4.85603010723139, -9.8225346377117, 3.50534384939214, 3.08239272713895, -9.92019737517891, -10.1065306142574, -8.79795495448311, -4.01442257971653]
[-2.70596398139361, -2.65443237395364, -1.03355975191747, 5.43106710118299, 9.57183741787636, 7.41390675997241, -8.09043009371666, -7.30180304927878, -1.50642825479215, -4.14594595273162, -1.78857280373917, -0.484382016930444, -7.42401696794793, -4.78491995868705, -8.43252648860165, -4.47485336471182, -2.3458119817208, 3.6184495826099, -7.50802924695147, -2.10106278080463, 7.15782745037036, 7.60049996423655, -10.6945339837475, -6.9874232887485, -4.85603010723139, -9.8225346377117, 3.50534384939214, 3.08239272713894, -9.9201973751789, -10.1065306142574, -8.79795495448311, -4.01442257971653]
 
[-5.35792362178344, -2.83992055857095, -0.00435065203934659, 0.548701864561436, 7.31905167177133, 2.98280880755406, 2.54042778638867, -1.82513292511705, -4.07944497473881, -3.87206774796269, 2.05320674506366, 1.00599045579458, -3.72912260067605, -3.4226426940923, 1.62806109332525, 3.26554642532303, -2.2232872618717, -2.06401927877361, 3.31046340349916, 3.21397515180161, 4.84963949791875, 1.98923326842668, 2.28775873178049, -0.927084258496161, -3.99100687576943, -1.67065148926557, 2.70438629346319, 0.400654313359669, -0.74522009023782, 0.737528754412463, 4.53246775536051, 5.82111882775243]
[-5.35792362178344, -2.83992055857095, -0.0043506520393467, 0.548701864561437, 7.31905167177133, 2.98280880755406, 2.54042778638867, -1.82513292511705, -4.0794449747388, -3.87206774796269, 2.05320674506366, 1.00599045579458, -3.72912260067605, -3.4226426940923, 1.62806109332525, 3.26554642532303, -2.2232872618717, -2.06401927877361, 3.31046340349916, 3.21397515180161, 4.84963949791875, 1.98923326842668, 2.28775873178049, -0.92708425849616, -3.99100687576943, -1.67065148926557, 2.70438629346319, 0.40065431335967, -0.745220090237821, 0.737528754412463, 4.53246775536051, 5.82111882775243]
 
[-6.85152530876464, -2.6466613868296, -0.814269203555543, -2.63807771948643, 6.89540453623166, 4.70804372948965, 2.78512631505336, 2.03877626337364, -1.77047482836463, 1.52836763170898, 0.71565745873906, 0.886707645932111, -2.25661460785133, -1.08891196061849, 3.44949857952115, 5.8645384965889, -3.09249704978979, -1.41518183096078, 1.87603297737169, 2.45042504250642, 3.66908389117503, 1.85358883025892, 1.23206155683761, -0.216105143607701, -1.88866851071821, -0.131570581491294, 5.7355274883507, 4.22029797577044, -0.212906215521922, -0.323884694190184, 4.41630150883192, 5.94513377054442]
[-6.85152530876464, -2.6466613868296, -0.814269203555542, -2.63807771948643, 6.89540453623166, 4.70804372948965, 2.78512631505335, 2.03877626337364, -1.77047482836463, 1.52836763170898, 0.715657458739061, 0.886707645932111, -2.25661460785133, -1.08891196061849, 3.44949857952115, 5.8645384965889, -3.09249704978979, -1.41518183096078, 1.87603297737169, 2.45042504250642, 3.66908389117503, 1.85358883025892, 1.23206155683761, -0.216105143607701, -1.88866851071821, -0.131570581491294, 5.7355274883507, 4.22029797577044, -0.212906215521922, -0.323884694190183, 4.41630150883192, 5.94513377054442]
 
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]</pre>
 
=={{header|C++}}==
{{trans|D}}
<syntaxhighlight lang="cpp">#include <algorithm>
#include <iostream>
#include <random>
#include <vector>
 
double uniform01() {
static std::default_random_engine generator;
static std::uniform_real_distribution<double> distribution(0.0, 1.0);
return distribution(generator);
}
 
int bitCount(int i) {
i -= ((i >> 1) & 0x55555555);
i = (i & 0x33333333) + ((i >> 2) & 0x33333333);
i = (i + (i >> 4)) & 0x0F0F0F0F;
i += (i >> 8);
i += (i >> 16);
return i & 0x0000003F;
}
 
double reorderingSign(int i, int j) {
int k = i >> 1;
int sum = 0;
while (k != 0) {
sum += bitCount(k & j);
k = k >> 1;
}
return ((sum & 1) == 0) ? 1.0 : -1.0;
}
 
struct MyVector {
public:
MyVector(const std::vector<double> &da) : dims(da) {
// empty
}
 
double &operator[](size_t i) {
return dims[i];
}
 
const double &operator[](size_t i) const {
return dims[i];
}
 
MyVector operator+(const MyVector &rhs) const {
std::vector<double> temp(dims);
for (size_t i = 0; i < rhs.dims.size(); ++i) {
temp[i] += rhs[i];
}
return MyVector(temp);
}
 
MyVector operator*(const MyVector &rhs) const {
std::vector<double> temp(dims.size(), 0.0);
for (size_t i = 0; i < dims.size(); i++) {
if (dims[i] != 0.0) {
for (size_t j = 0; j < dims.size(); j++) {
if (rhs[j] != 0.0) {
auto s = reorderingSign(i, j) * dims[i] * rhs[j];
auto k = i ^ j;
temp[k] += s;
}
}
}
}
return MyVector(temp);
}
 
MyVector operator*(double scale) const {
std::vector<double> temp(dims);
std::for_each(temp.begin(), temp.end(), [scale](double a) { return a * scale; });
return MyVector(temp);
}
 
MyVector operator-() const {
return *this * -1.0;
}
 
MyVector dot(const MyVector &rhs) const {
return (*this * rhs + rhs * *this) * 0.5;
}
 
friend std::ostream &operator<<(std::ostream &, const MyVector &);
 
private:
std::vector<double> dims;
};
 
std::ostream &operator<<(std::ostream &os, const MyVector &v) {
auto it = v.dims.cbegin();
auto end = v.dims.cend();
 
os << '[';
if (it != end) {
os << *it;
it = std::next(it);
}
while (it != end) {
os << ", " << *it;
it = std::next(it);
}
return os << ']';
}
 
MyVector e(int n) {
if (n > 4) {
throw new std::runtime_error("n must be less than 5");
}
 
auto result = MyVector(std::vector<double>(32, 0.0));
result[1 << n] = 1.0;
return result;
}
 
MyVector randomVector() {
auto result = MyVector(std::vector<double>(32, 0.0));
for (int i = 0; i < 5; i++) {
result = result + MyVector(std::vector<double>(1, uniform01())) * e(i);
}
return result;
}
 
MyVector randomMultiVector() {
auto result = MyVector(std::vector<double>(32, 0.0));
for (int i = 0; i < 32; i++) {
result[i] = uniform01();
}
return result;
}
 
int main() {
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
if (i < j) {
if (e(i).dot(e(j))[0] != 0.0) {
std::cout << "Unexpected non-null scalar product.";
return 1;
} else if (i == j) {
if (e(i).dot(e(j))[0] == 0.0) {
std::cout << "Unexpected null scalar product.";
}
}
}
}
}
 
auto a = randomMultiVector();
auto b = randomMultiVector();
auto c = randomMultiVector();
auto x = randomVector();
 
// (ab)c == a(bc)
std::cout << ((a * b) * c) << '\n';
std::cout << (a * (b * c)) << "\n\n";
 
// a(b+c) == ab + ac
std::cout << (a * (b + c)) << '\n';
std::cout << (a * b + a * c) << "\n\n";
 
// (a+b)c == ac + bc
std::cout << ((a + b) * c) << '\n';
std::cout << (a * c + b * c) << "\n\n";
 
// x^2 is real
std::cout << (x * x) << '\n';
 
return 0;
}</syntaxhighlight>
{{out}}
<pre>[-5.63542, -6.59107, -10.2043, -5.21095, 8.68946, 0.579114, -4.67295, -6.72461, 1.55005, -2.63952, -1.83855, 2.4967, -4.3396, -9.9157, -4.6942, -3.23625, -2.3767, -4.55607, -14.3135, -14.2001, 9.84839, 3.69933, -3.38306, -7.60063, -0.236772, 0.988399, -0.549176, 6.61959, 4.69712, -5.34606, -12.2294, -12.6537]
[-5.63542, -6.59107, -10.2043, -5.21095, 8.68946, 0.579114, -4.67295, -6.72461, 1.55005, -2.63952, -1.83855, 2.4967, -4.3396, -9.9157, -4.6942, -3.23625, -2.3767, -4.55607, -14.3135, -14.2001, 9.84839, 3.69933, -3.38306, -7.60063, -0.236772, 0.988399, -0.549176, 6.61959, 4.69712, -5.34606, -12.2294, -12.6537]
 
[-6.27324, -6.7904, 3.10486, -1.14265, 6.38677, 3.57612, -3.90542, -4.17752, -1.36656, -0.0780159, 6.77775, 6.39118, 1.5939, 1.04175, 8.18152, 2.72047, -3.59085, -5.1028, 2.62711, -1.41586, 5.84934, 4.25817, 1.1197, 0.123976, -2.04301, -1.81806, 4.87518, 6.67182, 2.91358, 0.252558, 6.15595, 1.1159]
[-6.27324, -6.7904, 3.10486, -1.14265, 6.38677, 3.57612, -3.90542, -4.17752, -1.36656, -0.0780159, 6.77775, 6.39118, 1.5939, 1.04175, 8.18152, 2.72047, -3.59085, -5.1028, 2.62711, -1.41586, 5.84934, 4.25817, 1.1197, 0.123976, -2.04301, -1.81806, 4.87518, 6.67182, 2.91358, 0.252558, 6.15595, 1.1159]
 
[-7.29133, -8.2555, 0.985588, -1.48171, 2.4995, 4.5152, -1.1938, -2.29702, -2.34025, -2.16526, 10.2208, 7.0629, 0.552639, -0.437582, 7.18962, 2.63274, -3.25348, -4.07006, -0.883786, -3.09677, 1.1018, 2.91198, -0.0095405, 0.0123323, -2.69156, -1.30815, 3.36179, 3.26852, 3.09518, -0.166247, 6.74016, 3.20827]
[-7.29133, -8.2555, 0.985588, -1.48171, 2.4995, 4.5152, -1.1938, -2.29702, -2.34025, -2.16526, 10.2208, 7.0629, 0.552639, -0.437582, 7.18962, 2.63274, -3.25348, -4.07006, -0.883786, -3.09677, 1.1018, 2.91198, -0.0095405, 0.0123323, -2.69156, -1.30815, 3.36179, 3.26852, 3.09518, -0.166247, 6.74016, 3.20827]
 
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]</pre>
 
=={{header|D}}==
{{trans|Kotlin}}
<syntaxhighlight lang="d">import std.exception;
import std.random;
import std.stdio;
 
auto doubleArray(size_t size) {
double[] result;
result.length = size;
result[] = 0.0;
return result;
}
 
int bitCount(int i) {
i -= ((i >> 1) & 0x55555555);
i = (i & 0x33333333) + ((i >> 2) & 0x33333333);
i = (i + (i >> 4)) & 0x0F0F0F0F;
i += (i >> 8);
i += (i >> 16);
return i & 0x0000003F;
}
 
double reorderingSign(int i, int j) {
int k = i >> 1;
int sum = 0;
while (k != 0) {
sum += bitCount(k & j);
k = k >> 1;
}
return ((sum & 1) == 0) ? 1.0 : -1.0;
}
 
struct Vector {
private double[] dims;
 
this(double[] da) {
dims = da;
}
 
Vector dot(Vector rhs) {
return (this * rhs + rhs * this) * 0.5;
}
 
Vector opUnary(string op : "-")() {
return this * -1.0;
}
 
Vector opBinary(string op)(Vector rhs) {
import std.algorithm.mutation : copy;
static if (op == "+") {
auto result = doubleArray(32);
copy(dims, result);
foreach (i; 0..rhs.dims.length) {
result[i] += rhs[i];
}
return Vector(result);
} else if (op == "*") {
auto result = doubleArray(32);
foreach (i; 0..dims.length) {
if (dims[i] != 0.0) {
foreach (j; 0..dims.length) {
if (rhs[j] != 0.0) {
auto s = reorderingSign(i, j) * dims[i] * rhs[j];
auto k = i ^ j;
result[k] += s;
}
}
}
}
return Vector(result);
} else {
assert(false);
}
}
 
Vector opBinary(string op : "*")(double scale) {
auto result = dims.dup;
foreach (i; 0..5) {
dims[i] = dims[i] * scale;
}
return Vector(result);
}
 
double opIndex(size_t i) {
return dims[i];
}
 
void opIndexAssign(double value, size_t i) {
dims[i] = value;
}
}
 
Vector e(int n) {
enforce(n <= 4, "n must be less than 5");
 
auto result = Vector(doubleArray(32));
result[1 << n] = 1.0;
return result;
}
 
Vector randomVector() {
auto result = Vector(doubleArray(32));
foreach (i; 0..5) {
result = result + Vector([uniform01()]) * e(i);
}
return result;
}
 
Vector randomMultiVector() {
auto result = Vector(doubleArray(32));
foreach (i; 0..32) {
result[i] = uniform01();
}
return result;
}
 
void main() {
foreach (i; 0..5) {
foreach (j; 0..5) {
if (i < j) {
if ((e(i).dot(e(j)))[0] != 0.0) {
writeln("Unexpected non-null scalar product.");
return;
} else if (i == j) {
if ((e(i).dot(e(j)))[0] == 0.0) {
writeln("Unexpected null scalar product.");
}
}
}
}
}
 
auto a = randomMultiVector();
auto b = randomMultiVector();
auto c = randomMultiVector();
auto x = randomVector();
 
// (ab)c == a(bc)
writeln((a * b) * c);
writeln(a * (b * c));
writeln;
 
// a(b+c) == ab + ac
writeln(a * (b + c));
writeln(a * b + a * c);
writeln;
 
// (a+b)c == ac + bc
writeln((a + b) * c);
writeln(a * c + b * c);
writeln;
 
// x^2 is real
writeln(x * x);
}</syntaxhighlight>
{{out}}
<pre>Vector([-4.60357, -1.66951, 0.230125, -4.36372, 11.0032, 7.21226, -1.5373, -6.44947, -5.07115, -1.63098, 2.90828, 7.1582, -15.5565, -1.31705, 1.3186, -1.07552, -4.04055, -2.16556, -4.41229, 0.323326, 5.03127, -1.36494, -0.915379, -6.86147, -5.87756, -4.31528, 12.4005, 15.6349, -9.54983, -1.08376, 3.60886, 4.17844])
Vector([-4.60357, -1.66951, 0.230125, -4.36372, 11.0032, 7.21226, -1.5373, -6.44947, -5.07115, -1.63098, 2.90828, 7.1582, -15.5565, -1.31705, 1.3186, -1.07552, -4.04055, -2.16556, -4.41229, 0.323326, 5.03127, -1.36494, -0.915379, -6.86147, -5.87756, -4.31528, 12.4005, 15.6349, -9.54983, -1.08376, 3.60886, 4.17844])
 
Vector([-3.70178, 0.430038, -3.1952, -0.878759, 2.91374, 4.86224, 3.52303, 1.66396, -0.847575, -2.11591, 1.3121, 4.42268, -3.80298, -0.773252, 5.63781, 4.70647, -2.50968, 0.196386, -1.51296, 1.92306, 2.38331, 3.00232, 4.1991, -0.254381, 0.112317, 1.53895, 2.74983, 7.70699, 0.00697711, 0.785638, 7.04352, 3.94291])
Vector([-3.70178, 0.430038, -3.1952, -0.878759, 2.91374, 4.86224, 3.52303, 1.66396, -0.847575, -2.11591, 1.3121, 4.42268, -3.80298, -0.773252, 5.63781, 4.70647, -2.50968, 0.196386, -1.51296, 1.92306, 2.38331, 3.00232, 4.1991, -0.254381, 0.112317, 1.53895, 2.74983, 7.70699, 0.00697711, 0.785638, 7.04352, 3.94291])
 
Vector([-4.49501, 0.40722, -3.84594, -0.429832, 6.94562, 7.06166, 1.99871, 2.27987, 0.153668, 0.16586, 1.44596, 3.74806, -3.1458, -2.35553, 3.87377, 7.18143, -2.17737, 0.987571, -1.47633, 3.38, 2.24917, 2.68417, 1.81881, 0.886526, 1.28089, 1.63795, 7.06364, 8.61935, 2.78735, -0.226174, 3.83569, 2.1715])
Vector([-4.49501, 0.40722, -3.84594, -0.429832, 6.94562, 7.06166, 1.99871, 2.27987, 0.153668, 0.16586, 1.44596, 3.74806, -3.1458, -2.35553, 3.87377, 7.18143, -2.17737, 0.987571, -1.47633, 3.38, 2.24917, 2.68417, 1.81881, 0.886526, 1.28089, 1.63795, 7.06364, 8.61935, 2.78735, -0.226174, 3.83569, 2.1715])
 
Vector([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])</pre>
 
=={{header|EchoLisp}}==
We build a CGA based upon a generationggenerating quadratic form in R^n. The implementation is general enough, that is ei*ei = +/- 1 , and not restricted to 1. The 5 dimension limit comes from the use of 32 bits numbers to generate all permutations 101... , but this could be improved. The multi-vector multiplication is based on a multiplication table 2^n * 2^n , generated once for all.
 
<langsyntaxhighlight lang="scheme">
(define e-bits (build-vector 32 (lambda(i) (arithmetic-shift 1 i)))) ;; 1,2,4,..
(define (e-index i) ;; index of ei in native vector
Line 167 ⟶ 715:
</syntaxhighlight>
</lang>
{{out}}
<langsyntaxhighlight lang="scheme">
;; we use indices (1 ... n) in conformity with the Wikipedia reference
 
Line 219 ⟶ 767:
(• II J K) → -1*1
 
</syntaxhighlight>
</lang>
Multiplication table for A(3 0)
 
Line 271 ⟶ 819:
<br> <b>e</b>1<b>e</b>2<b>e</b>3 * <b>e</b>1<b>e</b>3 = <b>e</b>2
<br> <b>e</b>1<b>e</b>2<b>e</b>3 * <b>e</b>2<b>e</b>3 = - <b>e</b>1
<br> <b>e</b>1<b>e</b>2<b>e</b>3 * <b>e</b>1<b>e</b>2<b>e</b>3 = - <b>1</b>
 
=={{header|FreeBASIC}}==
{{trans|Wren}}
<syntaxhighlight lang="vbnet">Type Vector
dims(31) As Single
End Type
 
Function bitCount(i As Integer) As Integer
i = i - ((i Shr 1) And &h55555555)
i = (i And &h33333333) + ((i Shr 2) And &h33333333)
i = (i + (i Shr 4)) And &h0f0f0f0f
i = i + (i Shr 8)
i = i + (i Shr 16)
Return i And &h0000003F
End Function
 
Function ReorderingSign(i As Integer, j As Integer) As Integer
Dim As Integer k = i Shr 1
Dim As Integer sum = 0
While (k <> 0)
sum += bitCount(k And j)
k Shr= 1
Wend
Return Iif((sum And 1) = 0, 1, -1)
End Function
 
Function dot(lhs As Vector, rhs As Vector) As Vector
Dim result As Vector
For i As Integer = 0 To 31
result.dims(i) = 0.5 * (lhs.dims(i) * rhs.dims(i) + rhs.dims(i) * lhs.dims(i))
Next i
Return result
End Function
 
Function addition(lhs As Vector, rhs As Vector) As Vector
Dim result As Vector
For i As Integer = 0 To 31
result.dims(i) = lhs.dims(i) + rhs.dims(i)
Next i
Return result
End Function
 
Function multiply(lhs As Vector, rhs As Vector) As Vector
Dim result As Vector
Dim As Single s
Dim As Integer i, j, k
For i = 0 To 31
If lhs.dims(i) <> 0 Then
For j = 0 To 31
If rhs.dims(j) <> 0 Then
s = ReorderingSign(i, j) * lhs.dims(i) * rhs.dims(j)
k = i Xor j
result.dims(k) += s
End If
Next j
End If
Next i
Return result
End Function
 
Function multiplyScalar(lhs As Vector, rhs As Single) As Vector
Dim result As Vector
For i As Integer = 0 To 31
result.dims(i) = lhs.dims(i) * rhs
Next i
Return result
End Function
 
Function e(n As Integer) As Vector
If n > 4 Then Print "n must be less than 5": End
Dim result As Vector
result.dims(1 Shl n) = 1
Return result
End Function
 
Function randomVector() As Vector
Dim result As Vector
For i As Integer = 0 To 4
result = addition(result, multiplyScalar(e(i), Rnd))
Next i
Return result
End Function
 
Function randomMultiVector() As Vector
Dim result As Vector
For i As Integer = 0 To 31
result.dims(i) = Rnd
Next i
Return result
End Function
 
Randomize Timer
Dim a As Vector = randomMultiVector()
Dim b As Vector = randomMultiVector()
Dim c As Vector = randomMultiVector()
Dim x As Vector = randomVector()
 
' (ab)c == a(bc)
Print (multiply(multiply(a, b), c).dims(0))
Print (multiply(a, multiply(b, c)).dims(0))
Print
 
' a(b+c) == ab + ac
Print (multiply(a, addition(b, c)).dims(0))
Print (addition(multiply(a, b), multiply(a, c)).dims(0))
Print
 
' (a+b)c == ac + bc
Print (multiply(addition(a, b), c).dims(0))
Print (addition(multiply(a, c), multiply(b, c)).dims(0))
Print
 
' x^2 is real
Print (multiply(x, x).dims(0))
 
Sleep</syntaxhighlight>
 
=={{header|Go}}==
{{trans|JavaScript}}
<syntaxhighlight lang="go">package main
 
import (
"fmt"
"math/rand"
"time"
)
 
type vector []float64
 
func e(n uint) vector {
if n > 4 {
panic("n must be less than 5")
}
result := make(vector, 32)
result[1<<n] = 1.0
return result
}
 
func cdot(a, b vector) vector {
return mul(vector{0.5}, add(mul(a, b), mul(b, a)))
}
 
func neg(x vector) vector {
return mul(vector{-1}, x)
}
 
func bitCount(i int) int {
i = i - ((i >> 1) & 0x55555555)
i = (i & 0x33333333) + ((i >> 2) & 0x33333333)
i = (i + (i >> 4)) & 0x0F0F0F0F
i = i + (i >> 8)
i = i + (i >> 16)
return i & 0x0000003F
}
 
func reorderingSign(i, j int) float64 {
i >>= 1
sum := 0
for i != 0 {
sum += bitCount(i & j)
i >>= 1
}
cond := (sum & 1) == 0
if cond {
return 1.0
}
return -1.0
}
 
func add(a, b vector) vector {
result := make(vector, 32)
copy(result, a)
for i, _ := range b {
result[i] += b[i]
}
return result
}
 
func mul(a, b vector) vector {
result := make(vector, 32)
for i, _ := range a {
if a[i] != 0 {
for j, _ := range b {
if b[j] != 0 {
s := reorderingSign(i, j) * a[i] * b[j]
k := i ^ j
result[k] += s
}
}
}
}
return result
}
 
func randomVector() vector {
result := make(vector, 32)
for i := uint(0); i < 5; i++ {
result = add(result, mul(vector{rand.Float64()}, e(i)))
}
return result
}
 
func randomMultiVector() vector {
result := make(vector, 32)
for i := 0; i < 32; i++ {
result[i] = rand.Float64()
}
return result
}
 
func main() {
rand.Seed(time.Now().UnixNano())
for i := uint(0); i < 5; i++ {
for j := uint(0); j < 5; j++ {
if i < j {
if cdot(e(i), e(j))[0] != 0 {
fmt.Println("Unexpected non-null scalar product.")
return
}
} else if i == j {
if cdot(e(i), e(j))[0] == 0 {
fmt.Println("Unexpected null scalar product.")
}
}
}
}
 
a := randomMultiVector()
b := randomMultiVector()
c := randomMultiVector()
x := randomVector()
 
// (ab)c == a(bc)
fmt.Println(mul(mul(a, b), c))
fmt.Println(mul(a, mul(b, c)))
 
// a(b + c) == ab + ac
fmt.Println(mul(a, add(b, c)))
fmt.Println(add(mul(a, b), mul(a, c)))
 
// (a + b)c == ac + bc
fmt.Println(mul(add(a, b), c))
fmt.Println(add(mul(a, c), mul(b, c)))
 
// x² is real
fmt.Println(mul(x, x))
}</syntaxhighlight>
 
{{out}}
Sample output:
<pre>
[1.6282881498413662 0.2490818261523896 -0.8936755921478269 -1.555477163901491 6.47589688756284 8.705633181089887 -1.28416798750558 -3.0984267307080446 -14.384954438859133 -13.511137120485879 6.071767421804147 1.099627765550034 -0.40641746354718655 -3.3593459129408076 -2.8089033176352967 -3.003641914720827 4.223517526463662 5.7807271315990185 -4.921271185053852 -5.698203073886508 -0.5449956221104395 3.2199941835007997 -0.4168598688210261 -1.6164380014352773 -13.447900615475964 -11.892642419707807 5.484071302025009 2.781324432176212 5.237445180167182 0.4643791234551212 -7.986755945938485 -2.9272187129576714]
[1.628288149841367 0.24908182615239083 -0.8936755921478254 -1.5554771639014895 6.475896887562836 8.705633181089889 -1.2841679875055805 -3.0984267307080433 -14.384954438859129 -13.51113712048588 6.071767421804145 1.099627765550032 -0.40641746354718755 -3.359345912940806 -2.8089033176352958 -3.003641914720825 4.223517526463663 5.7807271315990185 -4.921271185053855 -5.698203073886506 -0.5449956221104393 3.2199941835008032 -0.4168598688210253 -1.6164380014352775 -13.44790061547596 -11.89264241970781 5.484071302025003 2.781324432176209 5.237445180167183 0.464379123455121 -7.986755945938484 -2.9272187129576706]
[-4.652496095413123 -6.651741805769786 -0.18044192849719706 -1.118756694503706 -1.4545868044605725 0.10199724090664991 0.5018587820915257 2.3004721822960024 -1.813996268087529 0.38357415506855985 7.882236705126414 4.377167004918281 0.338317137066833 1.0631923204534859 5.08861779773926 4.611434580371178 -5.277764644396049 -7.961720991272197 -1.27063408303169 -1.2002120748969933 -0.3251154212726659 2.005000622005424 1.0505371909084391 1.9822320823801767 -2.271503682913346 -0.2403902213900877 6.6269980604812275 4.006018365857085 -0.15074367863748028 -0.48557428903338595 5.291057793190274 2.7751733146879394]
[-4.652496095413124 -6.651741805769786 -0.18044192849719662 -1.1187566945037064 -1.454586804460573 0.10199724090665008 0.5018587820915265 2.3004721822960037 -1.8139962680875295 0.38357415506856163 7.882236705126415 4.377167004918281 0.338317137066834 1.0631923204534859 5.088617797739261 4.611434580371178 -5.277764644396049 -7.9617209912721965 -1.2706340830316898 -1.200212074896994 -0.3251154212726654 2.0050006220054257 1.050537190908438 1.9822320823801762 -2.2715036829133437 -0.24039022139008648 6.626998060481226 4.006018365857084 -0.15074367863747984 -0.4855742890333855 5.291057793190275 2.7751733146879403]
[-4.682894668443622 -7.686899263290272 -0.2500585680601418 -0.8779897639638435 2.579501108403806 2.901924320921563 -0.4542430696469483 1.0374201754917136 -2.588607371991848 -3.229485794697976 7.444924967244714 4.93089687101153 -2.0124785310408284 0.46939350205418884 6.568153651157447 5.710192967946121 -1.41530169954937 -4.536345225213684 0.5240731948596796 1.5123734256564463 1.767786974613905 2.9960861930917018 0.969306657461082 1.036924529835111 -1.456640437477983 -1.3085896429723467 2.9678738261068895 1.3051596528834055 -3.8197616441989037 -1.3030506523824616 4.7818448875243895 4.122121121578954]
[-4.682894668443622 -7.686899263290271 -0.2500585680601421 -0.877989763963844 2.5795011084038055 2.9019243209215633 -0.4542430696469487 1.0374201754917127 -2.5886073719918494 -3.2294857946979736 7.444924967244715 4.93089687101153 -2.0124785310408275 0.46939350205418884 6.568153651157447 5.710192967946121 -1.415301699549369 -4.536345225213685 0.5240731948596802 1.512373425656447 1.7677869746139057 2.9960861930917013 0.9693066574610807 1.036924529835109 -1.456640437477983 -1.3085896429723465 2.9678738261068895 1.305159652883405 -3.819761644198904 -1.3030506523824616 4.781844887524388 4.122121121578957]
[2.1206022437357284 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
</pre>
 
=={{header|J}}==
Line 279 ⟶ 1,086:
Implementation:
 
<langsyntaxhighlight Jlang="j">NB. indices are signed machine integers
vzero=: 1 $.2^31+IF64*32
odim=. 2^.#vzero
Line 312 ⟶ 1,119:
 
obasis=:1 (2^i.odim)ndx01 vzero
e=: {&obasis</langsyntaxhighlight>
 
Explanation:
Line 336 ⟶ 1,143:
Task examples:
 
<langsyntaxhighlight Jlang="j"> NB. test arbitrary vector being real (and having the specified result)
clean gmul~ +/ (e 0 1 2 3 4) gmul 1 _1 2 3 _2 (0 ndx01) vzero
0 │ 19
Line 379 ⟶ 1,186:
I gmul J+K
10 │ 1
12 │ _1</langsyntaxhighlight>
 
Note that sparse arrays display as <code>indices | value</code> for elements which are not the default element (0).
 
So, for example in the part where we check for orthogonality, we are forming a 5 by 5 by 9223372036854775807 array. The first two dimensions correspond to arguments to <code>e</code> and the final dimension is the multivector dimension. A <code>0</code> in the multivector dimension means that that's the "real" or "scalar" part of the multivector. And, since the pair of dimensions for the <code>e</code> arguments whose "dot" product are <code>1</code> are identical, we know we have an [[wp:Identity_matrix|identity matrix]].
 
=={{header|Java}}==
{{trans|Kotlin}}
<syntaxhighlight lang="java">import java.util.Arrays;
import java.util.Random;
 
public class GeometricAlgebra {
private static int bitCount(int i) {
i -= ((i >> 1) & 0x55555555);
i = (i & 0x33333333) + ((i >> 2) & 0x33333333);
i = (i + (i >> 4)) & 0x0F0F0F0F;
i += (i >> 8);
i += (i >> 16);
return i & 0x0000003F;
}
 
private static double reorderingSign(int i, int j) {
int k = i >> 1;
int sum = 0;
while (k != 0) {
sum += bitCount(k & j);
k = k >> 1;
}
return ((sum & 1) == 0) ? 1.0 : -1.0;
}
 
static class Vector {
private double[] dims;
 
public Vector(double[] dims) {
this.dims = dims;
}
 
public Vector dot(Vector rhs) {
return times(rhs).plus(rhs.times(this)).times(0.5);
}
 
public Vector unaryMinus() {
return times(-1.0);
}
 
public Vector plus(Vector rhs) {
double[] result = Arrays.copyOf(dims, 32);
for (int i = 0; i < rhs.dims.length; ++i) {
result[i] += rhs.get(i);
}
return new Vector(result);
}
 
public Vector times(Vector rhs) {
double[] result = new double[32];
for (int i = 0; i < dims.length; ++i) {
if (dims[i] != 0.0) {
for (int j = 0; j < rhs.dims.length; ++j) {
if (rhs.get(j) != 0.0) {
double s = reorderingSign(i, j) * dims[i] * rhs.dims[j];
int k = i ^ j;
result[k] += s;
}
}
}
}
return new Vector(result);
}
 
public Vector times(double scale) {
double[] result = dims.clone();
for (int i = 0; i < 5; ++i) {
dims[i] *= scale;
}
return new Vector(result);
}
 
double get(int index) {
return dims[index];
}
 
void set(int index, double value) {
dims[index] = value;
}
 
@Override
public String toString() {
StringBuilder sb = new StringBuilder("(");
boolean first = true;
for (double value : dims) {
if (first) {
first = false;
} else {
sb.append(", ");
}
sb.append(value);
}
return sb.append(")").toString();
}
}
 
private static Vector e(int n) {
if (n > 4) {
throw new IllegalArgumentException("n must be less than 5");
}
Vector result = new Vector(new double[32]);
result.set(1 << n, 1.0);
return result;
}
 
private static final Random rand = new Random();
 
private static Vector randomVector() {
Vector result = new Vector(new double[32]);
for (int i = 0; i < 5; ++i) {
Vector temp = new Vector(new double[]{rand.nextDouble()});
result = result.plus(temp.times(e(i)));
}
return result;
}
 
private static Vector randomMultiVector() {
Vector result = new Vector(new double[32]);
for (int i = 0; i < 32; ++i) {
result.set(i, rand.nextDouble());
}
return result;
}
 
public static void main(String[] args) {
for (int i = 0; i < 5; ++i) {
for (int j = 0; j < 5; ++j) {
if (i < j) {
if (e(i).dot(e(j)).get(0) != 0.0) {
System.out.println("Unexpected non-null scalar product.");
return;
}
}
}
}
 
Vector a = randomMultiVector();
Vector b = randomMultiVector();
Vector c = randomMultiVector();
Vector x = randomVector();
 
// (ab)c == a(bc)
System.out.println(a.times(b).times(c));
System.out.println(a.times(b.times(c)));
System.out.println();
 
// a(b+c) == ab + ac
System.out.println(a.times(b.plus(c)));
System.out.println(a.times(b).plus(a.times(c)));
System.out.println();
 
// (a+b)c == ac + bc
System.out.println(a.plus(b).times(c));
System.out.println(a.times(c).plus(b.times(c)));
System.out.println();
 
// x^2 is real
System.out.println(x.times(x));
}
}</syntaxhighlight>
{{out}}
<pre>(-14.826385115483191, -10.223187918212313, -15.02996653452487, -14.46670632198489, 9.367877413249497, 16.476783705852135, -15.946557036515442, -6.398255774639048, 1.5560496352407314, -7.135570742872677, -3.926278194944716, 4.7948511296793646, -8.132546330778185, -6.8139397609050025, -4.203632573891533, -0.5216302370612196, -11.240590807272154, -4.724378457579242, -16.477497153082254, -16.781194046381223, 3.715894934067395, 14.220125782905383, -12.846081825616357, -2.8313637859206557, 3.149468439469149, -5.163082715280577, -7.174869565605504, -3.34527279512389, -11.232806169860876, -9.975821980348016, -3.7795503524017735, -1.0610782061627755)
(-14.826385115483196, -10.223187918212307, -15.029966534524872, -14.46670632198489, 9.367877413249495, 16.476783705852135, -15.946557036515443, -6.398255774639046, 1.5560496352407327, -7.135570742872677, -3.92627819494472, 4.794851129679368, -8.132546330778192, -6.813939760904995, -4.203632573891537, -0.5216302370612151, -11.240590807272161, -4.724378457579236, -16.477497153082247, -16.781194046381223, 3.7158949340673937, 14.220125782905386, -12.846081825616348, -2.831363785920656, 3.1494684394691537, -5.163082715280574, -7.174869565605505, -3.3452727951238828, -11.232806169860877, -9.975821980348009, -3.7795503524017757, -1.0610782061627715)
 
(-6.53148126676475, -3.686197874035778, -0.7257324996849555, 4.278415831115293, 6.812402569345597, 1.3919745454991994, -2.3737314163466, -2.534117136854738, -0.02773680252709232, -2.959894343894277, 9.079951306324414, 3.5445539013571175, 4.855317638943012, 2.7949884209613094, 3.4702307051832215, 5.9614310877021195, -6.273887650229915, -3.3318300067614355, 2.5996846757588705, 5.753030636602611, 8.66307309332676, 4.103168227184037, -2.0758275707527396, -0.7429391125916148, -1.7949737037366886, -2.709591610956401, 10.9623759848287, 5.951981557918796, 5.367767313008209, 1.288037481749198, 4.141675073009981, 7.643531800306178)
(-6.5314812667647475, -3.686197874035778, -0.7257324996849563, 4.278415831115293, 6.812402569345599, 1.3919745454991996, -2.3737314163465992, -2.5341171368547366, -0.02773680252709232, -2.9598943438942764, 9.079951306324414, 3.54455390135712, 4.8553176389430135, 2.7949884209613103, 3.470230705183222, 5.96143108770212, -6.273887650229915, -3.3318300067614346, 2.5996846757588723, 5.753030636602611, 8.66307309332676, 4.103168227184039, -2.075827570752741, -0.742939112591615, -1.7949737037366884, -2.7095916109564, 10.9623759848287, 5.951981557918795, 5.367767313008202, 1.2880374817491977, 4.141675073009981, 7.64353180030618)
 
(-7.736834353560962, -2.502599400656683, -1.3572044140931654, 0.08823728154205668, 6.035469456565145, -0.12760675585521175, 1.6863493427502443, 0.3572366658217211, -0.5993428822081044, -1.9667973240788488, 9.136744013591118, 5.590676320343252, 5.026876608331699, 2.930873432370117, 3.3588635932299327, 7.0096288327820115, -9.169529600001841, -2.648288994190627, 1.0293696456484516, 1.403189013821808, 6.487492648530549, 2.70613886829337, -0.1101834481621051, 0.9130516717900701, -1.5135624840660704, -0.03875540986063708, 7.7402678101288025, 3.7385632770106736, 2.9147287828638784, -1.2493549934763781, 2.9769191225149667, 7.2051875611073894)
(-7.736834353560959, -2.502599400656682, -1.357204414093165, 0.08823728154205956, 6.035469456565146, -0.12760675585521244, 1.686349342750246, 0.35723666582172275, -0.5993428822081048, -1.9667973240788483, 9.136744013591116, 5.590676320343253, 5.026876608331699, 2.9308734323701158, 3.358863593229933, 7.009628832782012, -9.169529600001841, -2.648288994190626, 1.0293696456484527, 1.4031890138218066, 6.487492648530545, 2.7061388682933707, -0.11018344816210468, 0.9130516717900696, -1.5135624840660693, -0.038755409860637524, 7.7402678101288025, 3.738563277010674, 2.914728782863878, -1.249354993476379, 2.976919122514966, 7.205187561107389)
 
(1.9374102817883092, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0)</pre>
 
=={{header|javascript}}==
<langsyntaxhighlight lang="javascript">var GA = function () {
function e(n) {
var result = [];
result[1 << n] = 1;
return result;
}
function cdot(a, b) { return mul([0.5], add(mul(a, b), mul(b, a))) }
function neg(x) { return mul([-1], x) }
function bitCount(i) {
// Note that unsigned shifting (>>>) is not required.
i = i - ((i >> 1) & 0x55555555);
i = (i & 0x33333333) + ((i >> 2) & 0x33333333);
i = (i + (i >> 4)) & 0x0F0F0F0F;
i = i + (i >> 8);
i = i + (i >> 16);
return i & 0x0000003F;
}
function reorderingSign(a, b) {
a >>= 1;
var sum = 0;
while (a != 0) {
sum += bitCount(a & b);
a >>= 1;
}
}
return (sum & 1) == 0 ? 1 : -1;
}
function add(a, b) {
var result = a.slice(0);
for (var i in b) {
if (result[i]) {
result[i] += b[i];
} else {
result[i] = b[i];
}
}
}
return result;
}
function mul(a, b)
{
var result = [];
for (var i in a) {
if (a[i]) {
for (var j in b) {
if (b[j]) {
var s = reorderingSign(i, j) * a[i] * b[j];
// if (i == 1 && j == 1) { s *= -1 } // e0*e0 == -1
var k = i ^ j;
if (result[k]) {
result[k] += s;
} else {
result[k] = s;
}
}
}
}
}
}
}
}
return result;
}
return {
e : e,
cdot : cdot,
neg : neg,
add : add,
mul : mul
};
}();</lang>
</syntaxhighlight>
 
And then, from the console:
 
<langsyntaxhighlight lang="javascript">var e = GA.e, cdot = GA.cdot;
for (var i = 0; i < 5; i++) {
Line 494 ⟶ 1,474:
 
// x² is real
console.log(GA.mul(x, x));</langsyntaxhighlight>
{{out}}
<pre>[-7.834854130554672, -10.179405417124476, 5.696414143584243, -1.4014556169803851, 12.334288331422336, 11.690738709598888, -0.4279888274147221, 6.226618790084965, -10.904144874917206, -5.46919448234424, -5.647472225071031, -2.9801969751721744, -8.284532508545746, -3.3280413654836494, -2.2182526412098493, 0.4191036292473347, 3.0485450100607103, -0.20619687045226742, 2.1369938048939527, 3.730913391951158, 10.929856967963905, 8.301187183717643, -4.874133827873075, 0.7918650606624789, -8.520661635525103, -7.732342981599732, -6.494750491582618, -2.458749173402162, 3.573788336699224, 2.784339193089742, -1.6479372032388944, -0.35120747879544256]
Line 504 ⟶ 1,484:
[3.193752260485546, 3: 0, 5: 0, 6: 0, 9: 0, 10: 0, 12: 0, 17: 0, 18: 0, 20: 0, 24: 0]</pre>
 
=={{header|Perl 6Jsish}}==
From Javascript.
 
<syntaxhighlight lang="javascript">/* Geometric Algebra, in Jsih */
<lang perl6>unit class MultiVector;
 
has Real %.blades{UInt};
var GA = function () {
method clean { for %!blades { %!blades{.key} :delete unless .value; } }
function e(n) {
method narrow {
var result = [];
for %!blades { return self if .key > 0 && .value !== 0; }
result[1 << n] = 1;
return %!blades{0} // 0;
return result;
}
function cdot(a, b) { return mul([0.5], add(mul(a, b), mul(b, a))); }
function neg(x) { return mul([-1], x); }
function bitCount(i) {
// Note that unsigned shifting (>>>) is not required.
i = i - ((i >> 1) & 0x55555555);
i = (i & 0x33333333) + ((i >> 2) & 0x33333333);
i = (i + (i >> 4)) & 0x0F0F0F0F;
i = i + (i >> 8);
i = i + (i >> 16);
return i & 0x0000003F;
}
function reorderingSign(a, b) {
a >>= 1;
var sum = 0;
while (a != 0) {
sum += bitCount(a & b);
a >>= 1;
}
return (sum & 1) == 0 ? 1 : -1;
}
function add(a, b) {
var result = a.slice(0);
for (var i in b) {
if (result[i]) result[i] += b[i]; else result[i] = b[i];
}
return result;
}
function mul(a, b) {
var result = [];
for (var i in a) {
if (a[i]) {
for (var j in b) {
if (b[j]) {
var s = reorderingSign(i, j) * a[i] * b[j];
// if (i == 1 && j == 1) { s *= -1 } // e0*e0 == -1
var k = i ^ j;
if (result[k]) result[k] += s; else result[k] = s;
}
}
}
}
for (var i = 0; i < result.length; i++) result[i] = (result[i]) ? result[i] : 0;
return result;
}
 
return {
e:e,
cdot:cdot,
neg:neg,
add:add,
mul:mul
};
}();
 
if (Interp.conf('unitTest')) {
var e = GA.e, cdot = GA.cdot;
 
for (var i = 0; i < 5; i++) {
for (var j = 0; j < 5; j++) {
if (i < j) {
if (cdot(e(i), e(j))[0]) { console.log("unexpected non-nul scalar product"); }
} else if (i === j) {
if (!cdot(e(i), e(j))[0]) { console.log("unexpected nul scalar product"); }
}
}
}
 
function randomVector() {
var result = new Array(32).fill(0);
for (var i = 0; i < 5; i++) { result = GA.add( result, GA.mul([Math.random()], e(i))); }
return result;
}
function randomMultiVector() {
var result = new Array(32).fill(0);
for (var i = 0; i < 32; i++) { result[i] = Math.random(); }
return result;
}
 
Math.srand(0);
var a = randomMultiVector(), b = randomMultiVector(), c = randomMultiVector();
var x = randomVector();
 
; a;
; b;
; c;
 
// (ab)c == a(bc)
; GA.mul(GA.mul(a, b), c);
; GA.mul(a, GA.mul(b, c));
 
// a(b + c) == ab + ac
; GA.mul(a, GA.add(b, c));
; GA.add(GA.mul(a,b), GA.mul(a, c));
 
// (a + b)c == ac + bc
; GA.mul(GA.add(a, b), c);
; GA.add(GA.mul(a,c), GA.mul(b, c));
 
 
// x² is real
; x;
; GA.mul(x, x);
}
 
/*
sub e(UInt $n?) returns MultiVector is export {
=!EXPECTSTART!=
$n.defined ?? MultiVector.new(:blades(my Real %{UInt} = (1 +< $n) => 1)) !! MultiVector.new
a ==> [ 0.1708280361062897, 0.7499019804849638, 0.09637165562356742, 0.8704652270270756, 0.5773035067951078, 0.7857992588396741, 0.6921941534586402, 0.3687662699204211, 0.8739040768618089, 0.7450950984500651, 0.4460459090931117, 0.3537282030933753, 0.7325196320025391, 0.2602220010828802, 0.3942937749238773, 0.7767899512256164, 0.845035137580286, 0.5757882004827763, 0.7155385951686632, 0.08300424607387669, 0.4558251286597574, 0.1099468141806454, 0.5452280238165734, 0.3906865706486755, 0.5685854232144472, 0.9590664494883754, 0.8677190964591368, 0.1631895102523586, 0.2755089268683157, 0.2603610948720672, 0.9240947418691654, 0.435922637102685 ]
b ==> [ 0.7894608655520905, 0.1276170168117403, 0.08220568604043521, 0.9406420164478462, 0.02557492625301805, 0.1542109313278246, 0.382182425278156, 0.1547366996666923, 0.5293334181169804, 0.8768484910832512, 0.4306114383383992, 0.2639062263420797, 0.313594499023214, 0.7700916858547231, 0.107390883054105, 0.7710422551956455, 0.7051955588944487, 0.2186396587077581, 0.7617939928559956, 0.4117130455789564, 0.648826822929113, 0.929956254907367, 0.5024185655986706, 0.6874406794288674, 0.4360909481473279, 0.6083009079497401, 0.5765586336353685, 0.6326217107140693, 0.4634256476287426, 0.6322437896100865, 0.1382949326493268, 0.9607614179251911 ]
c ==> [ 0.1443750010878411, 0.4466830710677812, 0.3245844598453793, 0.9525840775924692, 0.358183910481177, 0.3982082224922436, 0.1012815422323818, 0.9550857356528795, 0.9846169476710749, 0.5759700814514872, 0.8659137353852593, 0.1498758912327744, 0.9091504302816595, 0.6512525086400416, 0.06386085476492198, 0.9549993865624558, 0.9662627642756583, 0.7855433852139697, 0.8051648178950011, 0.5712536797957526, 0.2825857199542448, 0.9625510519679636, 0.5794770589463063, 0.4368586269705688, 0.3754361745372741, 0.9234076091930206, 0.02869938006311301, 0.7688599777155005, 0.7231067717175854, 0.5909693498129656, 0.4258885385798372, 0.6421430590830184 ]
GA.mul(GA.mul(a, b), c) ==> [ 1.541918542712994, 4.115829300591508, 6.756686908265433, 1.237835072374462, 10.35373455425321, 15.27788368572946, -10.02377587769663, -7.963603479812443, -4.551812682204639, -2.063312081493453, 6.501355951540042, 7.264555440540969, -8.486452071298562, -4.822494555299121, -4.759231263111541, -10.77800945200822, -7.362166274344194, -4.396761648257096, -4.546442029824131, -5.48725057173969, 7.12307450722373, 12.97562340826319, -15.0237414847673, -14.51557782429663, -4.883430414017697, -4.901409415740756, 7.906069132188758, 6.734848434665599, -9.783158191139472, -6.519424552890571, -2.139880496917612, -9.858645000418766 ]
GA.mul(a, GA.mul(b, c)) ==> [ 1.541918542712995, 4.11582930059151, 6.756686908265435, 1.23783507237446, 10.35373455425321, 15.27788368572945, -10.02377587769663, -7.963603479812441, -4.551812682204639, -2.06331208149345, 6.501355951540043, 7.264555440540969, -8.486452071298562, -4.822494555299119, -4.759231263111545, -10.77800945200822, -7.362166274344201, -4.396761648257097, -4.546442029824129, -5.48725057173969, 7.12307450722373, 12.97562340826319, -15.0237414847673, -14.51557782429663, -4.883430414017695, -4.901409415740756, 7.906069132188759, 6.734848434665598, -9.783158191139472, -6.519424552890572, -2.139880496917614, -9.858645000418766 ]
GA.mul(a, GA.add(b, c)) ==> [ -4.618544334910429, -1.861355248134714, -1.344616248842651, -0.2493092523303422, 2.805076632862419, 7.011456497501809, -2.595903465496111, -2.470668530528046, 2.219481357349965, 1.819582156863502, 7.750350045338696, 7.672479893390893, -0.4578513259004232, -0.2416326854384544, 6.428349361134747, 6.656718281504274, -5.564788398161922, -3.02924871963873, -0.2716453262784845, 2.840935952141899, 0.0859121820261296, 4.694618143418901, -5.096817957116206, -0.4737762603304853, -1.385313600482476, -3.455075469132893, 6.134561343411066, 4.384932175234187, -0.6284984442281132, -1.060102630996634, 6.555893195756837, 8.364446730582344 ]
GA.add(GA.mul(a,b), GA.mul(a, c)) ==> [ -4.618544334910429, -1.861355248134714, -1.344616248842651, -0.2493092523303427, 2.805076632862418, 7.011456497501809, -2.595903465496112, -2.470668530528046, 2.219481357349964, 1.819582156863503, 7.750350045338696, 7.672479893390893, -0.4578513259004234, -0.2416326854384541, 6.42834936113475, 6.656718281504276, -5.564788398161921, -3.029248719638729, -0.2716453262784859, 2.840935952141899, 0.08591218202612916, 4.6946181434189, -5.096817957116205, -0.4737762603304851, -1.385313600482476, -3.455075469132893, 6.134561343411068, 4.384932175234186, -0.6284984442281131, -1.060102630996634, 6.555893195756836, 8.364446730582346 ]
GA.mul(GA.add(a, b), c) ==> [ -4.443021937525184, -3.701220635832722, -0.6818565879668145, 0.239151370235406, 3.458768472629645, 6.988109725549518, -3.684631030647005, -0.8507257226324562, 2.724894692072849, 4.331141304914477, 6.87324809064668, 5.39527557728919, -1.338732261664156, 0.5042890433991951, 3.524762387495515, 6.138868250703226, -5.595434900923999, -5.095415369801449, -2.668271896337068, 0.6569878447501574, -0.03973787332027184, 4.991106401646302, -5.122908058541086, -1.273551488694048, -2.981638879697476, -2.047004560822915, 6.135097056892218, 5.062423121634416, -1.370651481167422, -0.9463086012211376, 5.574441079445841, 8.892885715782024 ]
GA.add(GA.mul(a,c), GA.mul(b, c)) ==> [ -4.443021937525184, -3.701220635832721, -0.6818565879668153, 0.2391513702354063, 3.458768472629644, 6.988109725549519, -3.684631030647005, -0.8507257226324556, 2.724894692072848, 4.331141304914478, 6.873248090646679, 5.39527557728919, -1.338732261664156, 0.5042890433991953, 3.524762387495516, 6.138868250703224, -5.595434900923999, -5.095415369801452, -2.668271896337069, 0.6569878447501573, -0.03973787332027234, 4.991106401646301, -5.122908058541086, -1.273551488694048, -2.981638879697477, -2.047004560822915, 6.135097056892217, 5.062423121634419, -1.370651481167422, -0.946308601221137, 5.57444107944584, 8.892885715782022 ]
x ==> [ 0, 0.7467627291006274, 0.06901854981410338, 0, 0.05329494862236217, 0, 0, 0, 0.7743136455713469, 0, 0, 0, 0, 0, 0, 0, 0.7035034807394887, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]
GA.mul(x, x) ==> [ 1.659737254471485, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]
=!EXPECTEND!=
*/</syntaxhighlight>
 
{{out}}
<pre>prompt$ jsish -u geometricAlgebra.jsi
[PASS] geometricAlgebra.jsi</pre>
 
=={{header|Julia}}==
{{trans|Kotlin}}
<syntaxhighlight lang="julia">using GeometryTypes
import Base.*
 
CliffordVector = Point{32, Float64}
 
e(n) = (v = zeros(32); v[(1 << n) + 1] = 1.0; CliffordVector(v))
 
randommultivector() = CliffordVector(rand(32))
 
randomvector() = sum(i -> rand() * e(i), 0:4)
 
bitcount(n) = (count = 0; while n != 0 n &= n - 1; count += 1 end; count)
 
function reorderingsign(i, j)
ssum, i = 0, i >> 1
while i != 0
ssum += bitcount(i & j)
i >>= 1
end
return iseven(ssum) ? 1.0 : -1.0
end
 
function Base.:*(v1::CliffordVector, v2::CliffordVector)
result = zeros(32)
for (i, x1) in enumerate(v1)
if x1 != 0.0
for (j, x2) in enumerate(v2)
if x2 != 0.0
s = reorderingsign(i - 1, j - 1) * x1 * x2
k = (i - 1) ⊻ (j - 1)
result[k + 1] += s
end
end
end
end
return CliffordVector(result)
end
 
function testcliffordvector()
allorthonormal = true
for i in 0:4, j in 0:4
i < j && all(iszero, e(i) * e(j)) != 0.0 && (allorthonormal = false)
i == j && !all(iszero, e(i) * e(j)) == 0.0 && (allorthonormal = false)
end
println("e(i) * e(j) are orthonormal for i, j ϵ [0, 4]: ", allorthonormal)
a, b, c = randommultivector(), randommultivector(), randommultivector()
x = randomvector()
 
@show (a * b) * c ≈ a * (b * c)
@show a * (b + c) ≈ a * b + a * c
@show (a + b) * c ≈ a * c + b * c
 
isreal(x) = x[1] isa Real && all(iszero, x[2:end])
@show isreal(x * x)
end
 
 
testcliffordvector()
</syntaxhighlight>{{out}}
<pre>
e(i) * e(j) are orthonormal for i, j ϵ [0, 4]: true
(a * b) * c ≈ a * (b * c) = true
a * (b + c) ≈ a * b + a * c = true
(a + b) * c ≈ a * c + b * c = true
isreal(x * x) = true
</pre>
 
=={{header|Kotlin}}==
{{trans|Go}}
<syntaxhighlight lang="scala">fun bitCount(i: Int): Int {
var j = i
j -= ((j shr 1) and 0x55555555)
j = (j and 0x33333333) + ((j shr 2) and 0x33333333)
j = (j + (j shr 4)) and 0x0F0F0F0F
j += (j shr 8)
j += (j shr 16)
return j and 0x0000003F
}
 
fun reorderingSign(i: Int, j: Int): Double {
my sub order(UInt:D $i is copy, UInt:D $j) is cached {
myvar $nk = 0;i shr 1
repeatvar {sum = 0
while (k != 0) {
$i +>= 1;
sum += bitCount(k and j)
$n += [+] ($i +& $j).base(2).comb;
} until $i k == 0;k shr 1
}
return $n +& 1 ?? -1 !! 1;
return if (sum and 1 == 0) 1.0 else -1.0
}
 
class Vector(private val dims: DoubleArray) {
multi infix:<+>(MultiVector $A, MultiVector $B) returns MultiVector is export {
 
my Real %blades{UInt} = $A.blades.clone;
infix fun dot(rhs: Vector): Vector {
for $B.blades {
return (this * rhs + rhs * this) * 0.5
%blades{.key} += .value;
}
%blades{.key} :delete unless %blades{.key};
 
operator fun unaryMinus(): Vector {
return this * -1.0
}
 
operator fun plus(rhs: Vector): Vector {
val result = DoubleArray(32)
dims.copyInto(result)
for (i in 0 until rhs.dims.size) {
result[i] += rhs[i]
}
return Vector(result)
}
 
operator fun times(rhs: Vector): Vector {
val result = DoubleArray(32)
for (i in 0 until dims.size) {
if (dims[i] != 0.0) {
for (j in 0 until rhs.dims.size) {
if (rhs[j] != 0.0) {
val s = reorderingSign(i, j) * dims[i] * rhs[j]
val k = i xor j
result[k] += s
}
}
}
}
return Vector(result)
}
 
operator fun times(scale: Double): Vector {
val result = dims.clone()
for (i in 0 until 5) {
dims[i] = dims[i] * scale
}
return Vector(result)
}
 
operator fun get(index: Int): Double {
return dims[index]
}
 
operator fun set(index: Int, value: Double) {
dims[index] = value
}
 
override fun toString(): String {
val sb = StringBuilder("(")
val it = dims.iterator()
if (it.hasNext()) {
sb.append(it.next())
}
while (it.hasNext()) {
sb.append(", ").append(it.next())
}
return sb.append(")").toString()
}
return MultiVector.new: :%blades;
}
 
multi infix:<+>(Real $s, MultiVector $A) returns MultiVector is export {
fun e(n: Int): Vector {
my Real %blades{UInt} = $A.blades.clone;
%blades{0}if +=(n $s;> 4) {
throw IllegalArgumentException("n must be less than 5")
%blades{0} :delete unless %blades{0};
}
return MultiVector.new: :%blades;
val result = Vector(DoubleArray(32))
result[1 shl n] = 1.0
return result
}
 
multi infix:<+>(MultiVector $A, Real $s) returns MultiVector is export { $s + $A }
val rand = java.util.Random()
multi infix:<*>(MultiVector $A, MultiVector $B) returns MultiVector is export {
 
my Real %blades{UInt};
fun randomVector(): Vector {
for $A.blades -> $a {
var result = Vector(DoubleArray(32))
for $B.blades -> $b {
myfor $c(i =in $a.key0 +^until $b.key;5) {
result += Vector(doubleArrayOf(rand.nextDouble())) * e(i)
%blades{$c} += $a.value * $b.value * order($a.key, $b.key);
%blades{$c} :delete unless %blades{$c};
}
}
return MultiVector.new: :%blades;result
}
multi infix:<**>(MultiVector $ , 0) returns MultiVector is export { MultiVector.new }
multi infix:<**>(MultiVector $A, 1) returns MultiVector is export { $A }
multi infix:<**>(MultiVector $A, 2) returns MultiVector is export { $A * $A }
multi infix:<**>(MultiVector $A, UInt $n where $n %% 2) returns MultiVector is export { ($A ** ($n div 2)) ** 2 }
multi infix:<**>(MultiVector $A, UInt $n) returns MultiVector is export { $A * ($A ** ($n div 2)) ** 2 }
 
fun randomMultiVector(): Vector {
multi infix:<*>(MultiVector $, 0) returns MultiVector is export { MultiVector.new }
val result = Vector(DoubleArray(32))
multi infix:<*>(MultiVector $A, 1) returns MultiVector is export { $A }
for (i in 0 until 32) {
multi infix:<*>(MultiVector $A, Real $s) returns MultiVector is export {
result[i] = rand.nextDouble()
return MultiVector.new: :blades(my Real %{UInt} = map { .key => $s * .value }, $A.blades);
}
return result
}
multi infix:<*>(Real $s, MultiVector $A) returns MultiVector is export { $A * $s }
multi infix:</>(MultiVector $A, Real $s) returns MultiVector is export { $A * (1/$s) }
multi prefix:<->(MultiVector $A) returns MultiVector is export { return -1 * $A }
multi infix:<->(MultiVector $A, MultiVector $B) returns MultiVector is export { $A + -$B }
multi infix:<->(MultiVector $A, Real $s) returns MultiVector is export { $A + -$s }
multi infix:<->(Real $s, MultiVector $A) returns MultiVector is export { $s + -$A }
 
fun main() {
multi infix:<==>(MultiVector $A, MultiVector $B) returns Bool is export { $A - $B == 0 }
for (i in 0..4) {
multi infix:<==>(Real $x, MultiVector $A) returns Bool is export { $A == $x }
for (j in 0..4) {
multi infix:<==>(MultiVector $A, Real $x) returns Bool is export {
if (i < j) {
my $narrowed = $A.narrow;
if ((e(i) dot e(j))[0] != 0.0) {
$narrowed ~~ Real and $narrowed == $x;
println("Unexpected non-null scalar product.")
}</lang>
return
} else if (i == j) {
if ((e(i) dot e(j))[0] == 0.0) {
println("Unexpected null scalar product.")
}
}
}
}
}
 
val a = randomMultiVector()
And here is the code implementing and verifying quaternions:
val b = randomMultiVector()
val c = randomMultiVector()
val x = randomVector()
 
// (ab)c == a(bc)
<lang perl6>use MultiVector;
println((a * b) * c)
use Test;
println(a * (b * c))
println()
 
// a(b+c) == ab + ac
plan 29;
println(a * (b + c))
println(a * b + a * c)
println()
 
// (a+b)c == ac + bc
sub infix:<cdot>($x, $y) { ($x*$y + $y*$x)/2 }
println((a + b) * c)
my @e = map &e, ^5;
println(a * c + b * c)
println()
 
for ^5 X ^5 ->// ($i,x^2 $j)is {real
println(x * x)
my $s = $i == $j ?? 1 !! 0;
}</syntaxhighlight>
ok @e[$i] cdot @e[$j] == $s, "e$i cdot e$j = $s";
{{out}}
}
<pre>(-6.38113123172589, -6.025395204580336, 0.5762054454373319, -2.224611121553874, -0.03467815839340305, -0.6665488550665257, -3.012105902847624, 0.7315782457554153, -4.183528079943369, -1.8391037440709876, -0.137654892093293, 0.10852885457965271, -6.021317788342983, -5.486453322362711, -3.524908677069778, -1.030729377561671, -6.858194536947578, -8.724962937014816, 0.4660400096706247, -1.6434599565678671, 4.212637141194194, 2.916899539720754, -1.365566480297562, 1.898991559248674, -2.5943503153384517, -0.7167616808942235, 1.2152416665362584, 2.9936787524618067, -5.394453145898911, -4.180356766796923, -6.622391097517418, -4.249450373116712)
sub random {
(-6.381131231725885, -6.025395204580336, 0.5762054454373331, -2.2246111215538744, -0.034678158393403866, -0.6665488550665265, -3.012105902847625, 0.7315782457554131, -4.183528079943374, -1.83910374407099, -0.13765489209329423, 0.1085288545796525, -6.021317788342984, -5.486453322362712, -3.524908677069777, -1.0307293775616722, -6.858194536947579, -8.724962937014814, 0.46604000967062464, -1.6434599565678658, 4.212637141194197, 2.916899539720756, -1.3655664802975644, 1.8989915592486726, -2.5943503153384526, -0.716761680894223, 1.2152416665362615, 2.9936787524618076, -5.394453145898909, -4.1803567667969235, -6.622391097517417, -4.24945037311671)
[+] map {
 
MultiVector.new:
(-5.001996874378833, -5.342863347345118, 0.5930301138931318, 1.8495242515856356, 5.226690714239807, 5.60029170092836, 1.9264816320512175, 2.9647400073622383, -1.231074336132209, -0.03574406666207321, 2.0490593688751666, 2.709392811857615, -0.534934380183112, 0.9566513059906786, 0.581531676517317, 2.6867651675849284, -6.072314695960932, -5.780622914352332, -2.264083859970755, -0.29904973719224437, 3.1693202958893196, 3.710947660874322, -0.3876119148699613, 0.28047758363117253, 0.4891346543855399, 1.1102262337923456, 1.9059090529704015, 2.2175302024987404, 3.6850877929174954, 4.798530127158409, 0.6243236143375706, 2.5910748978446576)
:blades(my Real %{UInt} = $_ => rand.round(.01))
(-5.001996874378833, -5.3428633473451175, 0.5930301138931321, 1.8495242515856363, 5.22669071423981, 5.600291700928359, 1.9264816320512164, 2.9647400073622387, -1.231074336132209, -0.035744066662073595, 2.0490593688751657, 2.7093928118576143, -0.5349343801831126, 0.9566513059906783, 0.5815316765173175, 2.6867651675849284, -6.072314695960929, -5.78062291435233, -2.264083859970754, -0.2990497371922432, 3.169320295889319, 3.7109476608743237, -0.3876119148699616, 0.2804775836311723, 0.4891346543855406, 1.1102262337923452, 1.9059090529704013, 2.21753020249874, 3.6850877929174954, 4.798530127158408, 0.6243236143375701, 2.591074897844657)
}, (^32).pick(5);
 
(-3.583945607396393, -3.5239300960595137, 0.801943558725803, 2.9686354622847357, 4.064529783603304, 3.6456241887862015, 0.5954304494585552, 1.2819925842824296, 0.6768216109361052, 0.352207714198545, 2.843092732483635, 2.680239849424965, -0.04943045827884884, 0.19653339086911384, 2.875432393192088, 2.8657275256839823, -4.689497942711508, -3.42309859067624, -2.830665114554725, -0.017676578013020444, 3.635425127096899, 3.10264457980534, -1.2355052114199154, 0.02671272974814648, 2.5200281685651413, 2.2030677245192627, 2.727374336905742, 1.7812768180621927, 1.901781821035387, 2.8306551025240863, 3.9572153730448463, 2.9611369534401093)
(-3.5839456073963945, -3.5239300960595115, 0.8019435587258037, 2.968635462284734, 4.064529783603305, 3.6456241887862024, 0.5954304494585542, 1.2819925842824302, 0.6768216109361052, 0.3522077141985451, 2.843092732483634, 2.6802398494249644, -0.04943045827884848, 0.1965333908691129, 2.875432393192088, 2.8657275256839827, -4.689497942711507, -3.4230985906762403, -2.8306651145547246, -0.017676578013019806, 3.6354251270968985, 3.1026445798053395, -1.2355052114199154, 0.026712729748146535, 2.5200281685651413, 2.2030677245192627, 2.7273743369057417, 1.7812768180621923, 1.9017818210353874, 2.830655102524086, 3.957215373044847, 2.9611369534401097)
 
(2.6501903002573224, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0)</pre>
 
=={{header|Nim}}==
{{trans|Go}}
<syntaxhighlight lang="nim">import bitops, random, sequtils, strutils
 
type Vector = seq[float]
 
func reorderingSign(i, j: int): float =
var i = i shr 1
var sum = 0
while i != 0:
sum += countSetBits(i and j)
i = i shr 1
result = if (sum and 1) == 0: 1 else: -1
 
func e(n: Natural): Vector =
result.setLen(32)
assert n < 5, "index must be less than 5; got $#.".format(n)
result[1 shl n] = 1
 
func `+`(a, b: Vector): Vector =
result.setLen(32)
for i in 0..b.high:
result[i] = a[i] + b[i]
 
func `*`(a, b: Vector): Vector =
result.setLen(32)
for i in 0..a.high:
if a[i] != 0:
for j in 0..b.high:
if b[j] != 0:
let s = reorderingSign(i, j) * a[i] * b[j]
let k = i xor j
result[k] += s
 
func dot(a, b: Vector): Vector =
(a * b + b * a) * @[0.5]
 
proc randomVector(): Vector =
result.setLen(32)
for i in 0..4:
result = result + @[rand(1.0)] * e(i)
 
proc randomMultiVector(): Vector =
newSeqWith(32, rand(1.0))
 
 
when isMainModule:
 
randomize()
for i in 0..4:
for j in 0..4:
if i < j:
if dot(e(i), e(j))[0] != 0:
raise newException(ValueError, "Unexpected non-null scalar product.")
elif i == j:
if dot(e(i), e(j))[0] == 0:
raise newException(ValueError, "Unexpected null scalar product.")
 
let a = randomMultiVector()
let b = randomMultiVector()
let c = randomMultiVector()
let x = randomVector()
 
# (ab)c == a(bc).
echo (a * b) * c
echo a * (b * c)
echo()
 
# a(b + c) == ab + ac.
echo a * (b + c)
echo a * b + a * c
echo()
 
# (a + b)c == ac + bc.
echo (a + b) * c
echo a * c + b * c
echo()
 
# x² is real.
echo x * x</syntaxhighlight>
 
{{out}}
<pre>@[-9.297288337196365, -13.59127999209494, 0.8722218109740326, 1.226935672314977, 7.508102247367465, 4.724948516329687, -5.033061024827017, -1.610503728288931, -3.33431529299565, 0.3532979194154671, 4.301275797990844, 0.515295984242726, 4.687736789474281, 2.172013218653572, 1.231492215423554, 0.3536950472866263, -2.327900412362799, -9.527999065273885, -1.555602751234329, 5.382767377500711, 6.267283581472086, 2.76910363753004, -2.301420318996988, 3.652383163769268, 1.752589228395532, 5.939099169023176, 4.479735695808257, 0.01446097776030125, -2.363384273037976, -5.720151847201447, -0.9397636030508162, -6.25507506195876]
@[-9.297288337196365, -13.59127999209493, 0.872221810974033, 1.226935672314978, 7.508102247367463, 4.72494851632969, -5.033061024827017, -1.610503728288931, -3.334315292995649, 0.3532979194154663, 4.301275797990842, 0.5152959842427232, 4.687736789474281, 2.172013218653572, 1.231492215423554, 0.3536950472866283, -2.327900412362798, -9.527999065273882, -1.55560275123433, 5.382767377500712, 6.267283581472084, 2.76910363753004, -2.301420318996988, 3.652383163769271, 1.752589228395533, 5.939099169023176, 4.47973569580826, 0.01446097776030148, -2.363384273037971, -5.720151847201445, -0.9397636030508175, -6.255075061958758]
 
@[-2.586487554821921, -2.653533704207625, 2.766021230656747, 2.036067471647896, 3.190493529679435, 2.42809912090021, 0.6900349473229486, 2.878934763823856, -3.935215841511595, -0.7288825987300381, 6.463778612248242, 4.417536841852129, 0.636912176867748, 4.413110019589562, 2.623393232840747, 1.608010580836939, -0.5328933745526506, -3.058074932298209, 2.178373565254037, 2.495618455562951, 4.609639873172126, 2.906729883514136, -0.934662696267724, 0.1369174733899857, 0.7572410282960323, 2.600596775217479, 4.079925278716743, 2.378076954647832, -1.529999013986847, 4.451662845891456, 0.07968415835836305, 0.7302442935297417]
@[-2.586487554821921, -2.653533704207625, 2.766021230656746, 2.036067471647896, 3.190493529679435, 2.42809912090021, 0.6900349473229492, 2.878934763823857, -3.935215841511596, -0.7288825987300391, 6.463778612248241, 4.417536841852128, 0.6369121768677473, 4.413110019589563, 2.623393232840748, 1.60801058083694, -0.5328933745526511, -3.058074932298209, 2.178373565254037, 2.495618455562951, 4.609639873172125, 2.906729883514135, -0.9346626962677241, 0.1369174733899854, 0.7572410282960332, 2.600596775217479, 4.079925278716742, 2.378076954647831, -1.529999013986847, 4.451662845891456, 0.0796841583583624, 0.7302442935297415]
 
@[-4.043970500041602, -6.87480031917386, 2.141017248170762, 0.3993395131802852, 0.8031440447491957, 3.401648770759057, 1.607243807621857, 3.522447744273161, -1.991055803046583, -0.7625625003549232, 6.536037328177198, 3.860062375500871, 2.237849358894385, 4.651754451010404, 8.300896571599077, 4.846096568587825, -2.0442907200416, -4.305082016141705, -0.9716874582456112, 0.214856705219781, 3.6445786747822, 2.050775132011032, -2.303468928921437, -1.111677463505033, 2.776551776801528, 1.829715078662076, 4.565478899003429, 1.874485695211426, -2.682597285575913, 1.056667802512815, 4.075588220758377, 1.609677009616234]
@[-4.043970500041601, -6.874800319173863, 2.141017248170761, 0.3993395131802844, 0.8031440447491961, 3.401648770759058, 1.607243807621859, 3.522447744273161, -1.991055803046583, -0.7625625003549237, 6.536037328177197, 3.860062375500871, 2.237849358894385, 4.651754451010405, 8.300896571599079, 4.846096568587828, -2.044290720041601, -4.305082016141704, -0.9716874582456119, 0.2148567052197807, 3.6445786747822, 2.050775132011031, -2.303468928921436, -1.111677463505034, 2.776551776801528, 1.829715078662075, 4.565478899003429, 1.874485695211426, -2.682597285575913, 1.056667802512815, 4.075588220758375, 1.609677009616233]
 
@[2.298735784397904, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]</pre>
 
=={{header|Phix}}==
{{trans|Go}}
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">bitCount</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">return</span> <span style="color: #7060A8;">sum</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">sq_eq</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"%b"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">i</span><span style="color: #0000FF;">),</span><span style="color: #008000;">'1'</span><span style="color: #0000FF;">))</span> <span style="color: #000080;font-style:italic;">-- (idea cribbed from Python)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">reorderingSign</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">i</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;">/</span><span style="color: #000000;">2</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">tot</span> <span style="color: #0000FF;">:=</span> <span style="color: #000000;">0</span>
<span style="color: #008080;">while</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">tot</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">bitCount</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">and_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;">,</span><span style="color: #000000;">j</span><span style="color: #0000FF;">))</span>
<span style="color: #000000;">i</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;">/</span><span style="color: #000000;">2</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #008080;">return</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">and_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tot</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)==</span><span style="color: #000000;">0</span> <span style="color: #0000FF;">?</span> <span style="color: #000000;">1</span> <span style="color: #0000FF;">:</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">add</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">return</span> <span style="color: #7060A8;">sq_add</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span><span style="color: #000000;">b</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">mul</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">result</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">32</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">s</span> <span style="color: #0000FF;">:=</span> <span style="color: #000000;">reorderingSign</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">*</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">*</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">k</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">xor_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">j</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">1</span>
<span style="color: #000000;">result</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">s</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">result</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">cdot</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">mul</span><span style="color: #0000FF;">({</span><span style="color: #000000;">0.5</span><span style="color: #0000FF;">},</span> <span style="color: #000000;">add</span><span style="color: #0000FF;">(</span><span style="color: #000000;">mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">),</span> <span style="color: #000000;">mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">)))</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">e</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">></span><span style="color: #000000;">4</span> <span style="color: #008080;">then</span> <span style="color: #7060A8;">crash</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"n must be less than 5"</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">result</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">32</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">result</span><span style="color: #0000FF;">[</span><span style="color: #7060A8;">power</span><span style="color: #0000FF;">(</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">n</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1.0</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">result</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #000080;font-style:italic;">--function neg(sequence x) -- (not actually used here)
-- return mul({-1}, x)
--end function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">randomVector</span><span style="color: #0000FF;">()</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">result</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">32</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">to</span> <span style="color: #000000;">4</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">result</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">add</span><span style="color: #0000FF;">(</span><span style="color: #000000;">result</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">mul</span><span style="color: #0000FF;">({</span><span style="color: #7060A8;">rnd</span><span style="color: #0000FF;">()},</span> <span style="color: #000000;">e</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;">)))</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">result</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">randomMultiVector</span><span style="color: #0000FF;">()</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">result</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">32</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">32</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">result</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">rnd</span><span style="color: #0000FF;">()</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">result</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">to</span> <span style="color: #000000;">4</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">to</span> <span style="color: #000000;">4</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">i</span> <span style="color: #0000FF;"><</span> <span style="color: #000000;">j</span> <span style="color: #008080;">then</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">cdot</span><span style="color: #0000FF;">(</span><span style="color: #000000;">e</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;">),</span> <span style="color: #000000;">e</span><span style="color: #0000FF;">(</span><span style="color: #000000;">j</span><span style="color: #0000FF;">))[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">!=</span> <span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
<span style="color: #7060A8;">crash</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"Unexpected non-null scalar product."</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">elsif</span> <span style="color: #000000;">i</span> <span style="color: #0000FF;">==</span> <span style="color: #000000;">j</span> <span style="color: #008080;">then</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">cdot</span><span style="color: #0000FF;">(</span><span style="color: #000000;">e</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;">),</span> <span style="color: #000000;">e</span><span style="color: #0000FF;">(</span><span style="color: #000000;">j</span><span style="color: #0000FF;">))[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">==</span> <span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
<span style="color: #7060A8;">crash</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"Unexpected null scalar product."</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">a</span> <span style="color: #0000FF;">:=</span> <span style="color: #000000;">randomMultiVector</span><span style="color: #0000FF;">(),</span>
<span style="color: #000000;">b</span> <span style="color: #0000FF;">:=</span> <span style="color: #000000;">randomMultiVector</span><span style="color: #0000FF;">(),</span>
<span style="color: #000000;">c</span> <span style="color: #0000FF;">:=</span> <span style="color: #000000;">randomMultiVector</span><span style="color: #0000FF;">(),</span>
<span style="color: #000000;">x</span> <span style="color: #0000FF;">:=</span> <span style="color: #000000;">randomVector</span><span style="color: #0000FF;">(),</span>
<span style="color: #000000;">xsq</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">x</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">test</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">txt</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">sequence</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">)</span>
<span style="color: #000080;font-style:italic;">-- bool eq = (a==b) -- no!</span>
<span style="color: #004080;">bool</span> <span style="color: #000000;">eq</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">(</span><span style="color: #7060A8;">sprint</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">)==</span><span style="color: #7060A8;">sprint</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">))</span> <span style="color: #000080;font-style:italic;">-- ok!</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%-20s: %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">txt</span><span style="color: #0000FF;">,</span><span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">eq</span><span style="color: #0000FF;">?</span><span style="color: #008000;">"true"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"false"</span><span style="color: #0000FF;">)})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #000000;">test</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"(ab)c == a(bc)"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">),</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">)))</span>
<span style="color: #000000;">test</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"a(b + c) == ab + ac"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">add</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">)),</span>
<span style="color: #000000;">add</span><span style="color: #0000FF;">(</span><span style="color: #000000;">mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">),</span> <span style="color: #000000;">mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">)))</span>
<span style="color: #000000;">test</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"(a + b)c == ac + bc"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">add</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">),</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">add</span><span style="color: #0000FF;">(</span><span style="color: #000000;">mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">),</span> <span style="color: #000000;">mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">)))</span>
<span style="color: #000000;">test</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"x^2 is real"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">xsq</span><span style="color: #0000FF;">,</span><span style="color: #000000;">xsq</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]&</span><span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">31</span><span style="color: #0000FF;">))</span>
<!--</syntaxhighlight>-->
{{out}}
Note the comparison of string representations of floats, rather than the floats themselves. That effectively ensures they
all match to 10 significant digits, and avoids a few tiny (~1e-16) discrepancies.
<pre>
(ab)c == a(bc) : true
a(b + c) == ab + ac : true
(a + b)c == ac + bc : true
x^2 is real : true
</pre>
 
=={{header|Python}}==
{{trans|D}}
<syntaxhighlight lang="python">import copy, random
 
def bitcount(n):
return bin(n).count("1")
 
def reoderingSign(i, j):
k = i >> 1
sum = 0
while k != 0:
sum += bitcount(k & j)
k = k >> 1
return 1.0 if ((sum & 1) == 0) else -1.0
 
class Vector:
def __init__(self, da):
self.dims = da
 
def dot(self, other):
return (self * other + other * self) * 0.5
 
def __getitem__(self, i):
return self.dims[i]
 
def __setitem__(self, i, v):
self.dims[i] = v
 
def __neg__(self):
return self * -1.0
 
def __add__(self, other):
result = copy.copy(other.dims)
for i in xrange(0, len(self.dims)):
result[i] += self.dims[i]
return Vector(result)
 
def __mul__(self, other):
if isinstance(other, Vector):
result = [0.0] * 32
for i in xrange(0, len(self.dims)):
if self.dims[i] != 0.0:
for j in xrange(0, len(self.dims)):
if other.dims[j] != 0.0:
s = reoderingSign(i, j) * self.dims[i] * other.dims[j]
k = i ^ j
result[k] += s
return Vector(result)
else:
result = copy.copy(self.dims)
for i in xrange(0, len(self.dims)):
self.dims[i] *= other
return Vector(result)
 
def __str__(self):
return str(self.dims)
 
def e(n):
assert n <= 4, "n must be less than 5"
result = Vector([0.0] * 32)
result[1 << n] = 1.0
return result
 
def randomVector():
result = Vector([0.0] * 32)
for i in xrange(0, 5):
result += Vector([random.uniform(0, 1)]) * e(i)
return result
 
def randomMultiVector():
result = Vector([0.0] * 32)
for i in xrange(0, 32):
result[i] = random.uniform(0, 1)
return result
 
def main():
for i in xrange(0, 5):
for j in xrange(0, 5):
if i < j:
if e(i).dot(e(j))[0] != 0.0:
print "Unexpected non-null scalar product"
return
elif i == j:
if e(i).dot(e(j))[0] == 0.0:
print "Unexpected non-null scalar product"
 
a = randomMultiVector()
b = randomMultiVector()
c = randomMultiVector()
x = randomVector()
 
# (ab)c == a(bc)
print (a * b) * c
print a * (b * c)
print
 
# a(b+c) == ab + ac
print a * (b + c)
print a * b + a * c
print
 
# (a+b)c == ac + bc
print (a + b) * c
print a * c + b * c
print
 
# x^2 is real
print x * x
 
main()</syntaxhighlight>
{{out}}
<pre>[2.646777769717816, -5.480686120935684, -8.183342078006843, -9.178717618666656, -0.21247781959240397, -3.1560121872423172, -14.210376795019405, -7.975576839132462, -2.963314079857538, -8.128489630952732, 8.84291288803876, 6.849688422048398, -3.948403894153645, -6.3295864734054295, 0.858339386946704, 0.04073276768257372, -0.8170168057484614, -5.987310468330181, -5.089567141509365, -6.5916164371098205, 1.066652018944462, -0.7553724661211869, -16.61957782752131, -10.74332838047719, -0.22326945346944393, -5.502857138805277, 11.833089760883906, 11.020055749901102, -3.7471254230186233, -3.5483496341413763, 7.788213699886802, 5.385261642366723]
[2.6467777697178145, -5.480686120935683, -8.183342078006845, -9.178717618666658, -0.2124778195924022, -3.156012187242318, -14.210376795019414, -7.975576839132467, -2.9633140798575406, -8.128489630952735, 8.842912888038763, 6.849688422048397, -3.9484038941536435, -6.329586473405431, 0.8583393869467044, 0.04073276768257594, -0.8170168057484637, -5.987310468330179, -5.089567141509367, -6.591616437109819, 1.0666520189444642, -0.7553724661211856, -16.61957782752132, -10.743328380477191, -0.22326945346944407, -5.502857138805281, 11.83308976088391, 11.0200557499011, -3.7471254230186246, -3.5483496341413807, 7.7882136998868035, 5.385261642366723]
 
[-4.45416862548425, -4.007728055936393, 2.2599167577088886, -0.5008511526260965, 6.404388731518947, 3.553799027487341, -1.4559344997025763, 1.200629741306491, 0.28084755190469957, 1.6881017142666677, 4.622735951152484, 2.042861306698215, -1.1859431529346458, -0.23268120656473645, 3.3088499800790308, 6.272881551311293, -6.283417063207868, -6.059129990387314, 0.9004412097752342, 0.540839567518711, 2.9772708785233157, 2.2875667777090625, 1.6049404915540564, 4.551625497411361, 3.4613544600410537, 4.601629280006443, 4.934029921827034, 3.0257810667323715, -1.280636387447562, -0.21306231994217983, 6.089428007073901, 8.128821330734313]
[-4.454168625484251, -4.007728055936392, 2.259916757708888, -0.5008511526260957, 6.404388731518948, 3.553799027487342, -1.455934499702577, 1.2006297413064915, 0.2808475519046991, 1.688101714266668, 4.622735951152485, 2.0428613066982155, -1.1859431529346458, -0.23268120656473568, 3.30884998007903, 6.272881551311293, -6.283417063207869, -6.059129990387315, 0.9004412097752316, 0.5408395675187101, 2.9772708785233157, 2.287566777709062, 1.6049404915540577, 4.551625497411363, 3.4613544600410533, 4.601629280006441, 4.934029921827035, 3.025781066732372, -1.2806363874475617, -0.21306231994217995, 6.0894280070738995, 8.128821330734311]
 
[-4.713407548689167, -5.470701972164317, 0.2834720300902142, -1.8843569665485043, 2.8883659013514302, 3.6276355158044815, -2.7614493177411843, 0.14095340884428206, -1.191066813989091, 1.1017933922740846, 2.995254519836379, 1.5249479602578073, 2.153333527417164, 1.999841187299821, 6.220565393668025, 8.730809912614522, -7.61200478654088, -9.557862449328784, 1.432009511995673, 0.14006605762543944, 1.450154388175902, 2.5115288790301835, -1.5609458922816675, 1.9148273860716452, 3.56683599400551, 3.9854109527025505, 3.6838872880534086, 3.059534508634617, 3.237048050921782, 2.674541802512928, 6.252577743980652, 7.309261452099341]
[-4.713407548689167, -5.470701972164316, 0.28347203009021416, -1.8843569665485043, 2.8883659013514302, 3.6276355158044815, -2.761449317741185, 0.14095340884428198, -1.1910668139890919, 1.101793392274085, 2.9952545198363785, 1.5249479602578067, 2.153333527417164, 1.9998411872998219, 6.220565393668025, 8.730809912614523, -7.612004786540879, -9.557862449328784, 1.4320095119956717, 0.14006605762543944, 1.4501543881759016, 2.511528879030183, -1.5609458922816672, 1.9148273860716456, 3.5668359940055105, 3.985410952702549, 3.683887288053409, 3.0595345086346164, 3.2370480509217803, 2.6745418025129273, 6.252577743980652, 7.30926145209934]
 
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]</pre>
 
=={{header|Raku}}==
(formerly Perl 6)
 
Here we write a simplified version of the [https://github.com/grondilu/clifford Clifford] module. It is very general as it is of infinite dimension and also contains an anti-euclidean basis @ē in addition to the euclidean basis @e.
 
<syntaxhighlight lang="raku" line>class MultiVector is Mix {
subset Vector of ::?CLASS is export where *.grades.all == 1;
 
method narrow { self.keys.any > 0 ?? self !! (self{0} // 0) }
method grades { self.keys.map: *.base(2).comb.sum }
 
multi method new(Real $x) returns ::?CLASS { self.new-from-pairs: 0 => $x }
multi method new(Str $ where /^^e(\d+)$$/) { self.new-from-pairs: (1 +< (2*$0)) => 1 }
 
our @e is export = map { ::?CLASS.new: "e$_" }, ^Inf;
 
my sub order(UInt:D $i is copy, UInt:D $j) {
(state %){$i}{$j} //= do {
my $n = 0;
repeat {
$i +>= 1;
$n += [+] ($i +& $j).polymod(2 xx *);
} until $i == 0;
$n +& 1 ?? -1 !! 1;
}
}
 
sub infix:<·>(Vector $x, Vector $y) returns Real is export { (($x*$y + $y*$x)/2){0} }
multi infix:<+>(::?CLASS $A, ::?CLASS $B) returns ::?CLASS is export {
return ::?CLASS.new-from-pairs: |$A.pairs, |$B.pairs;
}
multi infix:<+>(Real $s, ::?CLASS $B) returns ::?CLASS is export {
samewith $B.new($s), $B
}
multi infix:<+>(::?CLASS $A, Real $s) returns ::?CLASS is export {
samewith $s, $A
}
 
multi infix:<*>(::?CLASS $, 0) is export { 0 }
multi infix:<*>(::?CLASS $A, 1) returns ::?CLASS is export { $A }
multi infix:<*>(::?CLASS $A, Real $s) returns ::?CLASS is export {
::?CLASS.new-from-pairs: $A.pairs.map({Pair.new: .key, $s*.value})
}
multi infix:<*>(::?CLASS $A, ::?CLASS $B) returns ::?CLASS is export {
::?CLASS.new-from-pairs: gather
for $A.pairs -> $a {
for $B.pairs -> $b {
take ($a.key +^ $b.key) => [*]
$a.value, $b.value,
order($a.key, $b.key),
|grep +*, (
|(1, -1) xx * Z*
($a.key +& $b.key).polymod(2 xx *)
)
}
}
}
multi infix:<**>(::?CLASS $ , 0) returns ::?CLASS is export { ::?CLASS.new: (0 => 1).Mix }
multi infix:<**>(::?CLASS $A, 1) returns ::?CLASS is export { $A }
multi infix:<**>(::?CLASS $A, 2) returns ::?CLASS is export { $A * $A }
multi infix:<**>(::?CLASS $A, UInt $n where $n %% 2) returns ::?CLASS is export { ($A ** ($n div 2)) ** 2 }
multi infix:<**>(::?CLASS $A, UInt $n) returns ::?CLASS is export { $A * ($A ** ($n div 2)) ** 2 }
 
multi infix:<*>(Real $s, ::?CLASS $A) returns ::?CLASS is export { $A * $s }
multi infix:</>(::?CLASS $A, Real $s) returns ::?CLASS is export { $A * (1/$s) }
multi prefix:<->(::?CLASS $A) returns ::?CLASS is export { return -1 * $A }
multi infix:<->(::?CLASS $A, ::?CLASS $B) returns ::?CLASS is export { $A + -$B }
multi infix:<->(::?CLASS $A, Real $s) returns ::?CLASS is export { $A + -$s }
multi infix:<->(Real $s, ::?CLASS $A) returns ::?CLASS is export { $s + -$A }
 
multi infix:<==>(::?CLASS $A, 0) returns Bool is export { $A.elems == 0 }
multi infix:<==>(::?CLASS $A, ::?CLASS $B) returns Bool is export { samewith $A - $B, 0 }
multi infix:<==>(Real $x, ::?CLASS $A) returns Bool is export { samewith $A, $x }
multi infix:<==>(::?CLASS $A, Real $x) returns Bool is export { samewith $A, $A.new($x); }
 
sub random is export {
[+] map {
::?CLASS.new-from-pairs: $_ => rand.round(.01)
}, ^32;
}
}
 
#########################################
my ($a, $b, $c) = random() xx 3;
## Test code to verify the solution: ##
#########################################
 
import MultiVector;
use Test;
constant N = 10;
plan 5;
subtest "Orthonormality", {
for ^N X ^N -> ($i, $j) {
my $s = $i == $j ?? 1 !! 0;
ok @e[$i]·@e[$j] == $s, "e$i·e$j = $s";
}
}
my ($a, $b, $c) = random() xx 3;
ok ($a*$b)*$c == $a*($b*$c), 'associativity';
ok $a*($b + $c) == $a*$b + $a*$c, 'left distributivity';
ok ($a + $b)*$c == $a*$c + $b*$c, 'right distributivity';
my @coeff = (.5 - rand) xx 45;
my $v = [+] @coeff Z* map &@e, [^45];
ok ($v**2).narrow ~~ Real, 'contraction';</langsyntaxhighlight>
 
=={{header|Visual Basic .NET}}==
{{trans|C#}}
<syntaxhighlight lang="vbnet">Option Strict On
 
Imports System.Text
 
Module Module1
 
Structure Vector
Private ReadOnly dims() As Double
 
Public Sub New(da() As Double)
dims = da
End Sub
 
Public Shared Operator -(v As Vector) As Vector
Return v * -1.0
End Operator
 
Public Shared Operator +(lhs As Vector, rhs As Vector) As Vector
Dim result(31) As Double
Array.Copy(lhs.dims, 0, result, 0, lhs.Length)
For i = 1 To result.Length
Dim i2 = i - 1
result(i2) = lhs(i2) + rhs(i2)
Next
Return New Vector(result)
End Operator
 
Public Shared Operator *(lhs As Vector, rhs As Vector) As Vector
Dim result(31) As Double
For i = 1 To lhs.Length
Dim i2 = i - 1
If lhs(i2) <> 0.0 Then
For j = 1 To lhs.Length
Dim j2 = j - 1
If rhs(j2) <> 0.0 Then
Dim s = ReorderingSign(i2, j2) * lhs(i2) * rhs(j2)
Dim k = i2 Xor j2
result(k) += s
End If
Next
End If
Next
Return New Vector(result)
End Operator
 
Public Shared Operator *(v As Vector, scale As Double) As Vector
Dim result = CType(v.dims.Clone, Double())
For i = 1 To result.Length
Dim i2 = i - 1
result(i2) *= scale
Next
Return New Vector(result)
End Operator
 
Default Public Property Index(key As Integer) As Double
Get
Return dims(key)
End Get
Set(value As Double)
dims(key) = value
End Set
End Property
 
Public ReadOnly Property Length As Integer
Get
Return dims.Length
End Get
End Property
 
Public Function Dot(rhs As Vector) As Vector
Return (Me * rhs + rhs * Me) * 0.5
End Function
 
Private Shared Function BitCount(i As Integer) As Integer
i -= ((i >> 1) And &H55555555)
i = (i And &H33333333) + ((i >> 2) And &H33333333)
i = (i + (i >> 4)) And &HF0F0F0F
i += (i >> 8)
i += (i >> 16)
Return i And &H3F
End Function
 
Private Shared Function ReorderingSign(i As Integer, j As Integer) As Double
Dim k = i >> 1
Dim sum = 0
While k <> 0
sum += BitCount(k And j)
k >>= 1
End While
Return If((sum And 1) = 0, 1.0, -1.0)
End Function
 
Public Overrides Function ToString() As String
Dim it = dims.GetEnumerator
 
Dim sb As New StringBuilder("[")
If it.MoveNext() Then
sb.Append(it.Current)
End If
While it.MoveNext
sb.Append(", ")
sb.Append(it.Current)
End While
sb.Append("]")
Return sb.ToString
End Function
End Structure
 
Function DoubleArray(size As Integer) As Double()
Dim result(size - 1) As Double
For i = 1 To size
Dim i2 = i - 1
result(i2) = 0.0
Next
Return result
End Function
 
Function E(n As Integer) As Vector
If n > 4 Then
Throw New ArgumentException("n must be less than 5")
End If
 
Dim result As New Vector(DoubleArray(32))
result(1 << n) = 1.0
Return result
End Function
 
ReadOnly r As New Random()
 
Function RandomVector() As Vector
Dim result As New Vector(DoubleArray(32))
For i = 1 To 5
Dim i2 = i - 1
Dim singleton() As Double = {r.NextDouble()}
result += New Vector(singleton) * E(i2)
Next
Return result
End Function
 
Function RandomMultiVector() As Vector
Dim result As New Vector(DoubleArray(32))
For i = 1 To result.Length
Dim i2 = i - 1
result(i2) = r.NextDouble()
Next
Return result
End Function
 
Sub Main()
For i = 1 To 5
Dim i2 = i - 1
For j = 1 To 5
Dim j2 = j - 1
If i2 < j2 Then
If E(i2).Dot(E(j2))(0) <> 0.0 Then
Console.Error.WriteLine("Unexpected non-null scalar product")
Return
End If
ElseIf i2 = j2 Then
If E(i2).Dot(E(j2))(0) = 0.0 Then
Console.Error.WriteLine("Unexpected null scalar product")
Return
End If
End If
Next
Next
 
Dim a = RandomMultiVector()
Dim b = RandomMultiVector()
Dim c = RandomMultiVector()
Dim x = RandomVector()
 
' (ab)c == a(bc)
Console.WriteLine((a * b) * c)
Console.WriteLine(a * (b * c))
Console.WriteLine()
 
' a(b+c) == ab + ac
Console.WriteLine(a * (b + c))
Console.WriteLine(a * b + a * c)
Console.WriteLine()
 
' (a+b)c == ac + bc
Console.WriteLine((a + b) * c)
Console.WriteLine(a * c + b * c)
Console.WriteLine()
 
' x^2 is real
Console.WriteLine(x * x)
End Sub
 
End Module</syntaxhighlight>
{{out}}
<pre>[0.574263754349833, -1.04033308353824, -0.776121961159351, 2.00792496222078, 3.16921091358851, 6.73557610270275, -13.4327886840529, -7.74195172209513, -7.21674283588092, -5.86045645950882, 2.22312083899981, 1.32215440847646, -6.14796858424355, -6.31067579900569, -8.24016821785677, -7.13138966213629, 1.70037903072841, -1.61670055512076, -1.53920826677554, 0.0830404550813257, 3.93618132588852, 7.40029585163889, -6.36594388310886, 2.14605789872596, -12.3353817163416, -9.51720072572794, 4.57164353732716, 3.11601890765627, -3.45821025466289, -4.2333151576991, -5.88080545860622, -6.53549242641427]
<pre>1..29
[0.574263754349836, -1.04033308353825, -0.776121961159348, 2.00792496222078, 3.16921091358851, 6.73557610270275, -13.4327886840529, -7.74195172209514, -7.21674283588092, -5.86045645950883, 2.2231208389998, 1.32215440847646, -6.14796858424355, -6.31067579900569, -8.24016821785676, -7.13138966213629, 1.70037903072841, -1.61670055512076, -1.53920826677554, 0.0830404550813244, 3.93618132588852, 7.40029585163889, -6.36594388310886, 2.14605789872596, -12.3353817163416, -9.51720072572794, 4.57164353732716, 3.11601890765627, -3.4582102546629, -4.2333151576991, -5.88080545860622, -6.53549242641427]
ok 1 - e0 cdot e0 = 1
 
ok 2 - e0 cdot e1 = 0
[-4.47297646716049, -5.51675159908628, -2.0422292306007, -2.10280367601528, 4.45365145957714, 3.36803601730516, -1.14571129439412, -0.425208328771765, 1.55145295736126, 1.59542278752789, 5.96209903766593, 3.43000773717995, -1.93701906000176, -0.282031417434974, 2.27435916727966, 5.57909608271093, -4.5313823118833, -5.23492105300004, -1.61573387363407, -2.77225954890565, 2.7749883436186, 2.47317184825279, -1.66854919690689, -1.04001004327011, 0.314038463700274, 0.354414497531512, 6.65882395905864, 4.84274526210668, -1.26994943017024, 0.867830239054973, 5.4316876690133, 8.85070336472853]
ok 3 - e0 cdot e2 = 0
[-4.47297646716048, -5.51675159908628, -2.0422292306007, -2.10280367601528, 4.45365145957714, 3.36803601730516, -1.14571129439412, -0.425208328771764, 1.55145295736126, 1.59542278752789, 5.96209903766592, 3.43000773717995, -1.93701906000176, -0.282031417434974, 2.27435916727966, 5.57909608271093, -4.5313823118833, -5.23492105300004, -1.61573387363407, -2.77225954890565, 2.7749883436186, 2.47317184825279, -1.66854919690689, -1.04001004327011, 0.314038463700274, 0.354414497531512, 6.65882395905864, 4.84274526210668, -1.26994943017024, 0.867830239054973, 5.4316876690133, 8.85070336472853]
ok 4 - e0 cdot e3 = 0
 
ok 5 - e0 cdot e4 = 0
[-5.22293180574195, -5.83486719133951, -1.69911127655253, -0.239172378976677, 2.88101068267363, 3.97970294192276, -3.56156896393757, -2.61790431554284, -0.736020241689734, -0.776473740587332, 3.0171422268862, 2.15992705303214, -3.20043960767084, -0.644050812810021, 0.714338263909879, 1.74591314489993, -4.38202839888319, -3.26051280533051, -4.05531615492948, -2.93703039040279, 3.56583825504966, 4.17636250632614, -1.11524349520128, -3.21090579244331, 1.27680857237575, 2.37418947249269, 4.48848909104827, 3.7920821695994, -3.71929857788004, 0.286175312382222, 6.0485010014393, 8.27326094456212]
ok 6 - e1 cdot e0 = 0
[-5.22293180574195, -5.83486719133951, -1.69911127655253, -0.239172378976677, 2.88101068267363, 3.97970294192276, -3.56156896393757, -2.61790431554284, -0.736020241689734, -0.776473740587333, 3.0171422268862, 2.15992705303214, -3.20043960767084, -0.644050812810022, 0.71433826390988, 1.74591314489993, -4.38202839888319, -3.2605128053305, -4.05531615492948, -2.93703039040279, 3.56583825504966, 4.17636250632614, -1.11524349520128, -3.21090579244331, 1.27680857237575, 2.37418947249269, 4.48848909104827, 3.7920821695994, -3.71929857788004, 0.286175312382223, 6.0485010014393, 8.27326094456212]
ok 7 - e1 cdot e1 = 1
 
ok 8 - e1 cdot e2 = 0
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]</pre>
ok 9 - e1 cdot e3 = 0
 
ok 10 - e1 cdot e4 = 0
=={{header|Wren}}==
ok 11 - e2 cdot e0 = 0
{{trans|Kotlin}}
ok 12 - e2 cdot e1 = 0
<syntaxhighlight lang="wren">import "random" for Random
ok 13 - e2 cdot e2 = 1
 
ok 14 - e2 cdot e3 = 0
var bitCount = Fn.new { |i|
ok 15 - e2 cdot e4 = 0
ok 16 i = i - e3((i cdot>> e01) =& 00x55555555)
i = (i & 0x33333333) + ((i >> 2) & 0x33333333)
ok 17 - e3 cdot e1 = 0
i = (i + (i >> 4)) & 0x0f0f0f0f
ok 18 - e3 cdot e2 = 0
ok 19 - e3 cdot e3i = 1i + (i >> 8)
ok 20 - e3 cdot e4i = 0i + (i >> 16)
ok 21 - e4 cdotreturn e0i =& 00x0000003F
}
ok 22 - e4 cdot e1 = 0
 
ok 23 - e4 cdot e2 = 0
var ReorderingSign = Fn.new { |i, j|
ok 24 - e4 cdot e3 = 0
ok 25 - e4 cdotvar e4k = i >> 1
var sum = 0
ok 26 - associativity
while (k != 0) {
ok 27 - left distributivity
sum = sum + bitCount.call(k & j)
ok 28 - right distributivity
k = k >> 1
ok 29 - contraction</pre>
}
return (sum & 1 == 0) ? 1 : -1
}
 
class Vector {
construct new(dims) {
_dims = dims
}
 
dims { _dims }
 
dot(rhs) { (this * rhs + rhs * this) * 0.5 }
 
- { this * -1 }
 
+(rhs) {
var result = List.filled(32, 0)
for (i in 0..._dims.count) result[i] = _dims[i]
for (i in 0...rhs.dims.count) result[i] = result[i] + rhs[i]
return Vector.new(result)
}
 
*(rhs) {
if (rhs is Vector) {
var result = List.filled(32, 0)
for (i in 0..._dims.count) {
if (_dims[i] != 0) {
for (j in 0...rhs.dims.count) {
if (rhs[j] != 0) {
var s = ReorderingSign.call(i, j) * _dims[i] * rhs[j]
var k = i ^ j
result[k] = result[k] + s
}
}
}
}
return Vector.new(result)
} else if (rhs is Num) {
var result = _dims.toList
for (i in 0..4) dims[i] = dims[i] * rhs
return Vector.new(result)
} else {
Fiber.abort("rhs must either be a Vector or a number")
}
}
 
[index] { _dims[index] }
 
[index]=(value) { _dims[index] = value }
 
toString { "(" + _dims.join(", ") + ")" }
}
 
var e = Fn.new { |n|
if (n > 4) Fiber.abort("n must be less than 5")
var result = Vector.new(List.filled(32, 0))
result[1 << n] = 1
return result
}
 
var rand = Random.new()
 
var randomVector = Fn.new {
var result = Vector.new(List.filled(32, 0))
for (i in 0..4) {
result = result + Vector.new([rand.float()]) * e.call(i)
}
return result
}
 
var randomMultiVector = Fn.new {
var result = Vector.new(List.filled(32, 0))
for (i in 0..31) result[i] = rand.float()
return result
}
 
for (i in 0..4) {
for (j in 0..4) {
if (i < j) {
if (e.call(i).dot(e.call(j))[0] != 0) {
System.print("Unexpected non-null scalar product.")
return
} else if (i == j) {
if (e.call(i).dot(e.call(j))[0] == 0) {
System.print("Unexpected null scalar product.")
}
}
}
}
}
 
var a = randomMultiVector.call()
var b = randomMultiVector.call()
var c = randomMultiVector.call()
var x = randomVector.call()
 
// (ab)c == a(bc)
System.print((a * b) * c)
System.print(a * (b * c))
System.print()
 
// a(b+c) == ab + ac
System.print(a * (b + c))
System.print(a * b + a * c)
System.print()
 
// (a+b)c == ac + bc
System.print((a + b) * c)
System.print(a * c + b * c)
System.print()
 
// x^2 is real
System.print(x * x)</syntaxhighlight>
 
{{out}}
<pre>
(-6.1279343499972, -12.172471890613, -0.43596654360835, -9.4733600789769, 7.7468131011607, -1.0197449680744, -8.3386053167094, -4.514411938465, -0.85417113341489, 5.814264590591, 4.7534441812565, 3.6983892972325, -1.9487633151975, 1.0081516771802, 3.793528331478, -0.71739309800609, -5.0930834896765, -10.389798935116, -0.21991874396827, -9.2747185990727, 2.4902263109011, -1.217404792573, -7.5648404539069, -5.1713187775853, -4.9297458419615, -2.5365579590808, 5.6741886500532, -5.3820954955896, 0.84309276379896, -0.83865672543758, -6.6627947524069, -6.5068089919902)
(-6.1279343499972, -12.172471890613, -0.43596654360835, -9.4733600789769, 7.7468131011607, -1.0197449680744, -8.3386053167094, -4.514411938465, -0.85417113341489, 5.814264590591, 4.7534441812565, 3.6983892972325, -1.9487633151975, 1.0081516771802, 3.793528331478, -0.71739309800609, -5.0930834896765, -10.389798935116, -0.21991874396827, -9.2747185990727, 2.4902263109011, -1.217404792573, -7.5648404539069, -5.1713187775853, -4.9297458419615, -2.5365579590808, 5.6741886500532, -5.3820954955896, 0.84309276379896, -0.83865672543757, -6.6627947524069, -6.5068089919902)
 
(-4.5670205884692, -5.406285276749, 0.20435321499717, -4.7297569961965, 3.1536400277791, 4.3228858614581, -2.648422809333, -1.1833380429978, -1.7564258015137, 3.3290322042955, 4.1877600392827, 5.7622202559563, -2.6969120760046, 1.6040264499734, 1.7140507294369, 3.3982272822008, -2.7897066050195, -2.800819409065, 2.2770258183891, -1.3567979021271, 2.4379457462826, 4.9315720878673, -1.8523904994524, 0.57286280886659, 0.78942446076958, 3.2321401010964, 2.7052700803603, 4.1875465627791, -1.9573353620592, 3.042768958901, 0.55331226143665, 3.4813647018728)
(-4.5670205884692, -5.406285276749, 0.20435321499716, -4.7297569961965, 3.1536400277791, 4.3228858614581, -2.648422809333, -1.1833380429978, -1.7564258015137, 3.3290322042955, 4.1877600392827, 5.7622202559563, -2.6969120760046, 1.6040264499734, 1.7140507294369, 3.3982272822008, -2.7897066050195, -2.800819409065, 2.2770258183891, -1.3567979021271, 2.4379457462826, 4.9315720878673, -1.8523904994524, 0.57286280886659, 0.78942446076958, 3.2321401010964, 2.7052700803603, 4.1875465627791, -1.9573353620592, 3.042768958901, 0.55331226143665, 3.4813647018728)
 
(-6.4947965411446, -7.5334457985612, -0.48336700984287, -2.6235798111818, 3.6406622303652, 3.6398682775911, -1.8835092927705, -4.0165723310492, 1.6332945757193, 5.2056992102457, 4.202039318349, 7.3784879794787, -2.4843920053947, -0.47893361628939, 1.1220802570638, 2.693375877108, -1.278951846965, -2.5982492127516, 0.85382005828955, -0.077629574978695, 5.211354827205, 6.5199779982554, 0.85742615796087, -0.062281151554669, -1.4540738133743, 1.6710486134883, 3.8433969630048, 6.4484021393956, 2.8236029776283, 2.9302728085944, 1.3066828942527, 3.7490534064109)
(-6.4947965411446, -7.5334457985612, -0.48336700984287, -2.6235798111818, 3.6406622303652, 3.6398682775912, -1.8835092927705, -4.0165723310492, 1.6332945757193, 5.2056992102457, 4.202039318349, 7.3784879794787, -2.4843920053947, -0.47893361628939, 1.1220802570638, 2.693375877108, -1.278951846965, -2.5982492127516, 0.85382005828955, -0.077629574978696, 5.211354827205, 6.5199779982554, 0.85742615796087, -0.062281151554668, -1.4540738133743, 1.6710486134883, 3.8433969630048, 6.4484021393956, 2.8236029776283, 2.9302728085944, 1.3066828942527, 3.7490534064109)
 
(0.96552083436649, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
</pre>
2,122

edits