Task: Tropical algebra overloading




Go: package main

import (
    "fmt"
    "log"
    "math"
)

var MinusInf = math.Inf(-1)

type MaxTropical struct{ r float64 }

func newMaxTropical(r float64) MaxTropical {
    if math.IsInf(r, 1) || math.IsNaN(r) {
        log.Fatal("Argument must be a real number or negative infinity.")
    }
    return MaxTropical{r}
}

func (t MaxTropical) eq(other MaxTropical) bool {
    return t.r == other.r
}


func (t MaxTropical) add(other MaxTropical) MaxTropical {
    if t.r == MinusInf {
        return other
    }
    if other.r == MinusInf {
        return t
    }
    return newMaxTropical(math.Max(t.r, other.r))
}


func (t MaxTropical) mul(other MaxTropical) MaxTropical {
    if t.r == 0 {
        return other
    }
    if other.r == 0 {
        return t
    }
    return newMaxTropical(t.r + other.r)
}


func (t MaxTropical) pow(e int) MaxTropical {
    if e < 1 {
        log.Fatal("Exponent must be a positive integer.")
    }
    if e == 1 {
        return t
    }
    p := t
    for i := 2; i <= e; i++ {
        p = p.mul(t)
    }
    return p
}

func (t MaxTropical) String() string {
    return fmt.Sprintf("%g", t.r)
}

func main() {
    
    data := [][]float64{
        {2, -2, 1},
        {-0.001, MinusInf, 0},
        {0, MinusInf, 1},
        {1.5, -1, 0},
        {-0.5, 0, 1},
    }
    for _, d := range data {
        a := newMaxTropical(d[0])
        b := newMaxTropical(d[1])
        if d[2] == 0 {
            fmt.Printf("%s ⊕ %s = %s\n", a, b, a.add(b))
        } else {
            fmt.Printf("%s ⊗ %s = %s\n", a, b, a.mul(b))
        }
    }

    c := newMaxTropical(5)
    fmt.Printf("%s ^ 7 = %s\n", c, c.pow(7))

    d := newMaxTropical(8)
    e := newMaxTropical(7)
    f := c.mul(d.add(e))
    g := c.mul(d).add(c.mul(e))
    fmt.Printf("%s ⊗ (%s ⊕ %s) = %s\n", c, d, e, f)
    fmt.Printf("%s ⊗ %s ⊕ %s ⊗ %s = %s\n", c, d, c, e, g)
    fmt.Printf("%s ⊗ (%s ⊕ %s) == %s ⊗ %s ⊕ %s ⊗ %s is %t\n", c, d, e, c, d, c, e, f.eq(g))
}




Python: from numpy import Inf

class MaxTropical:
    
    def __init__(self, x=0):
        self.x = x

    def __str__(self):
        return str(self.x)

    def __add__(self, other):
        return MaxTropical(max(self.x, other.x))

    def __mul__(self, other):
        return MaxTropical(self.x + other.x)

    def __pow__(self, other):
        assert other.x // 1 == other.x and other.x > 0, "Invalid Operation" 
        return MaxTropical(self.x * other.x)

    def __eq__(self, other):
        return self.x == other.x


if __name__ == "__main__":
    a = MaxTropical(-2)
    b = MaxTropical(-1)
    c = MaxTropical(-0.5)
    d = MaxTropical(-0.001)
    e = MaxTropical(0)
    f = MaxTropical(0.5)
    g = MaxTropical(1)
    h = MaxTropical(1.5)
    i = MaxTropical(2)
    j = MaxTropical(5)
    k = MaxTropical(7)
    l = MaxTropical(8)
    m = MaxTropical(-Inf)

    print("2 * -2 == ", i * a)
    print("-0.001 + -Inf == ", d + m)
    print("0 * -Inf == ", e * m)
    print("1.5 + -1 == ", h + b)
    print("-0.5 * 0 == ", c * e)
    print("5**7 == ", j**k)
    print("5 * (8 + 7)) == ", j * (l + k))
    print("5 * 8 + 5 * 7 == ", j * l + j * k)
    print("5 * (8 + 7) == 5 * 8 + 5 * 7", j * (l + k) == j * l + j * k)