コンテンツにスキップ

Go/complex64

出典: フリー教科書『ウィキブックス(Wikibooks)』
< Go

Goのcomplex64について

[編集]

Goにおける complex64 は、複素数を表す事前宣言された型で、実部と虚部に float32 を使用します。メモリ効率を優先する用途や、リアルタイム性が求められる信号処理・グラフィック処理などに適しています。精度よりも速度やメモリ帯域が重視される場面で活躍します。

基本情報

[編集]
  • complex64 は32ビット浮動小数点数×2(実部・虚部)で構成される複素数型(合計64ビット = 8バイト)
  • 実部・虚部ともに IEEE 754 準拠の float32
  • 精度: 実部・虚部それぞれ約6〜9桁の有効数字
  • メモリ表現: 実部32ビット + 虚部32ビット
  • グラフィック、信号処理、組み込み、モバイル、GPU処理向け

他のキーワードとの組み合わせ

[編集]

変数宣言との組み合わせ

[編集]
var z complex64 = complex(3, 4)     // 実部3, 虚部4(float32リテラル)
value := complex64(1 + 2i)         // 明示的な型変換
zero := complex(0, 0)              // デフォルト型は complex128

定数定義との組み合わせ

[編集]
const I complex64 = 1i                    // 虚数単位(型推論)
const UNIT complex64 = 1 + 0i             // 実数1の複素数
const PURE_IMAG complex64 = 0 + 3.5i      // 純虚数
const ROTATE90 complex64 = 0 + 1i         // 90度回転

関数パラメータと戻り値

[編集]
func Conj(z complex64) complex64 {
    return complex(real(z), -imag(z))
}

func Mag(z complex64) float32 {
    return float32(math.Hypot(float64(real(z)), float64(imag(z))))
}

func Phase(z complex64) float32 {
    return float32(math.Atan2(float64(imag(z)), float64(real(z))))
}

型変換

[編集]
var z complex64 = complex(1.5, -2.3)
f := real(z)              // float32
g := imag(z)              // float32

z2 := complex64(1 + 2i)   // complex128 → complex64
z3 := complex(float32(3.2), float32(1.7)) // 明示的なfloat32指定

配列とスライス

[編集]
signals := []complex64{
    1 + 0i, 0 + 1i, -1 + 0i, 0 - 1i,
}

zeros := make([]complex64, 128) // 初期化されたゼロ複素数スライス

マップ

[編集]
filters := map[string]complex64{
    "lowpass":  0.8 + 0.1i,
    "highpass": 0.3 - 0.5i,
}

resonance := map[float32]complex64{
    440.0: 0.9 + 0.2i,
    880.0: 0.4 + 0.6i,
}

構造体のフィールド

[編集]
type ComplexSample struct {
    Time  float32
    Value complex64
}

type FFTResult struct {
    Frequency float32
    Amplitude complex64
}

type Polar struct {
    R     float32
    Theta float32
}

func RectToPolar(z complex64) Polar {
    return Polar{
        R:     float32(math.Hypot(float64(real(z)), float64(imag(z)))),
        Theta: float32(math.Atan2(float64(imag(z)), float64(real(z)))),
    }
}

スライスとバイナリ処理

[編集]
import (
    "encoding/binary"
    "math"
    "bytes"
)

func Complex64ToBytes(c complex64) []byte {
    buf := new(bytes.Buffer)
    binary.Write(buf, binary.LittleEndian, math.Float32bits(real(c)))
    binary.Write(buf, binary.LittleEndian, math.Float32bits(imag(c)))
    return buf.Bytes()
}

func BytesToComplex64(b []byte) complex64 {
    r := math.Float32frombits(binary.LittleEndian.Uint32(b[0:4]))
    i := math.Float32frombits(binary.LittleEndian.Uint32(b[4:8]))
    return complex(r, i)
}

一般的なユースケース

[編集]
  1. リアルタイム信号処理(低精度で高速)
    func Normalize(samples []complex64) {
        for i, s := range samples {
            mag := float32(math.Hypot(float64(real(s)), float64(imag(s))))
            if mag != 0 {
                samples[i] /= complex(mag, 0)
            }
        }
    }
    
  2. GPU用データ構造として利用(メモリ効率重視)
    type Vertex struct {
        Pos complex64
        Color [4]uint8
    }
    
  3. I/Q信号処理や無線通信のベースバンド解析
    type IQSample struct {
        I float32
        Q float32
    }
    
    func ToComplex(s IQSample) complex64 {
        return complex(s.I, s.Q)
    }
    

complex64 型は、メモリ使用量と処理速度を優先する場面、特に信号処理、グラフィックス、組み込みシステム、リアルタイムアプリケーションなどで有用です。ただし、精度には制限があるため、必要に応じて complex128 との使い分けが求められます。演算誤差や型変換の影響を理解したうえで、適切に運用することが重要です。