Geometric algebra: Difference between revisions

Added FreeBASIC
(Added FreeBASIC)
 
(21 intermediate revisions by 8 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 53:
<br><br>
 
=={{header|C++ sharp|C#}}==
{{trans|D}}
<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;
}</lang>
{{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|C#|C sharp}}==
{{trans|D}}
<langsyntaxhighlight lang="csharp">using System;
using System.Text;
 
Line 419 ⟶ 237:
}
}
}</langsyntaxhighlight>
{{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]
Line 429 ⟶ 247:
[-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>
Line 434:
=={{header|D}}==
{{trans|Kotlin}}
<langsyntaxhighlight lang="d">import std.exception;
import std.random;
import std.stdio;
Line 586:
// x^2 is real
writeln(x * x);
}</langsyntaxhighlight>
{{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])
Line 602:
We build a CGA based upon a generating 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 715:
</syntaxhighlight>
</lang>
{{out}}
<langsyntaxhighlight lang="scheme">
;; we use indices (1 ... n) in conformity with the Wikipedia reference
 
Line 767:
(• II J K) → -1*1
 
</syntaxhighlight>
</lang>
Multiplication table for A(3 0)
 
Line 820:
<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}}
<langsyntaxhighlight lang="go">package main
 
import (
Line 950 ⟶ 1,066:
// x² is real
fmt.Println(mul(x, x))
}</langsyntaxhighlight>
 
{{out}}
Line 970 ⟶ 1,086:
Implementation:
 
<langsyntaxhighlight Jlang="j">NB. indices are signed machine integers
vzero=: 1 $.2^31+IF64*32
odim=. 2^.#vzero
Line 1,003 ⟶ 1,119:
 
obasis=:1 (2^i.odim)ndx01 vzero
e=: {&obasis</langsyntaxhighlight>
 
Explanation:
Line 1,027 ⟶ 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 1,070 ⟶ 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 1,185 ⟶ 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 1,198 ⟶ 1,487:
From Javascript.
 
<langsyntaxhighlight lang="javascript">/* Geometric Algebra, in Jsih */
 
var GA = function () {
Line 1,324 ⟶ 1,613:
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!=
*/</langsyntaxhighlight>
 
{{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}}
<langsyntaxhighlight lang="scala">fun bitCount(i: Int): Int {
var j = i
j -= ((j shr 1) and 0x55555555)
Line 1,481 ⟶ 1,840:
// x^2 is real
println(x * x)
}</langsyntaxhighlight>
{{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)
Line 1,494 ⟶ 1,853:
(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|Perl 6Nim}}==
{{trans|Go}}
<syntaxhighlight lang="nim">import bitops, random, sequtils, strutils
 
type Vector = seq[float]
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.
 
func reorderingSign(i, j: int): float =
<lang perl6>unit class MultiVector;
var i = i shr 1
subset UIntHash of MixHash where .keys.all ~~ UInt;
var sum = 0
has UIntHash $.blades;
while i != 0:
method narrow { $!blades.keys.any > 0 ?? self !! ($!blades{0} // 0) }
sum += countSetBits(i and j)
i = i shr 1
result = if (sum and 1) == 0: 1 else: -1
 
func e(n: Natural): Vector =
multi method new(Real $x) returns MultiVector { self.new: (0 => $x).MixHash }
result.setLen(32)
multi method new(UIntHash $blades) returns MultiVector { self.new: :$blades }
assert n < 5, "index must be less than 5; got $#.".format(n)
result[1 shl n] = 1
 
func `+`(a, b: Vector): Vector =
multi method new(Str $ where /^^e(\d+)$$/) { self.new: (1 +< (2*$0)).MixHash }
result.setLen(32)
multi method new(Str $ where /^^ē(\d+)$$/) { self.new: (1 +< (2*$0 + 1)).MixHash }
for i in 0..b.high:
result[i] = a[i] + b[i]
 
func `*`(a, b: Vector): Vector =
our @e is export = map { MultiVector.new: "e$_" }, ^Inf;
result.setLen(32)
our @ē is export = map { MultiVector.new: "ē$_" }, ^Inf;
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 =
my sub order(UInt:D $i is copy, UInt:D $j) {
(a * b + b * a) * @[0.5]
(state %){$i}{$j} //= do {
my $n = 0;
repeat {
$i +>= 1;
$n += [+] ($i +& $j).polymod(2 xx *);
} until $i == 0;
$n +& 1 ?? -1 !! 1;
}
}
 
proc randomVector(): Vector =
multi infix:<+>(MultiVector $A, MultiVector $B) returns MultiVector is export {
result.setLen(32)
return MultiVector.new: ($A.blades.pairs, |$B.blades.pairs).MixHash;
for i in 0..4:
}
result = result + @[rand(1.0)] * e(i)
multi infix:<+>(Real $s, MultiVector $B) returns MultiVector is export {
return MultiVector.new: (0 => $s, |$B.blades.pairs).MixHash;
}
multi infix:<+>(MultiVector $A, Real $s) returns MultiVector is export { $s + $A }
 
proc randomMultiVector(): Vector =
multi infix:<*>(MultiVector $, 0) is export { 0 }
newSeqWith(32, rand(1.0))
multi infix:<*>(MultiVector $A, 1) returns MultiVector is export { $A }
multi infix:<*>(MultiVector $A, Real $s) returns MultiVector is export {
MultiVector.new: $A.blades.pairs.map({Pair.new: .key, $s*.value}).MixHash
}
multi infix:<*>(MultiVector $A, MultiVector $B) returns MultiVector is export {
MultiVector.new: do for $A.blades -> $a {
|do for $B.blades -> $b {
($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 *)
)
}
}.MixHash
}
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 }
 
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 }
 
