Source file src/go/types/hilbert_test.go

     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  

View as plain text