mirror of
https://github.com/gonum/gonum.git
synced 2025-10-08 16:40:06 +08:00
143 lines
3.9 KiB
Go
143 lines
3.9 KiB
Go
// Copyright ©2015 The gonum 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 conv provides matrix type interconversion utilities.
|
|
package conv // import "gonum.org/v1/gonum/matrix/conv"
|
|
|
|
import (
|
|
"gonum.org/v1/gonum/matrix"
|
|
"gonum.org/v1/gonum/matrix/cmat128"
|
|
"gonum.org/v1/gonum/matrix/mat64"
|
|
)
|
|
|
|
// Complex is a complex matrix constructed from two real matrices.
|
|
type Complex struct {
|
|
// r and i are not exposed to ensure that
|
|
// their dimensions can not be altered by
|
|
// clients behind our back.
|
|
r, i mat64.Matrix
|
|
|
|
// imagSign holds the sign of the imaginary
|
|
// part of the Complex. Valid values are 1 and -1.
|
|
imagSign float64
|
|
}
|
|
|
|
var (
|
|
_ Realer = Complex{}
|
|
_ Imager = Complex{}
|
|
)
|
|
|
|
// NewComplex returns a complex matrix constructed from r and i. At least one of
|
|
// r or i must be non-nil otherwise NewComplex will panic. If one of the inputs
|
|
// is nil, that part of the complex number will be zero when returned by At.
|
|
// If both are non-nil but differ in their sizes, NewComplex will panic.
|
|
func NewComplex(r, i mat64.Matrix) Complex {
|
|
if r == nil && i == nil {
|
|
panic("conv: no matrix")
|
|
} else if r != nil && i != nil {
|
|
rr, rc := r.Dims()
|
|
ir, ic := i.Dims()
|
|
if rr != ir || rc != ic {
|
|
panic(matrix.ErrShape)
|
|
}
|
|
}
|
|
return Complex{r: r, i: i, imagSign: 1}
|
|
}
|
|
|
|
// Dims returns the number of rows and columns in the matrix.
|
|
func (m Complex) Dims() (r, c int) {
|
|
if m.r == nil {
|
|
return m.i.Dims()
|
|
}
|
|
return m.r.Dims()
|
|
}
|
|
|
|
// At returns the element at row i, column j.
|
|
func (m Complex) At(i, j int) complex128 {
|
|
if m.i == nil {
|
|
return complex(m.r.At(i, j), 0)
|
|
}
|
|
if m.r == nil {
|
|
return complex(0, m.imagSign*m.i.At(i, j))
|
|
}
|
|
return complex(m.r.At(i, j), m.imagSign*m.i.At(i, j))
|
|
}
|
|
|
|
// 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(), imagSign: -m.imagSign}
|
|
}
|
|
return Complex{r: m.r.T(), i: m.i.T(), imagSign: -m.imagSign}
|
|
}
|
|
|
|
// Real returns the real part of the receiver.
|
|
func (m Complex) Real() mat64.Matrix { return m.r }
|
|
|
|
// Imag returns the imaginary part of the receiver.
|
|
func (m Complex) Imag() mat64.Matrix { return m.i }
|
|
|
|
// Realer is a complex matrix that can return its real part.
|
|
type Realer interface {
|
|
Real() mat64.Matrix
|
|
}
|
|
|
|
// Imager is a complex matrix that can return its imaginary part.
|
|
type Imager interface {
|
|
Imag() mat64.Matrix
|
|
}
|
|
|
|
// Real is the real part of a complex 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.
|
|
func NewReal(m cmat128.Matrix) mat64.Matrix {
|
|
if m, ok := m.(Realer); ok {
|
|
return m.Real()
|
|
}
|
|
return Real{m}
|
|
}
|
|
|
|
// Dims returns the number of rows and columns in the matrix.
|
|
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)) }
|
|
|
|
// T performs an implicit transpose.
|
|
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
|
|
|
|
// conjSign holds the sign of the matrix.
|
|
// Valid values are 1 and -1.
|
|
conjSign float64
|
|
}
|
|
|
|
// NewImag 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{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() }
|
|
|
|
// At returns the element at row i, column 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{matrix: m.matrix.H(), conjSign: -m.conjSign} }
|