Skip to content
This repository has been archived by the owner on Dec 10, 2018. It is now read-only.

Commit

Permalink
{conv,cmat128}: make cmat128.Matrix implement conjugate transpose
Browse files Browse the repository at this point in the history
  • Loading branch information
kortschak committed Feb 11, 2016
1 parent d46452f commit e6b4fa4
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 40 deletions.
50 changes: 26 additions & 24 deletions cmat128/matrix.go
Expand Up @@ -13,56 +13,58 @@ type Matrix interface {
// It will panic if i or j are out of bounds for the matrix.
At(i, j int) complex128

// T returns the transpose of the Matrix. Whether T returns a copy of the
// underlying data is implementation dependent.
// This method may be implemented using the Transpose type, which
// provides an implicit matrix transpose.
T() Matrix
// H returns the conjugate transpose of the Matrix. Whether H
// returns a copy of the underlying data is implementation dependent.
// This method may be implemented using the Conjugate type, which
// provides an implicit matrix conjugate transpose.
H() Matrix
}

var (
_ Matrix = Transpose{}
_ Untransposer = Transpose{}
_ Matrix = Conjugate{}
_ Unconjugator = Conjugate{}
)

// Transpose is a type for performing an implicit matrix transpose. It implements
// the Matrix interface, returning values from the transpose of the matrix within.
type Transpose struct {
// Conjugate is a type for performing an implicit matrix conjugate transpose.
// It implements the Matrix interface, returning values from the conjugate
// transpose of the matrix within.
type Conjugate struct {
Matrix Matrix
}

// At returns the value of the element at row i and column j of the transposed
// matrix, that is, row j and column i of the Matrix field.
func (t Transpose) At(i, j int) complex128 {
return t.Matrix.At(j, i)
func (t Conjugate) At(i, j int) complex128 {
return t.Matrix.At(j, i) * complex(1, -1)
}

// Dims returns the dimensions of the transposed matrix. The number of rows returned
// is the number of columns in the Matrix field, and the number of columns is
// the number of rows in the Matrix field.
func (t Transpose) Dims() (r, c int) {
func (t Conjugate) Dims() (r, c int) {
c, r = t.Matrix.Dims()
return r, c
}

// T performs an implicit transpose by returning the Matrix field.
func (t Transpose) T() Matrix {
// H performs an implicit conjugate transpose by returning the Matrix field.
func (t Conjugate) H() Matrix {
return t.Matrix
}

// Untranspose returns the Matrix field.
func (t Transpose) Untranspose() Matrix {
// Unconjugate returns the Matrix field.
func (t Conjugate) Unconjugate() Matrix {
return t.Matrix
}

// Untransposer is a type that can undo an implicit transpose.
type Untransposer interface {
// Note: This interface is needed to unify all of the Transpose types. In
// Unconjugator is a type that can undo an implicit conjugate transpose.
type Unconjugator interface {
// Note: This interface is needed to unify all of the Conjugate types. In
// the cmat128 methods, we need to test if the Matrix has been implicitly
// transposed. If this is checked by testing for the specific Transpose type
// then the behavior will be different if the user uses T() or TTri() for a
// transposed. If this is checked by testing for the specific Conjugate type
// then the behavior will be different if the user uses H() or HTri() for a
// triangular matrix.

// Untranspose returns the underlying Matrix stored for the implicit transpose.
Untranspose() Matrix
// Unconjugate returns the underlying Matrix stored for the implicit
// conjugate transpose.
Unconjugate() Matrix
}
44 changes: 28 additions & 16 deletions conv/conv.go
Expand Up @@ -17,6 +17,10 @@ type Complex struct {
// their dimensions can not be altered by
// clients behind our back.
r, i mat64.Matrix

// imagSign hold the sign of the imaginary
// part of the Complex. Valid values are 1 and -1.
imagSign float64
}

var (
Expand All @@ -38,7 +42,7 @@ func NewComplex(r, i mat64.Matrix) Complex {
panic(matrix.ErrShape)
}
}
return Complex{r: r, i: i}
return Complex{r: r, i: i, imagSign: 1}
}

// Dims returns the number of rows and columns in the matrix.
Expand All @@ -55,20 +59,20 @@ func (m Complex) At(i, j int) complex128 {
return complex(m.r.At(i, j), 0)
}
if m.r == nil {
return complex(0, m.i.At(i, j))
return complex(0, m.imagSign*m.i.At(i, j))
}
return complex(m.r.At(i, j), m.i.At(i, j))
return complex(m.r.At(i, j), m.imagSign*m.i.At(i, j))
}

// T performs an implicit transpose.
func (m Complex) T() cmat128.Matrix {
// H performs an implicit transpose.
func (m Complex) H() cmat128.Matrix {
if m.i == nil {
return Complex{r: m.r.T()}
}
if m.r == nil {
return Complex{i: m.i.T()}
return Complex{i: m.i.T(), imagSign: -m.imagSign}
}
return Complex{r: m.r.T(), i: m.i.T()}
return Complex{r: m.r.T(), i: m.i.T(), imagSign: -m.imagSign}
}

// Real returns the real part of the receiver.
Expand All @@ -88,7 +92,9 @@ type Imager interface {
}

// Real is the real part of a complex matrix.
type Real struct{ Matrix cmat128.Matrix }
type Real struct {
matrix cmat128.Matrix
}

// NewReal returns a mat64.Matrix representing the real part of m. If m is a Realer,
// the real part is returned.
Expand All @@ -100,31 +106,37 @@ func NewReal(m cmat128.Matrix) mat64.Matrix {
}

// Dims returns the number of rows and columns in the matrix.
func (m Real) Dims() (r, c int) { return m.Matrix.Dims() }
func (m Real) Dims() (r, c int) { return m.matrix.Dims() }

// At returns the element at row i, column j.
func (m Real) At(i, j int) float64 { return real(m.Matrix.At(i, j)) }
func (m Real) At(i, j int) float64 { return real(m.matrix.At(i, j)) }

// T performs an implicit transpose.
func (m Real) T() mat64.Matrix { return Real{m.Matrix.T()} }
func (m Real) T() mat64.Matrix { return Real{m.matrix.H()} }

// Imag is the imaginary part of a complex matrix.
type Imag struct{ Matrix cmat128.Matrix }
type Imag struct {
matrix cmat128.Matrix

// conjSign holds the sign of the matrix.
// Valid values are 1 and -1.
conjSign float64
}

// NewImage returns a mat64.Matrix representing the imaginary part of m. If m is an Imager,
// the imaginary part is returned.
func NewImag(m cmat128.Matrix) mat64.Matrix {
if m, ok := m.(Imager); ok {
return m.Imag()
}
return Imag{m}
return Imag{matrix: m, conjSign: 1}
}

// Dims returns the number of rows and columns in the matrix.
func (m Imag) Dims() (r, c int) { return m.Matrix.Dims() }
func (m Imag) Dims() (r, c int) { return m.matrix.Dims() }

// At returns the element at row i, column j.
func (m Imag) At(i, j int) float64 { return imag(m.Matrix.At(i, j)) }
func (m Imag) At(i, j int) float64 { return m.conjSign * imag(m.matrix.At(i, j)) }

// T performs an implicit transpose.
func (m Imag) T() mat64.Matrix { return Imag{m.Matrix.T()} }
func (m Imag) T() mat64.Matrix { return Imag{matrix: m.matrix.H(), conjSign: -m.conjSign} }

0 comments on commit e6b4fa4

Please sign in to comment.