Skip to content

Commit 7c0faea

Browse files
committed
Initial import from old repo
1 parent 82dda60 commit 7c0faea

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

66 files changed

+14619
-1
lines changed

.gitignore

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
bin/*
2+
cayley-*.pdf
3+
run-*.log
4+
coverage.out
5+
coverage.html
6+
cpu.out
7+
cpu.pdf
8+
golsv.test
9+
runs
10+
*~

Makefile

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
2+
date=$(shell date '+%Y%m%d-%H%M%S')
3+
4+
build all:
5+
go build .
6+
mkdir -p bin
7+
go build -o bin/align ./cmd/align
8+
go build -o bin/automorphism ./cmd/automorphism
9+
go build -o bin/calg-cayley ./cmd/calg-cayley
10+
go build -o bin/cayley ./cmd/cayley
11+
go build -o bin/cycles ./cmd/cycles
12+
go build -o bin/dim ./cmd/dim
13+
go build -o bin/lift ./cmd/lift
14+
go build -o bin/menum-cayley ./cmd/menum-cayley
15+
go build -o bin/multiply ./cmd/multiply
16+
go build -o bin/shorten ./cmd/shorten
17+
go build -o bin/smith ./cmd/smith
18+
go build -o bin/systole ./cmd/systole
19+
go build -o bin/transpose ./cmd/transpose
20+
go build -o bin/weight ./cmd/weight
21+
22+
test t: build
23+
go test
24+
25+
benchmark bench:
26+
go test -bench=.
27+
28+
watch w:
29+
bash scripts/watch.bash
30+
31+
coverage:
32+
go test -cover
33+
34+
coverage-report:
35+
go test -coverprofile=coverage.out
36+
go tool cover -html=coverage.out -o coverage.html
37+
open coverage.html
38+
39+
lines:
40+
find . -name '*.go' | xargs wc -l
41+
42+
clean:
43+
rm -rf bin
44+
rm -f coverage.out coverage.html

README.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,10 @@
1-
# golsv
1+
To build:
2+
3+
```
4+
% source env.bash
5+
% make test
6+
```
7+
8+
To use:
9+
10+
See the comments in worksets/Makefile.

aligner.go

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
package golsv
2+
3+
import (
4+
"log"
5+
"math"
6+
"time"
7+
)
8+
9+
// xxx optimization 8/1
10+
//
11+
// - precompute matrix of row operations, store in sparse form, load and convert to dense.
12+
// - pass in Dense matrix to aligner
13+
//
14+
// - use optimized Dense * Sparse multiplication
15+
//
16+
// - (maybe) add special SubMultiplyRight to Dense, works same as
17+
// the optimized MultiplyRight but only uses part of each column
18+
// slice.
19+
//
20+
// - then in the aligner use SubMultiplyRight to obtain the tail
21+
// of vector w, and only continue to compute the rest of w if
22+
// that tail is nonzero (meaning the vector is not in the image
23+
// the cumulative B to that point).
24+
//
25+
26+
type Aligner struct {
27+
B1smith *Sparse
28+
P *DenseBinaryMatrix
29+
B1colops []Operation
30+
Z1 *Sparse
31+
U BinaryMatrix // output matrix
32+
minWeight int
33+
}
34+
35+
func NewAligner(B1smith *Sparse, P *DenseBinaryMatrix, B1colops []Operation,
36+
Z1 *Sparse) *Aligner {
37+
return &Aligner{
38+
B1smith: B1smith,
39+
P: P,
40+
B1colops: B1colops,
41+
Z1: Z1,
42+
U: NewSparseBinaryMatrix(B1smith.NumRows(), 0),
43+
minWeight: math.MaxInt,
44+
}
45+
}
46+
47+
// Align computes a matrix U such that the columns of U, together with
48+
// the columns of Bsmith, form a basis for Z.
49+
func (a *Aligner) Align() BinaryMatrix {
50+
BIsSmith, Brank := a.B1smith.IsSmithNormalForm()
51+
if !BIsSmith {
52+
log.Fatal("matrix B1smith is not in Smith normal form")
53+
}
54+
log.Printf("B1smith = %v, Brank = %d", a.B1smith, Brank)
55+
56+
// nb. unexpectedly B1colops keeps coming out empty. xxx why? for
57+
// now assume it is true.
58+
if len(a.B1colops) > 0 {
59+
panic("B1colops not empty")
60+
}
61+
// Algorithm:
62+
//
63+
// let B = B1smith
64+
// let Z = Z1
65+
// let d = rank of B
66+
//
67+
// for each column vector v of Z:
68+
// - compute w = P(v) (P is the row operations matrix)
69+
// - let k = max index of support of w
70+
// - if k > d, then
71+
// - v is not in the span of B
72+
// - append column w to B
73+
// - reduce new column of B;
74+
// this involves row swapping to create the pivot in
75+
// position d and adding columns to clear column d
76+
// - apply the same row operations to P
77+
// - increment d
78+
// - append column v to U
79+
// - else
80+
// - discard v since it is in the span of B
81+
//
82+
// in our main example, this should produce 19 column vectors in U,
83+
// since we already know that dim H_1 = 19.
84+
85+
log.Printf("beginning alignment")
86+
Z := a.Z1
87+
rows := Z.NumRows()
88+
89+
statInterval := 1
90+
timeStart := time.Now()
91+
timeLastReport := timeStart
92+
doneLastReport := 0
93+
94+
for j := 0; j < Z.NumColumns(); j++ {
95+
v := Z.Submatrix(0, rows, j, j+1)
96+
w := a.P.MultiplyRight(v)
97+
k := w.(*DenseBinaryMatrix).MaxColumnSupport(0)
98+
if k >= Brank {
99+
a.handleIndependentVector(v, w, Brank, k)
100+
Brank++
101+
}
102+
doneLastReport++
103+
if doneLastReport >= statInterval {
104+
now := time.Now()
105+
reportElapsed := now.Sub(timeLastReport)
106+
totalElapsed := now.Sub(timeStart)
107+
cRate := float64(doneLastReport) / reportElapsed.Seconds()
108+
tRate := float64(j) / totalElapsed.Seconds()
109+
log.Printf("align: processed %d/%d (%.2f%%) cols; crate=%1.0f trate=%1.0f found=%d",
110+
j, Z.NumColumns(), 100.0 * float64(j) / float64(Z.NumColumns()),
111+
cRate, tRate, a.U.NumColumns())
112+
timeLastReport = now
113+
doneLastReport = 0
114+
if reportElapsed.Seconds() < 1 {
115+
statInterval = statInterval * 2
116+
} else if reportElapsed.Seconds() > 10 {
117+
statInterval = 1 + statInterval / 2
118+
}
119+
}
120+
}
121+
log.Printf("done; min weight is %d", a.minWeight)
122+
return a.U
123+
}
124+
125+
func (a *Aligner) handleIndependentVector(v BinaryMatrix, w BinaryMatrix, Brank int, k int) {
126+
a.U.(*Sparse).AppendColumn(v)
127+
log.Printf("found independent vector; found=%d total", a.U.NumColumns())
128+
// sneak peak at systole
129+
weight := v.(*Sparse).ColumnWeight(0)
130+
if weight < a.minWeight {
131+
a.minWeight = weight
132+
log.Printf("new min weight %d", weight)
133+
}
134+
a.B1smith.AppendColumn(w)
135+
a.makePivot(Brank, k)
136+
log.Printf("clearing column")
137+
a.clearColumn(Brank)
138+
log.Printf("done clearing column")
139+
}
140+
141+
func (a *Aligner) makePivot(Brank int, k int) {
142+
// we're increasing the rank of B by 1, so we want a pivot in
143+
// position Brank.
144+
if k > Brank {
145+
a.B1smith.SwapRows(Brank, k)
146+
a.P.SwapRows(Brank, k)
147+
}
148+
}
149+
150+
// xxx needs test!
151+
func (a *Aligner) clearColumn(Brank int) {
152+
col := Brank
153+
row := Brank + 1
154+
ops := 0
155+
reportInterval := 1000
156+
for {
157+
row = a.B1smith.ScanDown(row, col)
158+
if row == -1 {
159+
break
160+
}
161+
a.B1smith.Set(row, col, 0)
162+
a.P.AddRow(col, row)
163+
row++
164+
ops++
165+
if ops % reportInterval == 0 {
166+
log.Printf("did %d row ops", ops)
167+
}
168+
}
169+
log.Printf("did %d row ops", ops)
170+
}

bench-galoisfield/Makefile

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
2+
test t:
3+
go test
4+
5+
benchmark bench b:
6+
go test -bench=.

bench-galoisfield/go.mod

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module bench_galoisfield
2+
3+
go 1.19
4+
5+
require github.com/cloud9-tools/go-galoisfield v0.0.0-20160311182916-a8cf2bffadf0 // indirect

bench-galoisfield/go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
github.com/cloud9-tools/go-galoisfield v0.0.0-20160311182916-a8cf2bffadf0 h1:te0djrMIsqx2evVAE+U98Kfa09Jszv9OVxGJzjOjOXM=
2+
github.com/cloud9-tools/go-galoisfield v0.0.0-20160311182916-a8cf2bffadf0/go.mod h1:gum5aAgfkohBkDTmIabrl06Qht7QKxscuflLWFG5kXA=

0 commit comments

Comments
 (0)