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