hilbert_test.go raw

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