Task: Geometric algebra




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()

    
    fmt.Println(mul(mul(a, b), c))
    fmt.Println(mul(a, mul(b, c)))

    
    fmt.Println(mul(a, add(b, c)))
    fmt.Println(add(mul(a, b), mul(a, c)))

    
    fmt.Println(mul(add(a, b), c))
    fmt.Println(add(mul(a, c), mul(b, c)))

    
    fmt.Println(mul(x, x))
}


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();

        
        System.out.println(a.times(b).times(c));
        System.out.println(a.times(b.times(c)));
        System.out.println();

        
        System.out.println(a.times(b.plus(c)));
        System.out.println(a.times(b).plus(a.times(c)));
        System.out.println();

        
        System.out.println(a.plus(b).times(c));
        System.out.println(a.times(c).plus(b.times(c)));
        System.out.println();

        
        System.out.println(x.times(x));
    }
}