TGW3D.TGW3DModule

L’algoritmo Topological Gift Wrapping calcola le d-celle di una partizione di spazio generate da loro partendo da un oggetto geometrico d-1 dimensionale.

TGW prende una matrice sparsa di dimensione d-1 in input e produce in output la matrice sparsa di dimensione d sconosciuta aumentata dalle celle esterne.

source

Riferimenti

Questa pagina ha i riferimenti a tutti i tipi, metodi e funzioni utilizzati.

Tipi

TGW3D.ChainOpType
ChainOp = SparseArrays.SparseMatrixCSC{Int8,Int}

Dichiarazione Alias di specifiche strutture dati di LAR.

La SparseMatrix nel formato Colonne sparse compresse, contiene la rappresentazione in coordinate di un operatore tra lo spazio lineare delle P-chains.

Operatori $P-Boundary : P-Chain -> (P-1)-Chain$ e $P-Coboundary : P-Chain -> (P+1)-Chain$ sono tipicamente immagazinati come ChainOpcon elementi in ${-1,0,1}$ oppure in ${0,1}$, per operatori assegnati e non-assegnati rispettivamente.

source
TGW3D.PointsType
Points = Array{Number,2}

Dichiarazione Alias di specifiche strutture dati di LAR.

Array{Number,2,1} $M x N$ compatto per immagazzinare la posizione dei vertici (0-cells) di un complesso cellulare. Il numero delle righe $M$ è la dimensione dello spazio di inclusione. Il numero delle colonne $N$ è il numero dei vertici.

source

Funzioni

Dati utilizzati per l'esecuzione degli esempi:

using SparseArrays
V = Float64[
        0 0 0; 0 1 0;
        1 1 0; 1 0 0;
        0 0 1; 0 1 1;
        1 1 1; 1 0 1
]

EV = sparse(Int8[
        -1  1  0  0  0  0  0  0;
        0 -1  1  0  0  0  0  0;
        0  0 -1  1  0  0  0  0;
        -1  0  0  1  0  0  0  0;
        -1  0  0  0  1  0  0  0;
        0 -1  0  0  0  1  0  0;
        0  0 -1  0  0  0  1  0;
        0  0  0 -1  0  0  0  1;
        0  0  0  0 -1  1  0  0;
        0  0  0  0  0 -1  1  0;
        0  0  0  0  0  0 -1  1;
        0  0  0  0 -1  0  0  1;
])

FE = sparse(Int8[
        1  1  1 -1  0  0  0  0  0  0  0  0;
        0  0  0  0  0  0  0  0 -1 -1 -1  1;
        -1  0  0  0  1 -1  0  0  1  0  0  0;
        0 -1  0  0  0  1 -1  0  0  1  0  0;
        0  0 -1  0  0  0  1 -1  0  0  1  0;
        0  0  0  1 -1  0  0  1  0  0  0 -1;
])
TGW3D.filter_fnMethod
function filter_fn(face)

Funzione di filtro per la funzione merge_vertices. La funzione filter_fn prende in input una faccia e restituisce true se i vertici della faccia non sono stati visitati, false altrimenti.

Input

  • face::Vector{Tuple{Int64, Int64}}

Output

  • true/false::Bool
source
TGW3D.frag_faceMethod
function frag_face(
        V::Points, 
        EV::ChainOp, 
        FE::ChainOp, 
        sp_idx::Vector{Vector{Int64}}, 
        sigma::Int64)

Prende la faccia sigma e la trasforma in 2D per poter calcolare le intersezioni con le facce in sp_idx[sigma] ed ottenere la disposizione 2D della faccia sigma.

Input

  • V::Points
  • EV::ChainOp
  • FE::ChainOp
  • sp_idx::Vector{Vector{Int64}}
  • sigma::Int64

Output

  • nV::Points
  • nEV::ChainOp
  • nFE::ChainOp

Esempi

julia> nV, nEV, nFE = frag_face(V, EV, FE, [[2,3,4,5]], 2)

([0.0 0.0 1.0; 0.0 1.0 1.0; 1.0 1.0 1.0; 1.0 0.0 1.0], sparse([1, 4, 1, 2, 2, 3, 3, 4], 
[1, 1, 2, 2, 3, 3, 4, 4], Int8[-1, -1, 1, -1, 1, -1, 1, 1], 4, 4), sparse([1, 1, 1, 1], 
[1, 2, 3, 4], Int8[1, 1, 1, -1], 1, 4))


