// Function to obtain complex conjugate (dagger operation) of // sparse matrix stored in diagonal form func SparseDiagDagger(s *SparseMat) *SparseMat { // Initiaize variables for indexing purposes matSize := len(s.Data) numDiags := len(s.Data[0]) mainDiagIdx := (numDiags - 1) / 2 // Initialize output variable t := SparseCopy(s) for idx0 := 0; idx0 < matSize; idx0++ { // Complex conjugate main diagonal t.Data[idx0][mainDiagIdx] = cmplx.Conj(t.Data[idx0][mainDiagIdx]) // When there are more than one diagonal stored, and if we are not in the top left most entry, // we will need to swap rows and columns, and complex conjugate those entries as well. if (idx0 > 1) && (mainDiagIdx > 0) { loopIdx := mainDiagIdx if idx0 < loopIdx { loopIdx = idx0 } for idx1 := 1; idx1 < loopIdx; idx1++ { // Swap row and columns, and conjugate those entries t.Data[idx0][mainDiagIdx-idx1], t.Data[idx0-idx1][mainDiagIdx+idx1] = cmplx.Conj(t.Data[idx0-idx1][mainDiagIdx+idx1]), cmplx.Conj(t.Data[idx0][mainDiagIdx-idx1]) } } } return t }
func (a *matrix) choleskyDecomp() *matrix { l := like(a) // Cholesky-Banachiewicz algorithm for r, rxc0 := 0, 0; r < a.stride; r++ { // calculate elements along row, up to diagonal x := rxc0 for c, cxc0 := 0, 0; c < r; c++ { sum := a.ele[x] for k := 0; k < c; k++ { sum -= l.ele[rxc0+k] * cmplx.Conj(l.ele[cxc0+k]) } l.ele[x] = sum / l.ele[cxc0+c] x++ cxc0 += a.stride } // calcualate diagonal element sum := a.ele[x] for k := 0; k < r; k++ { sum -= l.ele[rxc0+k] * cmplx.Conj(l.ele[rxc0+k]) } l.ele[x] = cmplx.Sqrt(sum) rxc0 += a.stride } return l }
// Function to compute basis transformation matrix func BasisTransform(th, phi float64) *[2][2]complex128 { BTMatrix := new([2][2]complex128) th_2, phi_2 := 0.5*th, 0.5*phi csn := cmplx.Cos(complex(th_2, 0.0)) * cmplx.Exp(complex(0.0, -1.0*phi_2)) sn := cmplx.Sin(complex(th_2, 0.0)) * cmplx.Exp(complex(0.0, phi_2)) BTMatrix[0][0] = cmplx.Conj(csn) BTMatrix[0][1] = cmplx.Conj(sn) BTMatrix[1][0] = complex(-1.0, 0.0) * sn BTMatrix[1][1] = csn return BTMatrix }
func XCorrFFT(x1, x2 []float64, circular bool) []float64 { // zero padding. ftlength := len(x1) if !circular { length := len(x1) * 2 var i uint32 = 1 for ftlength < length { ftlength = 1 << i i++ } } datax1 := make([]complex128, ftlength) datax2 := make([]complex128, ftlength) for i := 0; i < len(x1); i++ { datax1[i] = complex(x2[i%len(x2)], 0) datax2[i] = complex(x1[i%len(x1)], 0) } v1 := fft.FFT(datax1) v2 := fft.FFT(datax2) temp := []complex128{} for i := 0; i < len(v1); i++ { v := v1[i] * cmplx.Conj(v2[i]) temp = append(temp, v) } v3 := fft.IFFT(temp) res := []float64{} for i := 0; i < len(x1); i++ { res = append(res, real(v3[i])) } return res }
func (a *triangleMat) Set(i, j int, x complex128) { if otherTri(i, j, a.Tri) { i, j = j, i x = cmplx.Conj(x) } a.Set(i, j, x) }
func (this *Matrix) parallel_Traspose(i0, i1, j0, j1 int, res *Matrix, done chan<- bool, conjugate bool) { di := i1 - i0 dj := j1 - j0 done2 := make(chan bool, THRESHOLD) if di >= dj && di >= THRESHOLD && runtime.NumGoroutine() < maxGoRoutines { mi := i0 + di/2 go this.parallel_Traspose(i0, mi, j0, j1, res, done2, conjugate) this.parallel_Traspose(mi, i1, j0, j1, res, done2, conjugate) <-done2 <-done2 } else if dj >= THRESHOLD && runtime.NumGoroutine() < maxGoRoutines { mj := j0 + dj/2 go this.parallel_Traspose(i0, i1, j0, mj, res, done2, conjugate) this.parallel_Traspose(i0, i1, mj, i1, res, done2, conjugate) <-done2 <-done2 } else { if !conjugate { for i := i0; i <= i1; i++ { for j := j0; j <= j1; j++ { res.SetValue(j, i, this.GetValue(i, j)) } } } else { for i := i0; i <= i1; i++ { for j := j0; j <= j1; j++ { res.SetValue(j, i, cmplx.Conj(this.GetValue(i, j))) } } } } done <- true }
func (self *ComplexV) VmulConj(b *ComplexV) *ComplexV { r := Zeros(len(*self)) for k, a := range *self { (*r)[k] = a * cmplx.Conj((*b)[k]) } return r }
func (self *ComplexV) Conj() *ComplexV { r := Zeros(len(*self)) for k, a := range *self { (*r)[k] = cmplx.Conj(a) } return r }
func ZdotcInc(x, y []complex128, n, incX, incY, ix, iy uintptr) (sum complex128) { for i := 0; i < int(n); i++ { sum += y[iy] * cmplx.Conj(x[ix]) ix += incX iy += incY } return }
// ci <- k conj(ai) bi func scaleMul(c *fftw.Array2, k complex128, a, b *fftw.Array2) { m, n := a.Dims() for i := 0; i < m; i++ { for j := 0; j < n; j++ { ax := cmplx.Conj(a.At(i, j)) bx := b.At(i, j) c.Set(i, j, k*ax*bx) } } }
// Creates a conjugated copy of the matrix. func Conj(a Const) *Mat { m, n := a.Dims() b := New(m, n) for i := 0; i < m; i++ { for j := 0; j < n; j++ { b.Set(i, j, cmplx.Conj(a.At(i, j))) } } return b }
// ci <- ci + conj(ai) bi func addMul(c *fftw.Array2, a, b *fftw.Array2) { m, n := a.Dims() for i := 0; i < m; i++ { for j := 0; j < n; j++ { ax := cmplx.Conj(a.At(i, j)) bx := b.At(i, j) cx := c.At(i, j) c.Set(i, j, cx+ax*bx) } } }
// implementation of Trans method func (v *vectorComplex) Trans() { if v.Type() == ColVector { v.vectorType = RowVector } else { v.vectorType = ColVector } for i := 0; i < v.Dim(); i++ { v.elements[i] = cmplx.Conj(v.elements[i]) } }
func (a *triangleMat) At(i, j int) complex128 { swap := otherTri(i, j, a.Tri) if swap { i, j = j, i } x := a.Mat.At(i, j) if swap { x = cmplx.Conj(x) } return x }
func main() { a := 1 + 1i b := 3.14159 + 1.25i fmt.Println("a: ", a) fmt.Println("b: ", b) fmt.Println("a + b: ", a+b) fmt.Println("a * b: ", a*b) fmt.Println("-a: ", -a) fmt.Println("1 / a: ", 1/a) fmt.Println("a̅: ", cmplx.Conj(a)) }
// Calc tests whether c is in the Mandelbrot set. // return 0 if c is in the set, // otherwise return i (> 0) where i is number of trials // when absolute value of z exceed by 2. func Calc(c complex128, limit int) (int, complex128) { z := c for i := 1; i <= limit; i++ { if real(z*cmplx.Conj(z)) > 4 { return i, z } z *= z z += c } return 0, z }
func (cdma *CDMA) DeSpread(InCH gocomm.Complex128Channel, OutCH gocomm.Complex128Channel) { despcode := vlib.Conj(cdma.SpreadSequence) var result complex128 for i := 0; i < len(despcode); i++ { rxchips := (<-InCH).Ch result += rxchips * cmplx.Conj(despcode[i]) } var chdataOut gocomm.SComplex128Obj chdataOut.Ch = result OutCH <- chdataOut }
// conjugate transpose, implemented here as a method on the matrix type. func (m *matrix) conjTranspose() *matrix { r := &matrix{make([]complex128, len(m.ele)), len(m.ele) / m.cols} rx := 0 for _, e := range m.ele { r.ele[rx] = cmplx.Conj(e) rx += r.cols if rx >= len(r.ele) { rx -= len(r.ele) - 1 } } return r }
func (self *ComplexV) FindMax() (inx int, a float64) { a = 0. inx = 0 for k, x := range *self { p := x * cmplx.Conj(x) if real(p) > a { a = real(p) inx = k } } return inx, a }
func ComplexRoots(f []complex128, p0 complex128, p1 complex128, p2 complex128, e float64) complex128 { k := 0 + 0i m := cmplx.Sqrt((HornerItCmplx(f, p2)) * cmplx.Conj(HornerItCmplx(f, p2))) n := cmplx.Sqrt((HornerItCmplx(f, p2))*cmplx.Conj(HornerItCmplx(f, p2))) - cmplx.Sqrt((HornerItCmplx(f, k))*cmplx.Conj(HornerItCmplx(f, k))) var mr, nr float64 mr, nr = real(m), real(n) j := 1 for (mr > e || math.Abs(nr) > e) && j < 1000*len(f) { A := ((p1-p2)*(HornerItCmplx(f, p0)-HornerItCmplx(f, p2)) - (p0-p1)*(HornerItCmplx(f, p1)-HornerItCmplx(f, p2))) / ((p0 - p2) * (p1 - p2) * (p0 - p1)) B := ((cmplx.Pow(p0-p2, 2))*(HornerItCmplx(f, p1)-HornerItCmplx(f, p2)) - (cmplx.Pow(p1-p2, 2))*(HornerItCmplx(f, p0)-HornerItCmplx(f, p2))) / ((p0 - p2) * (p1 - p2) * (p0 - p1)) C := HornerItCmplx(f, p2) div1 := cmplx.Sqrt((B + cmplx.Sqrt(cmplx.Pow(B, 2)-4*A*C)) * cmplx.Conj(B+cmplx.Sqrt(cmplx.Pow(B, 2)-4*A*C))) div2 := cmplx.Sqrt((B - cmplx.Sqrt(cmplx.Pow(B, 2)-4*A*C)) * (cmplx.Conj(B - cmplx.Sqrt(cmplx.Pow(B, 2)-4*A*C)))) var div1r, div2r float64 div1r, div2r = real(div1), real(div2) var D complex128 if div1r > div2r { D = (B + cmplx.Sqrt(cmplx.Pow(B, 2)-4*A*C)) } else { D = (B - cmplx.Sqrt(cmplx.Pow(B, 2)-4*A*C)) } p3 := p2 - ((2 * C) / D) k = p2 p2, p1, p0 = p3, p2, p1 m := cmplx.Sqrt((HornerItCmplx(f, p2)) * cmplx.Conj(HornerItCmplx(f, p2))) n := cmplx.Sqrt((HornerItCmplx(f, p2))*cmplx.Conj(HornerItCmplx(f, p2))) - cmplx.Sqrt((HornerItCmplx(f, k))*cmplx.Conj(HornerItCmplx(f, k))) mr, nr = real(m), real(n) j++ } return p2 }
// Returns an error if the matrix is not Hermitian. // Assumes that matrix is square. func errNonHerm(a Const) error { n, _ := a.Dims() for i := 0; i < n; i++ { for j := i; j < n; j++ { ij, ji := a.At(i, j), a.At(j, i) want, got := ij, cmplx.Conj(ji) if !(eqEpsAbs(want, got, EpsHermAbs) || eqEpsRel(want, got, EpsHermRel)) { return fmt.Errorf("not Hermitian: at %d, %d: upper %g, lower %g", i, j, ij, ji) } } } return nil }
// isLeftEigenvectorOf returns whether the vector yRe+i*yIm, where i is the // imaginary unit, is the left eigenvector of A corresponding to the eigenvalue // lambda. // // A left eigenvector corresponding to a complex eigenvalue λ is a complex // non-zero vector y such that // y^H A = λ y^H, // which is equivalent for real A to // A^T y = conj(λ) y, func isLeftEigenvectorOf(a blas64.General, yRe, yIm []float64, lambda complex128, tol float64) bool { if a.Rows != a.Cols { panic("matrix not square") } if imag(lambda) != 0 && yIm == nil { // Complex eigenvalue of a real matrix cannot have a real // eigenvector. return false } n := a.Rows // Compute A^T real(y) and store the result into yReAns. yReAns := make([]float64, n) blas64.Gemv(blas.Trans, 1, a, blas64.Vector{1, yRe}, 0, blas64.Vector{1, yReAns}) if imag(lambda) == 0 && yIm == nil { // Real eigenvalue and eigenvector. // Compute λy and store the result into lambday. lambday := make([]float64, n) floats.AddScaled(lambday, real(lambda), yRe) if floats.Distance(yReAns, lambday, math.Inf(1)) > tol { return false } return true } // Complex eigenvector, and real or complex eigenvalue. // Compute A^T imag(y) and store the result into yImAns. yImAns := make([]float64, n) blas64.Gemv(blas.Trans, 1, a, blas64.Vector{1, yIm}, 0, blas64.Vector{1, yImAns}) // Compute conj(λ)y and store the result into lambday. lambda = cmplx.Conj(lambda) lambday := make([]complex128, n) for i := range lambday { lambday[i] = lambda * complex(yRe[i], yIm[i]) } for i, v := range lambday { ay := complex(yReAns[i], yImAns[i]) if cmplx.Abs(v-ay) > tol { return false } } return true }
func main() { f := 3.2e5 display(f) x := -7.3 - 8.9i display(x) y := complex64(-18.3 + 8.9i) display(y) z := complex(f, 13.2) display(z) display(real(y)) display(imag(z)) display(cmplx.Conj(z)) display(cmplx.Inf()) display(cmplx.NaN()) display(cmplx.Sqrt(z)) }
// implementation of Trans method func (m *matrixComplex) Trans() { transMatrixNumCols := m.numRows transMatrixNumRows := m.numCols transMatrixElements := make([][]complex128, transMatrixNumRows) for i := 0; i < len(transMatrixElements); i++ { transMatrixElements[i] = make([]complex128, transMatrixNumCols) } for i := 0; i < transMatrixNumRows; i++ { for j := 0; j < transMatrixNumCols; j++ { transMatrixElements[i][j] = cmplx.Conj(m.Get(j, i)) } } m.numRows = transMatrixNumRows m.numCols = transMatrixNumCols m.elements = transMatrixElements }
// return a ConjugateTraspose func (this *Matrix) ConjugateTraspose() *Matrix { if this.m == 1 || this.n == 1 { c := this.Copy() t := c.m c.m = c.n c.n = t c = c.Apply( func(a complex128) complex128 { return cmplx.Conj(a) }) return c } out := NullMatrixP(this.n, this.m) done := make(chan bool) go this.parallel_Traspose(1, this.m, 1, this.n, out, done, true) <-done return out }
// Function for calculating the self-energy matrices func SelfEnergyEntries(currEnergy, modeEnergy, delta0, delta1, potential float64, t0 complex128, BT_Mat *[2][2]complex128) *[2][2]complex128 { s := new([2][2]complex128) SumEnergy := complex(currEnergy-modeEnergy+0.5*potential-delta0, utils.Zplus) SumEnergy /= complex(-2.0, 0.0) * t0 SumEnergy += complex(1.0, 0.0) sig_uu := complex(-1.0, 0.0) * t0 * cmplx.Exp(1.0i*cmplx.Acos(SumEnergy)) SumEnergy = complex(currEnergy-modeEnergy+0.5*potential-delta1, utils.Zplus) SumEnergy /= complex(-2.0, 0.0) * t0 SumEnergy += complex(1.0, 0.0) sig_dd := complex(-1.0, 0.0) * t0 * cmplx.Exp(1.0i*cmplx.Acos(SumEnergy)) s[0][0] = cmplx.Conj(BT_Mat[0][0])*sig_uu*BT_Mat[0][0] + cmplx.Conj(BT_Mat[1][0])*sig_dd*BT_Mat[1][0] s[0][1] = cmplx.Conj(BT_Mat[0][0])*sig_uu*BT_Mat[0][1] + cmplx.Conj(BT_Mat[1][0])*sig_dd*BT_Mat[1][1] s[1][0] = cmplx.Conj(BT_Mat[0][1])*sig_uu*BT_Mat[0][0] + cmplx.Conj(BT_Mat[1][1])*sig_dd*BT_Mat[1][0] s[1][1] = cmplx.Conj(BT_Mat[0][1])*sig_uu*BT_Mat[0][1] + cmplx.Conj(BT_Mat[1][1])*sig_dd*BT_Mat[1][1] return s }
// Given a buffer length, symbol length and a binary bitstring, compute the // frequency domain of the preamble for later use. func NewPreambleDetector(n uint, symbolLength float64, bits string) (pd PreambleDetector) { // Plan forward and reverse transforms. pd.forward = fftw.NewHCDFT1D(n, nil, nil, fftw.Forward, fftw.InPlace, fftw.Measure) pd.Real = pd.forward.Real pd.Complex = pd.forward.Complex pd.backward = fftw.NewHCDFT1D(n, pd.Real, pd.Complex, fftw.Backward, fftw.PreAlloc, fftw.Measure) // Zero out input array. for i := range pd.Real { pd.Real[i] = 0 } // Generate the preamble basis function. for idx, bit := range bits { // Must account for rounding error. sIdx := idx << 1 lower := intRound(float64(sIdx) * symbolLength) upper := intRound(float64(sIdx+1) * symbolLength) for i := 0; i < upper-lower; i++ { if bit == '1' { pd.Real[lower+i] = 1.0 pd.Real[upper+i] = -1.0 } else { pd.Real[lower+i] = -1.0 pd.Real[upper+i] = 1.0 } } } // Transform the preamble basis function. pd.forward.Execute() // Create the preamble template and store conjugated DFT result. pd.template = make([]complex128, len(pd.Complex)) copy(pd.template, pd.Complex) for i := range pd.template { pd.template[i] = cmplx.Conj(pd.template[i]) } return }
func (f FFTW) XCorr(x1, x2 []float64) []float64 { var v1, v2, temp []complex128 var rs []float64 v1 = f.foward.ExecuteNewArray(x2) v2 = f.foward.ExecuteNewArray(x1) for i := 0; i < len(v1); i++ { v := v1[i] * cmplx.Conj(v2[i]) temp = append(temp, v) } rs = f.backward.ExecuteNewArray(temp) totl := len(f.backward.Real) res := []float64{} for i := 0; i < len(x1); i++ { res = append(res, rs[i]/float64(totl)) } return res }
func (k *CQKernel) ProcessInverse(cv []complex128) []complex128 { // matrix multiply by conjugate transpose of m_kernel. This is // actually the original kernel as calculated, we just stored the // conjugate-transpose of the kernel because we expect to be doing // more forward transforms than inverse ones. if len(k.kernel.data) == 0 { panic("Whoops - return empty array? is this even possible?") } ncols := k.Properties.binsPerOctave * k.Properties.atomsPerFrame nrows := k.Properties.fftSize rv := make([]complex128, nrows, nrows) for j := 0; j < ncols; j++ { i0 := k.kernel.origin[j] i1 := i0 + len(k.kernel.data[j]) for i := i0; i < i1; i++ { rv[i] += cv[j] * cmplx.Conj(k.kernel.data[j][i-i0]) } } return rv }
func (cqi *CQInverse) processOctaveColumn(octave int, column []complex128) { // 3. For each taller column, take the product with the inverse CQ // kernel (which is the conjugate of the forward kernel) and // perform an inverse FFT bpo := cqi.kernel.Properties.binsPerOctave apf := cqi.kernel.Properties.atomsPerFrame fftSize := cqi.kernel.Properties.fftSize if len(column) != bpo*apf { fmt.Printf("Error: column in octave %d has size %d, required = %d * %d = %d\n", octave, len(column), bpo, apf, bpo*apf) panic("Invalid argument to inverse processOctaveColumn") } transformed := cqi.kernel.ProcessInverse(column) // For inverse real transforms, force symmetric conjugate representation first. for i := fftSize/2 + 1; i < fftSize; i++ { transformed[i] = cmplx.Conj(transformed[fftSize-i]) } inverse := fft.IFFT(transformed) cqi.overlapAddAndResample(octave, realParts(inverse)) }