Skip to content

Commit 59a22d6

Browse files
Add types TropicalMaxMin and TropicalBitwise. (#16)
* Add types `TropicalMaxMin` and `TropicalBitwise`. * fix CI * Update src/tropical_bitwise.jl * update * fix minplus --------- Co-authored-by: GiggleLiu <cacate0129@gmail.com>
1 parent 16c6444 commit 59a22d6

File tree

12 files changed

+394
-19
lines changed

12 files changed

+394
-19
lines changed

.github/workflows/TagBot.yml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,22 @@ on:
44
types:
55
- created
66
workflow_dispatch:
7+
inputs:
8+
lookback:
9+
default: 3
10+
permissions:
11+
actions: read
12+
checks: read
13+
contents: write
14+
deployments: read
15+
issues: read
16+
discussions: read
17+
packages: read
18+
pages: read
19+
pull-requests: read
20+
repository-projects: read
21+
security-events: read
22+
statuses: read
723
jobs:
824
TagBot:
925
if: github.event_name == 'workflow_dispatch' || github.actor == 'JuliaTagBot'

.github/workflows/ci.yml

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,24 @@
11
name: CI
22
on:
3-
- push
4-
- pull_request
3+
push:
4+
branches:
5+
- master
6+
tags: ['*']
7+
pull_request:
8+
workflow_dispatch:
9+
concurrency:
10+
# Skip intermediate builds: always.
11+
# Cancel intermediate builds: only if it is a pull request build.
12+
group: ${{ github.workflow }}-${{ github.ref }}
13+
cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }}
514
jobs:
615
test:
716
name: Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }} - ${{ github.event_name }}
817
runs-on: ${{ matrix.os }}
18+
timeout-minutes: 60
19+
permissions: # needed to allow julia-actions/cache to proactively delete old caches that it has created
20+
actions: write
21+
contents: read
922
strategy:
1023
fail-fast: false
1124
matrix:
@@ -17,24 +30,17 @@ jobs:
1730
arch:
1831
- x64
1932
steps:
20-
- uses: actions/checkout@v2
21-
- uses: julia-actions/setup-julia@v1
33+
- uses: actions/checkout@v4
34+
- uses: julia-actions/setup-julia@v2
2235
with:
2336
version: ${{ matrix.version }}
2437
arch: ${{ matrix.arch }}
25-
- uses: actions/cache@v1
26-
env:
27-
cache-name: cache-artifacts
28-
with:
29-
path: ~/.julia/artifacts
30-
key: ${{ runner.os }}-test-${{ env.cache-name }}-${{ hashFiles('**/Project.toml') }}
31-
restore-keys: |
32-
${{ runner.os }}-test-${{ env.cache-name }}-
33-
${{ runner.os }}-test-
34-
${{ runner.os }}-
38+
- uses: julia-actions/cache@v2
3539
- uses: julia-actions/julia-buildpkg@v1
3640
- uses: julia-actions/julia-runtest@v1
3741
- uses: julia-actions/julia-processcoverage@v1
38-
- uses: codecov/codecov-action@v1
42+
- uses: codecov/codecov-action@v5
3943
with:
40-
file: lcov.info
44+
files: lcov.info
45+
token: ${{ secrets.CODECOV_TOKEN }}
46+
slug: TensorBFS/TropicalNumbers.jl

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,11 @@ pkg> add TropicalNumbers
2323

2424
A Topical algebra can be described as a tuple $(R, \oplus, \otimes, \mathbb{0}, \mathbb{1})$, where $R$ is the set, $\oplus$ and $\otimes$ are the opeartions and $\mathbb{0}$, $\mathbb{1}$ are their identity element, respectively. In this package, the following tropical algebras are implemented:
2525
* `TropicalAndOr`: $([T, F], \lor, \land, F, T)$;
26+
* `TropicalBitwise`: $(\mathbb{T}, |, \&, 0, \sim 0)$
2627
* `Tropical` (`TropicalMaxPlus`): $(\mathbb{R}, \max, +, -\infty, 0)$;
2728
* `TropicalMinPlus`: $(\mathbb{R}, \min, +, \infty, 0)$;
2829
* `TropicalMaxMul`: $(\mathbb{R}^+, \max, \times, 0, 1)$.
30+
* `TropicalMaxMin`: $(\mathbb{R}^+, \max, \min, -\infty, \infty)$.
2931