julia> nV

4×3 Matrix{Float64}:
 0.0  0.0  1.0
 0.0  1.0  1.0
 1.0  1.0  1.0
 1.0  0.0  1.0


julia> nEV

4×4 SparseMatrixCSC{Int8, Int64} with 8 stored entries:
 -1   1   ⋅  ⋅
  ⋅  -1   1  ⋅
  ⋅   ⋅  -1  1
 -1   ⋅   ⋅  1


julia> nFE

1×4 SparseMatrixCSC{Int8, Int64} with 4 stored entries:
 1  1  1  -1

source
TGW3D.frag_face_channelMethod
function frag_face_channel(
        in_chan, 
        out_chan, 
        V::Points, 
        EV::ChainOp, 
        FE::ChainOp, 
        sp_idx::Vector{Int64})

Funziona che parallelizza, con l'utilizzo dei canali, la frammentazione delle facce in FE rispetto le facce in sp_idx.

Input

  • in_chan
  • out_chan
  • V::Points
  • EV::ChainOp
  • FE::ChainOp
  • sp_idx::Vector{Int64}

Output

  • V::Points
  • EV::ChainOp
source
TGW3D.merge_verticesFunction
function merge_vertices(
        V::Points, 
        EV::ChainOp, 
        FE::ChainOp, 
        [err=1e-4])

Rimuove i vertici congruenti ad un singolo rappresentatante, traduce i lati per tener conto della congruenza ed otteniene nuove facce congruenti.

Argomenti addizionali:

  • err: Limite di errore massimo che si vuole utilizzare. Di Defaults a 1e-4.

Input

  • V::Points
  • EV::ChainOp
  • FE::ChainOp
  • err=1e-4

Output

  • nV::Points
  • nEV::ChainOp
  • nFE::ChainOp

Esempi

julia> nV, nEV, nFE = merge_vertices(V, EV, FE)

([0.0 0.0 0.0; 0.0 1.0 0.0; … ; 1.0 1.0 1.0; 1.0 0.0 1.0], sparse([1, 4, 5, 1, 2, 6, 2, 3, 7, 3  
…  12, 6, 9, 10, 7, 10, 11, 8, 11, 12], [1, 1, 1, 2, 2, 2, 3, 3, 3, 4  …  5, 6, 6, 6, 7, 7, 7, 
8, 8, 8], Int8[-1, -1, -1, 1, -1, -1, 1, -1, -1, 1  …  -1, 1, 1, -1, 1, 1, -1, 1, 1, 1], 12, 8), 
sparse([1, 3, 1, 4, 1, 5, 1, 6, 3, 6  …  5, 6, 2, 3, 2, 4, 2, 5, 2, 6], [1, 1, 2, 2, 3, 3, 4, 4, 
5, 5  …  8, 8, 9, 9, 10, 10, 11, 11, 12, 12], Int8[1, -1, 1, -1, 1, -1, -1, 1, 1, -1  …  -1, 1, 
-1, 1, -1, 1, -1, 1, 1, -1], 6, 12))


julia> nV

8×3 Matrix{Float64}:
 0.0  0.0  0.0
 0.0  1.0  0.0
 1.0  1.0  0.0
 1.0  0.0  0.0
 0.0  0.0  1.0
 0.0  1.0  1.0
 1.0  1.0  1.0
 1.0  0.0  1.0


julia> nEV

12×8 SparseMatrixCSC{Int8, Int64} with 24 stored entries:
 -1   1   ⋅   ⋅   ⋅   ⋅   ⋅  ⋅
  ⋅  -1   1   ⋅   ⋅   ⋅   ⋅  ⋅
  ⋅   ⋅  -1   1   ⋅   ⋅   ⋅  ⋅
 -1   ⋅   ⋅   1   ⋅   ⋅   ⋅  ⋅
 -1   ⋅   ⋅   ⋅   1   ⋅   ⋅  ⋅
  ⋅  -1   ⋅   ⋅   ⋅   1   ⋅  ⋅
  ⋅   ⋅  -1   ⋅   ⋅   ⋅   1  ⋅
  ⋅   ⋅   ⋅  -1   ⋅   ⋅   ⋅  1
  ⋅   ⋅   ⋅   ⋅  -1   1   ⋅  ⋅
  ⋅   ⋅   ⋅   ⋅   ⋅  -1   1  ⋅
  ⋅   ⋅   ⋅   ⋅   ⋅   ⋅  -1  1
  ⋅   ⋅   ⋅   ⋅  -1   ⋅   ⋅  1


