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  }