3032
```julia
3133
julia> using TropicalNumbers

src/TropicalNumbers.jl

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@ export TropicalTypes, AbstractSemiring
55

66
export TropicalAndOr
77
export Tropical, TropicalF64, TropicalF32, TropicalF16, TropicalI64, TropicalI32, TropicalI16
8-
export TropicalMaxMul, TropicalMaxMulF64, TropicalMaxMulF32, TropicalMaxMulF16, TropicalMaxMulI64, TropicalMaxMulI32, TropicalMaxMulI16
98
export TropicalMaxPlus, TropicalMaxPlusF64, TropicalMaxPlusF32, TropicalMaxPlusF16, TropicalMaxPlusI64, TropicalMaxPlusI32, TropicalMaxPlusI16
109
export TropicalMinPlus, TropicalMinPlusF64, TropicalMinPlusF32, TropicalMinPlusF16, TropicalMinPlusI64, TropicalMinPlusI32, TropicalMinPlusI16
10+
export TropicalMaxMul, TropicalMaxMulF64, TropicalMaxMulF32, TropicalMaxMulF16, TropicalMaxMulI64, TropicalMaxMulI32, TropicalMaxMulI16
11+
export TropicalMaxMin, TropicalMaxMinF64, TropicalMaxMinF32, TropicalMaxMinF16, TropicalMaxMinI64, TropicalMaxMinI32, TropicalMaxMinI16
12+
export TropicalBitwise, TropicalBitwiseI64, TropicalBitwiseI32, TropicalBitwiseI16
1113
export CountingTropical, CountingTropicalF16, CountingTropicalF32, CountingTropicalF64, CountingTropicalI16, CountingTropicalI32, CountingTropicalI64
1214

1315

@@ -41,6 +43,8 @@ include("tropical_maxplus.jl")
4143
include("tropical_andor.jl")
4244
include("tropical_minplus.jl")
4345
include("tropical_maxmul.jl")
46+
include("tropical_maxmin.jl")
47+
include("tropical_bitwise.jl")
4448
include("counting_tropical.jl")
4549

4650
const TropicalTypes{T} = Union{CountingTropical{T}, Tropical{T}}
@@ -53,17 +57,20 @@ for NBIT in [16, 32, 64]
5357
@eval const $(Symbol(:TropicalMaxPlus, :F, NBIT)) = TropicalMaxPlus{$(Symbol(:Float, NBIT))}
5458
@eval const $(Symbol(:TropicalMinPlus, :F, NBIT)) = TropicalMinPlus{$(Symbol(:Float, NBIT))}
5559
@eval const $(Symbol(:TropicalMaxMul, :F, NBIT)) = TropicalMaxMul{$(Symbol(:Float, NBIT))}
60+
@eval const $(Symbol(:TropicalMaxMin, :F, NBIT)) = TropicalMaxMin{$(Symbol(:Float, NBIT))}
5661
@eval const $(Symbol(:CountingTropical, :F, NBIT)) = CountingTropical{$(Symbol(:Float, NBIT)),$(Symbol(:Float, NBIT))}
5762

5863
@eval const $(Symbol(:Tropical, :I, NBIT)) = Tropical{$(Symbol(:Int, NBIT))}
5964
@eval const $(Symbol(:TropicalMaxPlus, :I, NBIT)) = TropicalMaxPlus{$(Symbol(:Int, NBIT))}
6065
@eval const $(Symbol(:TropicalMinPlus, :I, NBIT)) = TropicalMinPlus{$(Symbol(:Int, NBIT))}
6166
@eval const $(Symbol(:TropicalMaxMul, :I, NBIT)) = TropicalMaxMul{$(Symbol(:Int, NBIT))}
67+
@eval const $(Symbol(:TropicalMaxMin, :I, NBIT)) = TropicalMaxMin{$(Symbol(:Int, NBIT))}
68+
@eval const $(Symbol(:TropicalBitwise, :I, NBIT)) = TropicalBitwise{$(Symbol(:Int, NBIT))}
6269
@eval const $(Symbol(:CountingTropical, :I, NBIT)) = CountingTropical{$(Symbol(:Int, NBIT)),$(Symbol(:Float, NBIT))}
6370
end
6471

6572
# alias
66-
for T in [:Tropical, :TropicalMaxMul, :TropicalMinPlus, :CountingTropical]
73+
for T in [:Tropical, :TropicalMaxMul, :TropicalMaxMin, :CountingTropical]
6774
for OP in [:>, :<, :(==), :>=, :<=, :isless]
6875
@eval Base.$OP(a::$T, b::$T) = $OP(a.n, b.n)
6976
end
@@ -76,6 +83,16 @@ for T in [:Tropical, :TropicalMaxMul, :TropicalMinPlus, :CountingTropical]
7683
end
7784
end
7885

86+
for T in [:TropicalMinPlus, :TropicalBitwise]
87+
@eval begin
88+
content(x::$T) = x.n
89+
content(x::Type{$T{X}}) where X = X
90+
Base.isapprox(x::AbstractArray{<:$T}, y::AbstractArray{<:$T}; kwargs...) = all(isapprox.(x, y; kwargs...))
91+
Base.show(io::IO, ::MIME"text/plain", t::$T) = Base.show(io, t)
92+
Base.isnan(x::$T) = isnan(content(x))
93+
end
94+
end
95+
7996
for T in [:TropicalAndOr]
8097
for OP in [:>, :<, :(==), :>=, :<=, :isless]
8198
@eval Base.$OP(a::$T, b::$T) = $OP(a.n, b.n)
@@ -88,7 +105,7 @@ for T in [:TropicalAndOr]
88105
end
89106
end
90107

91-
for T in [:Tropical, :TropicalMaxMul, :TropicalMinPlus, :CountingTropical]
108+
for T in [:Tropical, :TropicalMinPlus, :TropicalMaxMul, :CountingTropical]
92109
@eval begin
93110
# this is for CUDA matmul
94111
Base.:(*)(a::$T, b::Bool) = b ? a : zero(a)
@@ -100,4 +117,11 @@ for T in [:Tropical, :TropicalMaxMul, :TropicalMinPlus, :CountingTropical]
100117
end
101118
end
102119

120+
for T in [:TropicalMaxMin, :TropicalBitwise]
121+
@eval begin
122+
Base.:(*)(a::$T, b::Bool) = b ? a : zero(a)
123+
Base.:(*)(b::Bool, a::$T) = b ? a : zero(a)
124+
end
125+
end
126+
103127
end # module

src/tropical_andor.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ It maps
1212
* `1` to `true` in regular algebra,
1313
* `0` to `false` in regular algebra.
1414
15+
For the parallel bit-wise version, see [`TropicalBitwise`](@ref).
16+
1517
Example
1618
-------------------------
1719
```jldoctest; setup=:(using TropicalNumbers)