julia> nFE

6×12 SparseMatrixCSC{Int8, Int64} with 24 stored entries:
  1   1   1  -1   ⋅   ⋅   ⋅   ⋅   ⋅   ⋅   ⋅   ⋅
  ⋅   ⋅   ⋅   ⋅   ⋅   ⋅   ⋅   ⋅  -1  -1  -1   1
 -1   ⋅   ⋅   ⋅   1  -1   ⋅   ⋅   1   ⋅   ⋅   ⋅
  ⋅  -1   ⋅   ⋅   ⋅   1  -1   ⋅   ⋅   1   ⋅   ⋅
  ⋅   ⋅  -1   ⋅   ⋅   ⋅   1  -1   ⋅   ⋅   1   ⋅
  ⋅   ⋅   ⋅   1  -1   ⋅   ⋅   1   ⋅   ⋅   ⋅  -1
source
TGW3D.removeinnerloopsMethod
function removeinnerloops(
        g::Int64, 
        nFE::ChainOp)

Rimuove le facce all'interno dei cicli interni dalla matrice sparsa nFE. Il valore restituito ha g righe in meno rispetto all'input nFE.

Input

  • g::Int
  • nFE::ChainOp

Output

  • nFE::ChainOp

Esempio

julia> nFE = removeinnerloops(2, FE)

4×12 SparseMatrixCSC{Int8, Int64} with 16 stored entries:
 1  1  1  1  ⋅  ⋅  ⋅  ⋅  ⋅  ⋅  ⋅  ⋅
 ⋅  ⋅  ⋅  ⋅  ⋅  ⋅  ⋅  ⋅  1  1  1  1
 1  ⋅  ⋅  ⋅  1  1  ⋅  ⋅  1  ⋅  ⋅  ⋅
 ⋅  1  ⋅  ⋅  ⋅  1  1  ⋅  ⋅  1  ⋅  ⋅
source
TGW3D.spatial_arrangementFunction
function spatial_arrangement(
        V::Points, 
        copEV::ChainOp, 
        copFE::ChainOp; 
        [multiproc::Bool])

Calcola la disposizione sulle cellule complesse 2-skeleton date in 3D.

Un complesso cellulare è disposto quando l'intersezione di ogni coppia di celle del complesso è vuota e l'unione di tutte le celle rappresenta l'intero spazio Euclideo. La funzione ritorna la piena disposizione complessa come una lista di vertici V e una catena di lati EV, FE, CF.

Argomenti addizionali:

  • multiproc::Bool: Esegue la computazione in modalità parallela. Di Defaults a false.

Input

  • V::Points
  • copEV::ChainOp
  • copFE::ChainOp
  • multiproc::Bool=false

Output

  • rV::Points
  • rEV::ChainOp
  • rFE::ChainOp
  • rCF::ChainOp

Esempi

julia> rV, rEV, rFE, rCF = spatial_arrangement(Points(V), ChainOp(EV), ChainOp(FE))

([0.0 0.0 0.0; 0.0 1.0 0.0; … ; 1.0 1.0 1.0; 1.0 0.0 1.0], sparse([1, 4, 9, 1, 2, 10,
2, 3, 11, 3  …  9, 5, 6, 10, 6, 7, 11, 7, 8, 12], [1, 1, 1, 2, 2, 2, 3, 3, 3, 4  …  5,
6, 6, 6, 7, 7, 7, 8, 8, 8], Int8[-1, -1, -1, 1, -1, -1, 1, -1, -1, 1  …  1, 1, -1, 1, 1,
-1, 1, 1, 1, 1], 12, 8), sparse([1, 3, 1, 4, 1, 5, 1, 6, 2, 3  …  2, 6, 3, 6, 3, 4, 4, 5,
5, 6], [1, 1, 2, 2, 3, 3, 4, 4, 5, 5  …  8, 8, 9, 9, 10, 10, 11, 11, 12, 12], Int8[1, 1,
1, 1, 1, 1, -1, 1, 1, -1  …  -1, -1, -1, -1, 1, -1, 1, -1, 1, 1], 6, 12), sparse([1, 7,
2, 8, 3, 9, 4, 10, 5, 11, 6, 12], [1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6], Int8[-1, 1, -1,
1, -1, 1, -1, 1, -1, 1, -1, 1], 12, 6))


