Documentation
¶
Overview ¶
Package conformance compares this module with SciPy. A Generator runs the cases in both implementations through a live oracle session and records SciPy's answers as a Fixture (JSON, committed under testdata/); Verify re-runs the Go side from the fixture alone, so the regression tests need neither Python nor network.
Index ¶
- Constants
- Variables
- func CorpusDir(getenv func(string) string, userCache func() (string, error)) (string, error)
- func DefaultSolveCases(matrices []Named) []struct{ ... }
- func Document(f *Fixture, live *LiveReport) string
- func Fetch(dir string, get func(string) ([]byte, error), entries []CorpusEntry, ...) (paths []string, unpinned map[string]string, err error)
- func HTTPGet(url string) ([]byte, error)
- func IterTolerance(solver string, sciIters int) int
- func LSMRTable(rows []LSMRRow) string
- func LSQRMatrix(m, n, perRow int, seed uint64) *sparse.CSR[float64]
- func LSQRTable(rows []LSQRRow) string
- func OrderTable(rows []OrderRow) string
- func PermHash(p []int) string
- func RHS(n int) []float64
- func RunGo(n Named, c SolveCase) (info, iters int, res float64, err error)
- func SaveFixture(path string, f *Fixture) error
- func SolveTable(rows []SolveRow) string
- type CorpusEntry
- type Fixture
- type LSMRFix
- type LSMRRow
- type LSQRCase
- type LSQRFix
- type LSQRRow
- type LiveReport
- type Named
- type OrderFix
- type OrderRow
- type PrecondSpec
- type SolveCase
- type SolveFix
- type SolveRow
Constants ¶
const CorpusBase = "https://math.nist.gov/pub/MatrixMarket2/Harwell-Boeing/"
CorpusBase is where the matrices come from. They carry no stated licence, so they are never copied into this repository: they are downloaded into a cache directory outside every work tree and checked against pinned SHA-256 sums.
const LiveMaxIter = 900
LiveMaxIter bounds the iterations of a live (report-only) run.
Variables ¶
var ( SuiteSolve = []string{"lap2d:30:30", "lap3d:12:12:12", "cd2d:30:30:2", "rnd:1000:6:1:1", "rnd:1000:6:0:2"} SuiteOrder = []string{"lap2d:30:30+scr:1", "lap3d:12:12:12+scr:2", "cd2d:30:30:1+scr:3", "rnd:1000:3:1:4", "rnd:1000:3:0:5"} )
SuiteSolve and SuiteOrder name the matrices of the committed suite.
var Corpus = []CorpusEntry{
{"bcsstruc1", "bcsstk01"}, {"bcsstruc1", "bcsstk04"}, {"bcsstruc1", "bcsstk05"},
{"lanpro", "nos1"}, {"lanpro", "nos2"}, {"lanpro", "nos3"}, {"lanpro", "nos5"}, {"lanpro", "nos6"}, {"lanpro", "nos7"},
{"chemwest", "west0067"}, {"chemwest", "west0479"},
{"sherman", "sherman1"}, {"sherman", "sherman4"}, {"pores", "pores_3"},
{"oilgen", "orsirr_1"}, {"oilgen", "orsreg_1"},
}
Corpus is the small named set (n <= 5000) used by the live comparison.
var CorpusSums = map[string]string{
"bcsstk01": "567560f75b952d9c14c0d193ded5d80370d7ca26fe49f9e67deee55f22e55699",
"bcsstk04": "11aa7f961f13eb47752e7f7dddaa5ffb3213c0158ef8bb1f30cae59088771694",
"bcsstk05": "f69d081ee645980a230909473991f5d5edfd3ee1c1637c5dceb3b7a174705eb3",
"nos1": "22887f6f2e5d5f45cd93d4ed34e87f4ed34a10e9fe10f7b37e7b467b5ccb6e00",
"nos2": "2e64095a3df034ddb4739695c3f37f63a084f8b27c239dcc562a5080255e97ab",
"nos3": "83337fac6e0785af7043ba216cb54795b98bcab4903375f14ef23d2fc05e1def",
"nos5": "1317ee84c28a6380793e22ec6e70ceb75b1b5a74cb3765da7200b00e22615f16",
"nos6": "474a46ccf889db2ffe466e6b46d0d1b1684b80c360aaba05fc34e3c8fada2095",
"nos7": "c0a58a31b26cfef06aa4830940244dbc6dd28730afdd40c7246a0d511eb1c6ed",
"west0067": "228c55ac4746e8be7bb7f7e03e590d7066cdfe9ba9c06616dd19c04104ff6adb",
"west0479": "aa32caf765f8236338e4899ca8434fad56d524020b60a329671223e6c5d68027",
"sherman1": "36f6d76bbfec3c4465070e92171b05ed74fda5beb4a5a0910b2237ff6de6c2fd",
"sherman4": "6ed0608d81db3f2cb66a5f779086e2ae0856a2d5c13c682bd893e3492bdcdb97",
"pores_3": "254509c62d170c2cb28ed5868e899e969263bd83b2122047fb0d33836395543b",
"orsirr_1": "402189c444c35acbd3b49eed2099ada90814b8795ea845260be5008ad43f406c",
"orsreg_1": "56d2e8897d8a5f906b8065409fe501eecff49a39e7d5f2ee40abb12b97bb1dd7",
}
CorpusSums pins the SHA-256 of each corpus file (the .mtx.gz as served by math.nist.gov on 2026-10-17).
var OrderBounds = struct{ RCMBandwidth, RCMProfile, AMDChol, AMDLU, COLAMDLU float64 }{
RCMBandwidth: 1.25, RCMProfile: 1.25, AMDChol: 1.15, AMDLU: 1.15, COLAMDLU: 1.2,
}
OrderBounds are the quality ratios Verify enforces (Go over reference).
Functions ¶
func CorpusDir ¶
CorpusDir returns the cache directory (GO_SPARSE_CORPUS overrides it) and refuses a directory inside a git work tree.
func DefaultSolveCases ¶
DefaultSolveCases is the committed suite: every solver on matrices of the right kind with each applicable preconditioner.
func Document ¶
func Document(f *Fixture, live *LiveReport) string
Document renders docs/verification.md from the committed fixture (re-run on the Go side) and, when live is not nil, the corpus comparison.
func Fetch ¶
func Fetch(dir string, get func(string) ([]byte, error), entries []CorpusEntry, sums map[string]string) (paths []string, unpinned map[string]string, err error)
Fetch makes sure every entry is in dir (as <name>.mtx.gz) and returns the paths. A file already present is reused; a downloaded or present file whose SHA-256 is pinned in sums must match it. unpinned lists the entries that had no pinned sum, with the sum observed, for the maintainer to pin.
func HTTPGet ¶
HTTPGet fetches a URL with a timeout. (Not built for android and ios, where importing net/http pulls in cgo and the corpus download is meaningless.)
func IterTolerance ¶
IterTolerance is the allowed difference in iteration counts between Go and SciPy for the same case: floating-point summation order differs, which moves a Krylov method by an iteration or two (more for BiCGSTAB, whose convergence is erratic).
func LSQRMatrix ¶
LSQRMatrix builds a full-column-rank m x n least-squares matrix with about perRow random entries per row plus a strengthened diagonal block.
func OrderTable ¶
OrderTable renders ordering rows: Go next to SciPy / SuiteSparse.
func PermHash ¶
PermHash is a short checksum of a permutation, used to detect that an ordering changed since the fixture was generated.
func SaveFixture ¶
SaveFixture writes f as indented JSON.
func SolveTable ¶
SolveTable renders solver rows as a Markdown table.
Types ¶
type CorpusEntry ¶
type CorpusEntry struct{ Set, Name string }
CorpusEntry names a matrix of the NIST Matrix Market Harwell-Boeing set.
type Fixture ¶
type Fixture struct {
SciPy string `json:"scipy"`
NumPy string `json:"numpy"`
Solves []SolveFix `json:"solves"`
LSQR []LSQRFix `json:"lsqr"`
LSMR []LSMRFix `json:"lsmr"`
Orders []OrderFix `json:"orders"`
}
Fixture is the committed oracle record.
func GenerateAll ¶
GenerateAll runs the whole suite against the oracle.
func LoadFixture ¶
LoadFixture reads a fixture file.
type LSMRFix ¶
type LSMRFix struct {
LSQRCase
Sci scipy.LSMRResponse `json:"scipy"`
}
LSMRFix is an LSQRCase (the matrices are shared) with SciPy's lsmr answer.
type LSMRRow ¶
LSMRRow compares the two implementations on one case.
func VerifyLSMR ¶
VerifyLSMR checks stopping reason, iteration count (within 3), solution and residual norm (1e-6 relative) against the fixtures.
type LSQRCase ¶
type LSQRCase struct {
Matrix string `json:"matrix"` // "m:n:perRow:seed"
Damp float64 `json:"damp"`
ATol float64 `json:"atol"`
BTol float64 `json:"btol"`
}
LSQRCase is one lsqr run.
func DefaultLSQRCases ¶
func DefaultLSQRCases() []LSQRCase
DefaultLSQRCases is the committed least-squares suite.
type LSQRFix ¶
type LSQRFix struct {
LSQRCase
Sci scipy.LSQRResponse `json:"scipy"`
}
LSQRFix is an LSQRCase with SciPy's answer.
type LSQRRow ¶
type LSQRRow struct {
LSQRFix
GoIstop, GoItn int
GoR1Norm float64
MaxXDiff float64 // max |x_go - x_scipy| / max(1, |x_scipy|)
}
LSQRRow compares the two implementations on one case.
func VerifyLSQR ¶
VerifyLSQR runs the Go side and checks it against the fixtures: same stopping reason, iteration count within 3, solution and residual norm equal to 1e-6 relative.
type LiveReport ¶
LiveReport holds a report-only comparison on matrices whose behaviour is not enforced (ill-conditioned corpus matrices converge erratically, so iteration counts are listed, not asserted).
type Named ¶
Named is a matrix and the name it is reported under.
func Build ¶
Build constructs a gallery matrix from its name: lap1d:n, lap2d:nx:ny, lap3d:nx:ny:nz, cd2d:nx:ny:peclet, rnd:n:perRow:sym:seed, each optionally followed by "+scr:seed" (symmetric random permutation).
func LoadCorpus ¶
LoadCorpus reads the files; symmetric files are treated as SPD candidates.
type OrderFix ¶
type OrderFix struct {
Matrix string `json:"matrix"`
N int `json:"n"`
NNZ int `json:"nnz"`
// RCM: bandwidth and profile after SciPy's reverse_cuthill_mckee.
SciRCMBandwidth int `json:"sci_rcm_bandwidth"`
SciRCMProfile int `json:"sci_rcm_profile"`
// AMD (symmetric matrices): Cholesky nnz under SuiteSparse AMD's
// permutation and nnz(L+U) of SuperLU's minimum degree on A+Aᵀ.
SuiteSparseAMDChol int `json:"suitesparse_amd_chol,omitempty"`
SuperLUMMDLU int `json:"superlu_mmd_lu,omitempty"`
GoAMDHash string `json:"go_amd_hash,omitempty"`
GoAMDLU int `json:"go_amd_lu,omitempty"`
// COLAMD: nnz(L+U) of SuperLU's COLAMD and of SuperLU on our ordering.
SciCOLAMDLU int `json:"sci_colamd_lu"`
NaturalLU int `json:"natural_lu"`
GoCOLAMDHash string `json:"go_colamd_hash"`
GoCOLAMDLU int `json:"go_colamd_lu"`
GoRCMHash string `json:"go_rcm_hash"`
}
OrderFix records the ordering comparison for one matrix.
type PrecondSpec ¶
type PrecondSpec string
PrecondSpec names a preconditioner: none, jacobi, ssor, ic0, ilu0, ilut.
type SolveCase ¶
type SolveCase struct {
Matrix string `json:"matrix"`
Solver string `json:"solver"`
Precond string `json:"precond"`
RTol float64 `json:"rtol"`
Restart int `json:"restart,omitempty"`
MaxIter int `json:"maxiter,omitempty"` // 0: the solver default
}
SolveCase is one solver run on one matrix.
type SolveFix ¶
type SolveFix struct {
SolveCase
Sci scipy.SolveResponse `json:"scipy"`
}
SolveFix is a SolveCase with SciPy's answer.