when isMainModule:
multi infix:<==>(MultiVector $A, MultiVector $B) returns Bool is export { $A - $B == 0 }
multi infix:<==>(Real $x, MultiVector $A) returns Bool is export { $A == $x }
multi infix:<==>(MultiVector $A, Real $x) returns Bool is export {
my $narrowed = $A.narrow;
$narrowed ~~ Real and $narrowed == $x;
}
 
randomize()
#########################################
for i in 0..4:
## Test code to verify the solution: ##
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()
use Test;
let b = randomMultiVector()
let c = randomMultiVector()
plan 29;
let x = randomVector()
sub infix:<cdot>($x, $y) { ($x*$y + $y*$x)/2 }
for ^5 X ^5 -> ($i, $j) {
my $s = $i == $j ?? 1 !! 0;
ok @e[$i] cdot @e[$j] == $s, "e$i cdot e$j = $s";
}
sub random {
[+] map {
MultiVector.new:
:blades(($_ => rand.round(.01)).MixHash)
}, ^32;
}
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 5;
my $v = [+] @coeff Z* @e[^5];
ok ($v**2).narrow ~~ Real, 'contraction';</lang>
 
# (ab)c == a(bc).
=={{header|Phix}}==
echo (a * b) * c
{{trans|Go}}
echo a * (b * c)
<lang Phix>function bitCount(integer i)
echo()
return sum(sq_eq(sprintf("%b",i),'1')) -- (idea cribbed from Python)
end function
function reorderingSign(integer i, j)
i = floor(i/2)
integer tot := 0
while i!=0 do
tot += bitCount(and_bits(i,j))
i = floor(i/2)
end while
return iff(and_bits(tot,1)==0 ? 1 : -1)
end function
function add(sequence a, b)
return sq_add(a,b)
end function
 
# a(b + c) == ab + ac.
function mul(sequence a, b)
echo a sequence* result(b =+ repeat(0,32c)
echo a for* i=1b to+ length(a) do* c
echo()
if a[i]!=0 then
for j=1 to length(b) do
if b[j]!=0 then
atom s := reorderingSign(i-1, j-1) * a[i] * b[j]
integer k = xor_bits(i-1,j-1)+1
result[k] += s
end if
end for
end if
end for
return result
end function
function cdot(sequence a, b)
return mul({0.5}, add(mul(a, b), mul(b, a)))
end function
function e(integer n)
if n>4 then crash("n must be less than 5") end if
sequence result = repeat(0,32)
result[power(2,n)+1] = 1.0
return result
end function
--function neg(sequence x) -- (not actually used here)
-- return mul({-1}, x)
--end function
function randomVector()
sequence result = repeat(0,32)
for i=0 to 4 do
result = add(result, mul({rnd()}, e(i)))
end for
return result
end function
function randomMultiVector()
sequence result = repeat(0, 32)
for i=1 to 32 do
result[i] = rnd()
end for
return result
end function
 
# (a + b)c == ac + bc.
for i=0 to 4 do
echo (a for+ j=0b) to* 4 doc
echo a * c + b if* i < j thenc
echo()
if cdot(e(i), e(j))[1] != 0 then
crash("Unexpected non-null scalar product.")
end if
elsif i == j then
if cdot(e(i), e(j))[1] == 0 then
crash("Unexpected null scalar product.")
end if
end if
end for
end for
sequence a := randomMultiVector(),
b := randomMultiVector(),
c := randomMultiVector(),
x := randomVector(),
xsq = mul(x, x)
 
# x² is real.
procedure test(string txt, sequence a, b)
echo x * x</syntaxhighlight>
-- bool eq = (a==b) -- no!
bool eq = (sprint(a)==sprint(b)) -- ok!
printf(1,"%-20s: %s\n",{txt,iff(eq?"true","false")})
end procedure
test("(ab)c == a(bc)",mul(mul(a, b), c),
mul(a, mul(b, c)))
 
{{out}}
test("a(b + c) == ab + ac",mul(a, add(b, c)),
<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]
add(mul(a, b), mul(a, c)))
@[-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]
 
test("(a + b)c == ac + bc",mul(add(a, b), c),
@[-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]
add(mul(a, c), mul(b, c)))
@[-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]
 
test("x^2 is real",xsq,xsq[1]&repeat(0,31))</lang>
@[-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
Line 1,714 ⟶ 2,064:
=={{header|Python}}==
{{trans|D}}
<langsyntaxhighlight lang="python">import copy, random
 
def bitcount(n):
Line 1,821 ⟶ 2,171:
print x * x
 
main()</langsyntaxhighlight>
{{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]
Line 1,833 ⟶ 2,183:
 
[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;
}
}
 
#########################################
## 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 5;
my $v = [+] @coeff Z* @e[^5];
ok ($v**2).narrow ~~ Real, 'contraction';</syntaxhighlight>
 
=={{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]
[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]
 
[-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]
[-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]
 
[-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]
[-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]
 
[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|Wren}}==
{{trans|Kotlin}}
<syntaxhighlight lang="wren">import "random" for Random
 
var bitCount = Fn.new { |i|
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
}
 
var ReorderingSign = Fn.new { |i, j|
var k = i >> 1
var sum = 0
while (k != 0) {
sum = sum + bitCount.call(k & j)
k = k >> 1
}
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