julia> rV

8×3 Matrix{Float64}:
 0.0  0.0  0.0
 0.0  1.0  0.0
 1.0  1.0  0.0
 1.0  0.0  0.0
 0.0  0.0  1.0
 0.0  1.0  1.0
 1.0  1.0  1.0
 1.0  0.0  1.0


julia> rEV

12×8 SparseMatrixCSC{Int8, Int64} with 24 stored entries:
 -1   1   ⋅   ⋅   ⋅   ⋅   ⋅  ⋅
  ⋅  -1   1   ⋅   ⋅   ⋅   ⋅  ⋅
  ⋅   ⋅  -1   1   ⋅   ⋅   ⋅  ⋅
 -1   ⋅   ⋅   1   ⋅   ⋅   ⋅  ⋅
  ⋅   ⋅   ⋅   ⋅  -1   1   ⋅  ⋅
  ⋅   ⋅   ⋅   ⋅   ⋅  -1   1  ⋅
  ⋅   ⋅   ⋅   ⋅   ⋅   ⋅  -1  1
  ⋅   ⋅   ⋅   ⋅  -1   ⋅   ⋅  1
 -1   ⋅   ⋅   ⋅   1   ⋅   ⋅  ⋅
  ⋅  -1   ⋅   ⋅   ⋅   1   ⋅  ⋅
  ⋅   ⋅  -1   ⋅   ⋅   ⋅   1  ⋅
  ⋅   ⋅   ⋅  -1   ⋅   ⋅   ⋅  1


julia> rFE

6×12 SparseMatrixCSC{Int8, Int64} with 24 stored entries:
 1  1  1  -1   ⋅   ⋅   ⋅   ⋅   ⋅   ⋅   ⋅  ⋅
 ⋅  ⋅  ⋅   ⋅   1   1   1  -1   ⋅   ⋅   ⋅  ⋅
 1  ⋅  ⋅   ⋅  -1   ⋅   ⋅   ⋅  -1   1   ⋅  ⋅
 ⋅  1  ⋅   ⋅   ⋅  -1   ⋅   ⋅   ⋅  -1   1  ⋅
 ⋅  ⋅  1   ⋅   ⋅   ⋅  -1   ⋅   ⋅   ⋅  -1  1
 ⋅  ⋅  ⋅   1   ⋅   ⋅   ⋅  -1  -1   ⋅   ⋅  1


julia> rCF

12×6 SparseMatrixCSC{Int8, Int64} with 12 stored entries:
 -1   ⋅   ⋅   ⋅   ⋅   ⋅
  ⋅  -1   ⋅   ⋅   ⋅   ⋅
  ⋅   ⋅  -1   ⋅   ⋅   ⋅
  ⋅   ⋅   ⋅  -1   ⋅   ⋅
  ⋅   ⋅   ⋅   ⋅  -1   ⋅
  ⋅   ⋅   ⋅   ⋅   ⋅  -1
  1   ⋅   ⋅   ⋅   ⋅   ⋅
  ⋅   1   ⋅   ⋅   ⋅   ⋅
  ⋅   ⋅   1   ⋅   ⋅   ⋅
  ⋅   ⋅   ⋅   1   ⋅   ⋅
  ⋅   ⋅   ⋅   ⋅   1   ⋅
  ⋅   ⋅   ⋅   ⋅   ⋅   1
source
TGW3D.spatial_arrangement_1Function
function spatial_arrangement_1(
        V::Points,
        copEV::ChainOp,
        copFE::ChainOp, 
        [multiproc::Bool=false])

Si occupa del processo di frammentazione delle facce per l'utilizzo del planar arrangement. Richiama le funzioni frag_face e `merge_vertices' per ritornare i nuovi vertici, lati e facce.

Argomenti addizionali:

  • multiproc::Bool: Esegue la computazione in modalità parallela. Di Defaults a false.

Input

  • V::Points
  • copEV::ChainOp
  • copFE::ChainOp
  • multiproc::Bool=false

Output

  • rV::Points
  • rEV::ChainOp
  • rFE::ChainOp

Esempi

julia> rV, rEV, rFE = spatial_arrangement_1(Points(V), ChainOp(EV), ChainOp(FE))

