github.com/AndrienkoAleksandr/go@v0.0.19/src/go/types/hilbert_test.go (about) 1 // Code generated by "go test -run=Generate -write=all"; DO NOT EDIT. 2 3 // Copyright 2013 The Go Authors. All rights reserved. 4 // Use of this source code is governed by a BSD-style 5 // license that can be found in the LICENSE file. 6 7 package types_test 8 9 import ( 10 "bytes" 11 "flag" 12 "fmt" 13 "os" 14 "testing" 15 16 . "go/types" 17 ) 18 19 var ( 20 H = flag.Int("H", 5, "Hilbert matrix size") 21 out = flag.String("out", "", "write generated program to out") 22 ) 23 24 func TestHilbert(t *testing.T) { 25 // generate source 26 src := program(*H, *out) 27 if *out != "" { 28 os.WriteFile(*out, src, 0666) 29 return 30 } 31 32 DefPredeclaredTestFuncs() // declare assert (used by code generated by verify) 33 mustTypecheck(string(src), nil, nil) 34 } 35 36 func program(n int, out string) []byte { 37 var g gen 38 39 g.p(`// Code generated by: go test -run=Hilbert -H=%d -out=%q. DO NOT EDIT. 40 41 // +`+`build ignore 42 43 // This program tests arbitrary precision constant arithmetic 44 // by generating the constant elements of a Hilbert matrix H, 45 // its inverse I, and the product P = H*I. The product should 46 // be the identity matrix. 47 package main 48 49 func main() { 50 if !ok { 51 printProduct() 52 return 53 } 54 println("PASS") 55 } 56 57 `, n, out) 58 g.hilbert(n) 59 g.inverse(n) 60 g.product(n) 61 g.verify(n) 62 g.printProduct(n) 63 g.binomials(2*n - 1) 64 g.factorials(2*n - 1) 65 66 return g.Bytes() 67 } 68 69 type gen struct { 70 bytes.Buffer 71 } 72 73 func (g *gen) p(format string, args ...interface{}) { 74 fmt.Fprintf(&g.Buffer, format, args...) 75 } 76 77 func (g *gen) hilbert(n int) { 78 g.p(`// Hilbert matrix, n = %d 79 const ( 80 `, n) 81 for i := 0; i < n; i++ { 82 g.p("\t") 83 for j := 0; j < n; j++ { 84 if j > 0 { 85 g.p(", ") 86 } 87 g.p("h%d_%d", i, j) 88 } 89 if i == 0 { 90 g.p(" = ") 91 for j := 0; j < n; j++ { 92 if j > 0 { 93 g.p(", ") 94 } 95 g.p("1.0/(iota + %d)", j+1) 96 } 97 } 98 g.p("\n") 99 } 100 g.p(")\n\n") 101 } 102 103 func (g *gen) inverse(n int) { 104 g.p(`// Inverse Hilbert matrix 105 const ( 106 `) 107 for i := 0; i < n; i++ { 108 for j := 0; j < n; j++ { 109 s := "+" 110 if (i+j)&1 != 0 { 111 s = "-" 112 } 113 g.p("\ti%d_%d = %s%d * b%d_%d * b%d_%d * b%d_%d * b%d_%d\n", 114 i, j, s, i+j+1, n+i, n-j-1, n+j, n-i-1, i+j, i, i+j, i) 115 } 116 g.p("\n") 117 } 118 g.p(")\n\n") 119 } 120 121 func (g *gen) product(n int) { 122 g.p(`// Product matrix 123 const ( 124 `) 125 for i := 0; i < n; i++ { 126 for j := 0; j < n; j++ { 127 g.p("\tp%d_%d = ", i, j) 128 for k := 0; k < n; k++ { 129 if k > 0 { 130 g.p(" + ") 131 } 132 g.p("h%d_%d*i%d_%d", i, k, k, j) 133 } 134 g.p("\n") 135 } 136 g.p("\n") 137 } 138 g.p(")\n\n") 139 } 140 141 func (g *gen) verify(n int) { 142 g.p(`// Verify that product is the identity matrix 143 const ok = 144 `) 145 for i := 0; i < n; i++ { 146 for j := 0; j < n; j++ { 147 if j == 0 { 148 g.p("\t") 149 } else { 150 g.p(" && ") 151 } 152 v := 0 153 if i == j { 154 v = 1 155 } 156 g.p("p%d_%d == %d", i, j, v) 157 } 158 g.p(" &&\n") 159 } 160 g.p("\ttrue\n\n") 161 162 // verify ok at type-check time 163 if *out == "" { 164 g.p("const _ = assert(ok)\n\n") 165 } 166 } 167 168 func (g *gen) printProduct(n int) { 169 g.p("func printProduct() {\n") 170 for i := 0; i < n; i++ { 171 g.p("\tprintln(") 172 for j := 0; j < n; j++ { 173 if j > 0 { 174 g.p(", ") 175 } 176 g.p("p%d_%d", i, j) 177 } 178 g.p(")\n") 179 } 180 g.p("}\n\n") 181 } 182 183 func (g *gen) binomials(n int) { 184 g.p(`// Binomials 185 const ( 186 `) 187 for j := 0; j <= n; j++ { 188 if j > 0 { 189 g.p("\n") 190 } 191 for k := 0; k <= j; k++ { 192 g.p("\tb%d_%d = f%d / (f%d*f%d)\n", j, k, j, k, j-k) 193 } 194 } 195 g.p(")\n\n") 196 } 197 198 func (g *gen) factorials(n int) { 199 g.p(`// Factorials 200 const ( 201 f0 = 1 202 f1 = 1 203 `) 204 for i := 2; i <= n; i++ { 205 g.p("\tf%d = f%d * %d\n", i, i-1, i) 206 } 207 g.p(")\n\n") 208 }