1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 // A little test program and benchmark for rational arithmetics.
6 // Computes a Hilbert matrix, its inverse, multiplies them
7 // and verifies that the product is the identity matrix.
23 func (a
*matrix
) at(i
, j
int) *Rat
{
24 if !(0 <= i
&& i
< a
.n
&& 0 <= j
&& j
< a
.m
) {
25 panic("index out of range")
31 func (a
*matrix
) set(i
, j
int, x
*Rat
) {
32 if !(0 <= i
&& i
< a
.n
&& 0 <= j
&& j
< a
.m
) {
33 panic("index out of range")
39 func newMatrix(n
, m
int) *matrix
{
40 if !(0 <= n
&& 0 <= m
) {
41 panic("illegal matrix")
46 a
.a
= make([]*Rat
, n
*m
)
51 func newUnit(n
int) *matrix
{
53 for i
:= 0; i
< n
; i
++ {
54 for j
:= 0; j
< n
; j
++ {
66 func newHilbert(n
int) *matrix
{
68 for i
:= 0; i
< n
; i
++ {
69 for j
:= 0; j
< n
; j
++ {
70 a
.set(i
, j
, NewRat(1, int64(i
+j
+1)))
77 func newInverseHilbert(n
int) *matrix
{
79 for i
:= 0; i
< n
; i
++ {
80 for j
:= 0; j
< n
; j
++ {
81 x1
:= new(Rat
).SetInt64(int64(i
+ j
+ 1))
82 x2
:= new(Rat
).SetInt(new(Int
).Binomial(int64(n
+i
), int64(n
-j
-1)))
83 x3
:= new(Rat
).SetInt(new(Int
).Binomial(int64(n
+j
), int64(n
-i
-1)))
84 x4
:= new(Rat
).SetInt(new(Int
).Binomial(int64(i
+j
), int64(i
)))
102 func (a
*matrix
) mul(b
*matrix
) *matrix
{
104 panic("illegal matrix multiply")
106 c
:= newMatrix(a
.n
, b
.m
)
107 for i
:= 0; i
< c
.n
; i
++ {
108 for j
:= 0; j
< c
.m
; j
++ {
110 for k
:= 0; k
< a
.m
; k
++ {
111 x
.Add(x
, new(Rat
).Mul(a
.at(i
, k
), b
.at(k
, j
)))
120 func (a
*matrix
) eql(b
*matrix
) bool {
121 if a
.n
!= b
.n || a
.m
!= b
.m
{
124 for i
:= 0; i
< a
.n
; i
++ {
125 for j
:= 0; j
< a
.m
; j
++ {
126 if a
.at(i
, j
).Cmp(b
.at(i
, j
)) != 0 {
135 func (a
*matrix
) String() string {
137 for i
:= 0; i
< a
.n
; i
++ {
138 for j
:= 0; j
< a
.m
; j
++ {
139 s
+= fmt
.Sprintf("\t%s", a
.at(i
, j
))
147 func doHilbert(t
*testing
.T
, n
int) {
149 b
:= newInverseHilbert(n
)
154 panic("Hilbert failed")
156 t
.Errorf("a = %s\n", a
)
157 t
.Errorf("b = %s\n", b
)
158 t
.Errorf("a*b = %s\n", ab
)
159 t
.Errorf("I = %s\n", I
)
164 func TestHilbert(t
*testing
.T
) {
169 func BenchmarkHilbert(b
*testing
.B
) {
170 for i
:= 0; i
< b
.N
; i
++ {