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