Как умножать комплексные матрицы Golang gonum/mat

У меня есть:

    dataA := []complex128{
        1 + 2i, 3 + 4i,
        5 + 6i, 7 + 8i,
    }
    A := mat.NewCDense(2, 2, dataA)
    dataB := []complex128{
        9 + 10i, 11 + 12i,
        13 + 14i, 15 + 16i,
    }
    B := mat.NewCDense(2, 2, dataB)

    var C mat.CDense

    C.Mul(A, B)

это не работает

type mat.CDense has no field or method Mul)

как умножать комплексные матрицы Golang gonum/mat

🤔 А знаете ли вы, что...
Go обладает мощным статическим анализатором кода.


2
50
2

Ответы:

Умножение сложных матриц не реализовано в gonum. Идет закрытый пиар, с реализацией Mul на CMatrix. Пиар был закрыт по причине «потому что [пиар] устарел. Мы все еще заинтересованы в пожертвованиях»

Реализация из пиара от notmgsk:

func (m *CDense) Mul(a, b CMatrix) {
    ar, ac := a.Dims()
    br, bc := b.Dims()

    if ac != br {
        panic(ErrShape)
    }

    aU, aTrans, aConj := untransposeCmplx(a)
    bU, bTrans, bConj := untransposeCmplx(b)
    m.reuseAsNonZeroed(ar, bc)
    var restore func()
    if aTrans != aConj && m == aU {
        m, restore = m.isolatedWorkspace(aU)
        defer restore()
    } else if bTrans != bConj && m == bU {
        m, restore = m.isolatedWorkspace(bU)
        defer restore()
    }
    aT := blas.NoTrans
    if aTrans {
        aT = blas.Trans
    } else if aConj {
        aT = blas.ConjTrans
    }
    bT := blas.NoTrans
    if bTrans != bConj {
        bT = blas.Trans
    } else if bConj {
        bT = blas.ConjTrans
    }

    if aU, ok := aU.(*CDense); ok {
        switch bU := bU.(type) {
        case *CDense:
            if restore == nil {
                m.checkOverlap(bU.mat)
            }
            cblas128.Gemm(aT, bT, 1, aU.mat, bU.mat, 0, m.mat)
            return
        }
    }

    m.checkOverlapMatrix(aU)
    m.checkOverlapMatrix(bU)
    row := getZs(ac, false)
    defer putZs(row)
    for r := 0; r < ar; r++ {
        for i := range row {
            row[i] = a.At(r, i)
        }
        for c := 0; c < bc; c++ {
            var v complex128
            for i, e := range row {
                v += e * b.At(i, c)
            }
            m.mat.Data[r*m.mat.Stride+c] = v
        }
    }
 }

Решено

Я смог умножить комплексные матрицы следующим образом:

package main

import (
     "fmt"
     "gonum.org/v1/gonum/blas"
     "gonum.org/v1/gonum/blas/cblas64"
)

func main() {
     a := cblas64.General{
         Rows:   2,
         Cols:   2,
         Stride: 2,
         Data:   []complex64{1 + 2i, 3 + 4i, 5 + 6i, 7 + 8i},
     }

     b := cblas64.General{
         Rows:   2,
         Cols:   1,
         Stride: 1,
         Data:   []complex64{9 + 10i, 11 + 12i},
     }

     c := cblas64.General{
         Rows:   2,
         Cols:   1,
         Stride: 1,
         Data:   make([]complex64, 2),
     }


     cblas64.Gemm(blas.NoTrans, blas.NoTrans, 1, a, b, 0, c)

     for i := 0; i < c.Rows; i++ {
         fmt.Printf("%v\n", c.Data[i])
     }

}