([0.0 0.0 0.0; 0.0 1.0 0.0; … ; 1.0 1.0 1.0; 1.0 0.0 1.0], sparse([1, 4, 9, 1, 2,
10, 2, 3, 11, 3  …  9, 5, 6, 10, 6, 7, 11, 7, 8, 12], [1, 1, 1, 2, 2, 2, 3, 3, 3,
4  …  5, 6, 6, 6, 7, 7, 7, 8, 8, 8], Int8[-1, -1, -1, 1, -1, -1, 1, -1, -1, 1  …
1, 1, -1, 1, 1, -1, 1, 1, 1, 1], 12, 8), sparse([1, 3, 1, 4, 1, 5, 1, 6, 2, 3  …
2, 6, 3, 6, 3, 4, 4, 5, 5, 6], [1, 1, 2, 2, 3, 3, 4, 4, 5, 5  …  8, 8, 9, 9, 10,
10, 11, 11, 12, 12], Int8[1, 1, 1, 1, 1, 1, -1, 1, 1, -1  …  -1, -1, -1, -1, 1,
-1, 1, -1, 1, 1], 6, 12))


julia> rV

8×3 Matrix{Float64}:
 0.0  0.0  0.0
 0.0  1.0  0.0
 1.0  1.0  0.0
 1.0  0.0  0.0
 0.0  0.0  1.0
 0.0  1.0  1.0
 1.0  1.0  1.0
 1.0  0.0  1.0

julia> rEV

12×8 SparseMatrixCSC{Int8, Int64} with 24 stored entries:
 -1   1   ⋅   ⋅   ⋅   ⋅   ⋅  ⋅
  ⋅  -1   1   ⋅   ⋅   ⋅   ⋅  ⋅
  ⋅   ⋅  -1   1   ⋅   ⋅   ⋅  ⋅
 -1   ⋅   ⋅   1   ⋅   ⋅   ⋅  ⋅
  ⋅   ⋅   ⋅   ⋅  -1   1   ⋅  ⋅
  ⋅   ⋅   ⋅   ⋅   ⋅  -1   1  ⋅
  ⋅   ⋅   ⋅   ⋅   ⋅   ⋅  -1  1
  ⋅   ⋅   ⋅   ⋅  -1   ⋅   ⋅  1
 -1   ⋅   ⋅   ⋅   1   ⋅   ⋅  ⋅
  ⋅  -1   ⋅   ⋅   ⋅   1   ⋅  ⋅
  ⋅   ⋅  -1   ⋅   ⋅   ⋅   1  ⋅
  ⋅   ⋅   ⋅  -1   ⋅   ⋅   ⋅  1

julia> rFE

6×12 SparseMatrixCSC{Int8, Int64} with 24 stored entries:
 1  1  1  -1   ⋅   ⋅   ⋅   ⋅   ⋅   ⋅   ⋅  ⋅
 ⋅  ⋅  ⋅   ⋅   1   1   1  -1   ⋅   ⋅   ⋅  ⋅
 1  ⋅  ⋅   ⋅  -1   ⋅   ⋅   ⋅  -1   1   ⋅  ⋅
 ⋅  1  ⋅   ⋅   ⋅  -1   ⋅   ⋅   ⋅  -1   1  ⋅
 ⋅  ⋅  1   ⋅   ⋅   ⋅  -1   ⋅   ⋅   ⋅  -1  1
 ⋅  ⋅  ⋅   1   ⋅   ⋅   ⋅  -1  -1   ⋅   ⋅  1
source
TGW3D.spatial_arrangement_2Function
function spatial_arrangement_2(
        rV::Points, 
        rcopEV::ChainOp, 
        rcopFE::ChainOp, 
        [multiproc::Bool=false])

Effettua la ricostruzione delle facce permettendo il wrapping spaziale 3D.

Argomenti addizionali:

  • multiproc::Bool: Esegue la computazione in modalità parallela. Di Defaults a false.

Input

  • rV::Points
  • rcopEV::ChainOp
  • rcopFE::ChainOp
  • multiproc::Bool=false

Output

  • rV::Points
  • rcopEV::ChainOp
  • rcopFE::ChainOp
  • rcopCF::ChainOp
  • multiproc::Bool=false

Esempi

julia> rV, rcopEV, rcopFE, rcopCF = spatial_arrangement_2(rV, rEV, rFE)

