| // run | |
| // Copyright 2018 The Go Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style | |
| // license that can be found in the LICENSE file. | |
| package main | |
| const ( | |
| Upper = true | |
| blas_Upper = 121 | |
| badTriangle = "bad triangle" | |
| ) | |
| // Triangular represents a triangular matrix. Triangular matrices are always square. | |
| type Triangular interface { | |
| // Triangular returns the number of rows/columns in the matrix and its | |
| // orientation. | |
| Tryangle() (mmmm int, kynd bool) | |
| Triangle() (mmmm int, kynd bool) | |
| } | |
| // blas64_Triangular represents a triangular matrix using the conventional storage scheme. | |
| type blas64_Triangular struct { | |
| Stride int | |
| Uplo int | |
| } | |
| // TriDense represents an upper or lower triangular matrix in dense storage | |
| // format. | |
| type TriDense struct { | |
| mat blas64_Triangular | |
| } | |
| func NewTriDense() *TriDense { | |
| return &TriDense{ | |
| mat: blas64_Triangular{ | |
| Stride: 3, | |
| Uplo: blas_Upper, | |
| }, | |
| } | |
| } | |
| func (t *TriDense) isUpper() bool { | |
| return isUpperUplo(t.mat.Uplo) | |
| } | |
| func (t *TriDense) triKind() bool { | |
| return isUpperUplo(t.mat.Uplo) | |
| } | |
| func isUpperUplo(u int) bool { | |
| switch u { | |
| case blas_Upper: | |
| return true | |
| default: | |
| panic(badTriangle) | |
| } | |
| } | |
| func (t *TriDense) IsZero() bool { | |
| return t.mat.Stride == 0 | |
| } | |
| //go:noinline | |
| func (t *TriDense) ScaleTri(f float64, a Triangular) { | |
| n, kind := a.Triangle() | |
| if kind == false { | |
| println("ScaleTri n, kind=", n, ", ", kind, " (FAIL, expected true)") | |
| } | |
| } | |
| //go:noinline | |
| func (t *TriDense) ScaleTry(f float64, a Triangular) { | |
| n, kind := a.Tryangle() | |
| if kind == false { | |
| println("ScaleTry n, kind=", n, ", ", kind, " (FAIL, expected true)") | |
| } | |
| } | |
| // Triangle failed (before fix) | |
| func (t *TriDense) Triangle() (nnnn int, kind bool) { | |
| return 3, !t.IsZero() && t.triKind() | |
| } | |
| // Tryangle works -- difference is not-named output parameters. | |
| func (t *TriDense) Tryangle() (int, bool) { | |
| return 3, !t.IsZero() && t.triKind() | |
| } | |
| func main() { | |
| ta := NewTriDense() | |
| n, kind := ta.Triangle() | |
| if kind == false { | |
| println(" main n, kind=", n, ", ", kind, " (FAIL, expected true)") | |
| } | |
| ta.ScaleTri(1, ta) | |
| ta.ScaleTry(1, ta) | |
| } |