| // 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) |
| } |