([0.0 0.0 0.0; 0.0 1.0 0.0; … ; 1.0 1.0 1.0; 1.0 0.0 1.0], sparse([1, 4, 
9, 1, 2, 10, 2, 3, 11, 3  …  9, 5, 6, 10, 6, 7, 11, 7, 8, 12], [1, 1, 1, 
2, 2, 2, 3, 3, 3, 4  …  5, 6, 6, 6, 7, 7, 7, 8, 8, 8], Int8[-1, -1, -1, 
1, -1, -1, 1, -1, -1, 1  …  1, 1, -1, 1, 1, -1, 1, 1, 1, 1], 12, 8), sparse(
[1, 3, 1, 4, 1, 5, 1, 6, 2, 3  …  2, 6, 3, 6, 3, 4, 4, 5, 5, 6], [1, 
1, 2, 2, 3, 3, 4, 4, 5, 5  …  8, 8, 9, 9, 10, 10, 11, 11, 12, 12], Int8[1, 
1, 1, 1, 1, 1, -1, 1, 1, -1  …  -1, -1, -1, -1, 1, -1, 1, -1, 1, 1], 
6, 12), sparse([1, 7, 2, 8, 3, 9, 4, 10, 5, 11, 6, 12], [1, 1, 2, 2, 3, 
3, 4, 4, 5, 5, 6, 6], Int8[-1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1], 12, 6))


julia> rV
8×3 Matrix{Float64}:
 0.0  0.0  0.0
 0.0  1.0  0.0
 1.0  1.0  0.0
 1.0  0.0  0.0
 0.0  0.0  1.0
 0.0  1.0  1.0
 1.0  1.0  1.0
 1.0  0.0  1.0


julia> rcopEV

12×8 SparseMatrixCSC{Int8, Int64} with 24 stored entries:
 -1   1   ⋅   ⋅   ⋅   ⋅   ⋅  ⋅
  ⋅  -1   1   ⋅   ⋅   ⋅   ⋅  ⋅
  ⋅   ⋅  -1   1   ⋅   ⋅   ⋅  ⋅
 -1   ⋅   ⋅   1   ⋅   ⋅   ⋅  ⋅
  ⋅   ⋅   ⋅   ⋅  -1   1   ⋅  ⋅
  ⋅   ⋅   ⋅   ⋅   ⋅  -1   1  ⋅
  ⋅   ⋅   ⋅   ⋅   ⋅   ⋅  -1  1
  ⋅   ⋅   ⋅   ⋅  -1   ⋅   ⋅  1
 -1   ⋅   ⋅   ⋅   1   ⋅   ⋅  ⋅
  ⋅  -1   ⋅   ⋅   ⋅   1   ⋅  ⋅
  ⋅   ⋅  -1   ⋅   ⋅   ⋅   1  ⋅
  ⋅   ⋅   ⋅  -1   ⋅   ⋅   ⋅  1


julia> rcopFE

6×12 SparseMatrixCSC{Int8, Int64} with 24 stored entries:
 1  1  1  -1   ⋅   ⋅   ⋅   ⋅   ⋅   ⋅   ⋅  ⋅
 ⋅  ⋅  ⋅   ⋅   1   1   1  -1   ⋅   ⋅   ⋅  ⋅
 1  ⋅  ⋅   ⋅  -1   ⋅   ⋅   ⋅  -1   1   ⋅  ⋅
 ⋅  1  ⋅   ⋅   ⋅  -1   ⋅   ⋅   ⋅  -1   1  ⋅
 ⋅  ⋅  1   ⋅   ⋅   ⋅  -1   ⋅   ⋅   ⋅  -1  1
 ⋅  ⋅  ⋅   1   ⋅   ⋅   ⋅  -1  -1   ⋅   ⋅  1

julia> rcopCF

12×6 SparseMatrixCSC{Int8, Int64} with 12 stored entries:
 -1   ⋅   ⋅   ⋅   ⋅   ⋅
  ⋅  -1   ⋅   ⋅   ⋅   ⋅
  ⋅   ⋅  -1   ⋅   ⋅   ⋅
  ⋅   ⋅   ⋅  -1   ⋅   ⋅
  ⋅   ⋅   ⋅   ⋅  -1   ⋅
  ⋅   ⋅   ⋅   ⋅   ⋅  -1
  1   ⋅   ⋅   ⋅   ⋅   ⋅
  ⋅   1   ⋅   ⋅   ⋅   ⋅
  ⋅   ⋅   1   ⋅   ⋅   ⋅
  ⋅   ⋅   ⋅   1   ⋅   ⋅
  ⋅   ⋅   ⋅   ⋅   1   ⋅
  ⋅   ⋅   ⋅   ⋅   ⋅   1
source