src/tropical_bitwise.jl

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
"""
2+
TropicalBitwise{T} <: AbstractSemiring
3+
4+
`TropicalBitwise` is a semiring algebra that parallelizes the [`TropicalAndOr`](@ref) algebra,
5+
It can be described by
6+
* TropicalBitwise, (ℝ, |, &, 0, ~0).
7+
8+
It maps
9+
* `+` to `|`
10+
* `*` to `&`
11+
* `0` to `0`
12+
* `1` to `~0`
13+
14+
Example
15+
-------------------------
16+
```jldoctest; setup=:(using TropicalNumbers)
17+
julia> TropicalBitwise(1) + TropicalBitwise(3)
18+
3ₛ
19+
20+
julia> TropicalBitwise(1) * TropicalBitwise(3)
21+
1ₛ
22+
23+
julia> zero(TropicalBitwiseI64)
24+
0ₛ
25+
26+
julia> one(TropicalBitwiseI64)
27+
-1ₛ
28+
```
29+
"""
30+
struct TropicalBitwise{T} <: AbstractSemiring
31+
n::T
32+
end
33+
34+
function TropicalBitwise(a::TropicalBitwise)
35+
return TropicalBitwise(a.n)
36+
end
37+
38+
function TropicalBitwise{T}(a::TropicalBitwise) where {T}
39+
return TropicalBitwise{T}(a.n)
40+
end
41+
42+
function Base.show(io::IO, a::TropicalBitwise)
43+
print(io, "$(a.n)")
44+
return
45+
end
46+
47+
function Base.isapprox(a::TropicalBitwise, b::TropicalBitwise; kw...)
48+
return isapprox(a.n, b.n; kw...)
49+
end
50+
51+
function Base.promote_rule(::Type{TropicalBitwise{U}}, ::Type{TropicalBitwise{V}}) where {U, V}
52+
W = promote_type(U, V)
53+
return TropicalBitwise{W}
54+
end
55+
56+
function Base.:+(a::TropicalBitwise, b::TropicalBitwise)
57+
n = a.n | b.n
58+
return TropicalBitwise(n)
59+
end
60+
61+
function Base.:*(a::TropicalBitwise, b::TropicalBitwise)
62+
n = a.n & b.n
63+
return TropicalBitwise(n)
64+
end
65+
66+
function Base.zero(::Type{T}) where {T <: TropicalBitwise}
67+
return typemin(T)
68+
end
69+
70+
function Base.zero(::T) where {T <: TropicalBitwise}
71+
return zero(T)
72+
end
73+
74+
function Base.one(::Type{T}) where {T <: TropicalBitwise}
75+
return typemax(T)
76+
end
77+
78+
function Base.one(::T) where {T <: TropicalBitwise}
79+
return one(T)
80+
end
81+
82+
function Base.typemin(::Type{TropicalBitwise{T}}) where {T}
83+
n = zero(T)
84+
return TropicalBitwise(n)
85+
end
86+
87+
function Base.typemax(::Type{TropicalBitwise{T}}) where {T}
88+
n = ~zero(T)
89+
return TropicalBitwise(n)
90+
end
91+
92+
function Base.:(==)(a::TropicalBitwise, b::TropicalBitwise)
93+
return a.n == b.n
94+
end
95+
96+
function Base.:>=(a::TropicalBitwise, b::TropicalBitwise)
97+
return b.n <= a.n
98+
end
99+
100+
function Base.:<=(a::TropicalBitwise, b::TropicalBitwise)
101+
return a.n | b.n == b.n
102+
end
103+
104+
function Base.:<(a::TropicalBitwise, b::TropicalBitwise)
105+
return a != b && a <= b
106+
end
107+
108+
function Base.:>(a::TropicalBitwise, b::TropicalBitwise)
109+
return b < a
110+
end

