Source file src/go/types/hilbert_test.go

     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  }
   209  

View as plain text