src/tropical_maxmin.jl

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
"""
2+
TropicalMaxMin{T} <: AbstractSemiring
3+
4+
TropicalMaxMin is a semiring algebra, can be described by
5+
* TropicalMaxMin, (ℝ, max, min, -Inf, Inf).
6+
7+
It maps
8+
* `+` to `max` in regular algebra,
9+
* `*` to `min` in regular algebra,
10+
* `0` to `-Inf` in regular algebra (for integer content types, this is a small integer).
11+
* `1` to `Inf` in regular algebra, (for integer content types, this is a large integer)
12+
13+
Example
14+
-------------------------
15+
```jldoctest; setup=:(using TropicalNumbers)
16+
julia> TropicalMaxMin(1.0) + TropicalMaxMin(3.0)
17+
3.0ₛ
18+
19+
julia> TropicalMaxMin(1.0) * TropicalMaxMin(3.0)
20+
1.0ₛ
21+
22+
julia> zero(TropicalMaxMinF64)
23+
-Infₛ
24+
25+
julia> one(TropicalMaxMinF64)
26+
Infₛ
27+
```
28+
"""
29+
struct TropicalMaxMin{T} <: AbstractSemiring
30+
n::T
31+
end
32+
33+
function TropicalMaxMin(a::TropicalMaxMin)
34+
return TropicalMaxMin(a.n)
35+
end
36+
37+
function TropicalMaxMin{T}(a::TropicalMaxMin) where {T}
38+
return TropicalMaxMin{T}(a.n)
39+
end
40+
41+
function Base.show(io::IO, a::TropicalMaxMin)
42+
print(io, "$(a.n)")
43+
return
44+
end
45+
46+
function Base.isapprox(a::TropicalMaxMin, b::TropicalMaxMin; kw...)
47+
return isapprox(a.n, b.n; kw...)
48+
end
49+
50+
function Base.promote_rule(::Type{TropicalMaxMin{U}}, ::Type{TropicalMaxMin{V}}) where {U, V}
51+
W = promote_type(U, V)
52+
return TropicalMaxMin{W}
53+
end
54+
55+
function Base.:+(a::TropicalMaxMin, b::TropicalMaxMin)
56+
n = max(a.n, b.n)
57+
return TropicalMaxMin(n)
58+
end
59+
60+
function Base.:*(a::TropicalMaxMin, b::TropicalMaxMin)
61+
n = min(a.n, b.n)
62+
return TropicalMaxMin(n)
63+
end
64+
65+
function Base.zero(::Type{T}) where {T <: TropicalMaxMin}
66+
return typemin(T)
67+
end
68+
69+
function Base.zero(::T) where {T <: TropicalMaxMin}
70+
return zero(T)
71+
end
72+
73+
function Base.one(::Type{T}) where {T <: TropicalMaxMin}
74+
return typemax(T)
75+
end
76+
77+
function Base.one(::T) where {T <: TropicalMaxMin}
78+
return one(T)
79+
end
80+
81+
function Base.typemin(::Type{TropicalMaxMin{T}}) where {T}
82+
n = neginf(T)
83+
return TropicalMaxMin(n)
84+
end
85+
86+
function Base.typemax(::Type{TropicalMaxMin{T}}) where {T}
87+
n = posinf(T)
88+
return TropicalMaxMin(n)
89+
end

0 commit comments

Comments
 (0)