package main import ( "fmt" "math" "math/rand" "time" ) type Complex64 struct { Real float32 Imag float32 } type StateVector struct { data []Complex64 numQubits int } func NewStateVector(n int) *StateVector { size := 1 << n data := make([]Complex64, size) data[0] = Complex64{Real: 1.0, Imag: 0.0} return &StateVector{data: data, numQubits: n} } func (sv *StateVector) Apply1Qubit(q int, u [2][2]Complex64) { n := sv.numQubits block := 1 << (q + 1) stride := 1 << q for base := 0; base < (1 << n); base += block { for offset := 0; offset < stride; offset++ { i0 := base + offset i1 := i0 + stride a := sv.data[i0] b := sv.data[i1] sv.data[i0] = Complex64{ Real: u[0][0].Real*a.Real - u[0][0].Imag*a.Imag + u[0][1].Real*b.Real - u[0][1].Imag*b.Imag, Imag: u[0][0].Real*a.Imag + u[0][0].Imag*a.Real + u[0][1].Real*b.Imag + u[0][1].Imag*b.Real, } sv.data[i1] = Complex64{ Real: u[1][0].Real*a.Real - u[1][0].Imag*a.Imag + u[1][1].Real*b.Real - u[1][1].Imag*b.Imag, Imag: u[1][0].Real*a.Imag + u[1][0].Imag*a.Real + u[1][1].Real*b.Imag + u[1][1].Imag*b.Real, } } } } func (sv *StateVector) Apply2Qubit(q1, q2 int, u [4][4]Complex64) { n := sv.numQubits for i := 0; i < (1 << n); i++ { b1 := (i >> q1) & 1 b2 := (i >> q2) & 1 idx := b1*2 + b2 if idx != 0 { continue } i00 := i i01 := i | (1 << q2) i10 := i | (1 << q1) i11 := i | (1 << q1) | (1 << q2) indices := [4]int{i00, i01, i10, i11} var vals [4]Complex64 for k := 0; k < 4; k++ { vals[k] = sv.data[indices[k]] } for row := 0; row < 4; row++ { var sum Complex64 for col := 0; col < 4; col++ { a := u[row][col] b := vals[col] sum.Real += a.Real*b.Real - a.Imag*b.Imag sum.Imag += a.Real*b.Imag + a.Imag*b.Real } sv.data[indices[row]] = sum } } } func (sv *StateVector) Copy() *StateVector { newData := make([]Complex64, len(sv.data)) copy(newData, sv.data) return &StateVector{data: newData, numQubits: sv.numQubits} } func (sv *StateVector) InnerProduct(other *StateVector) Complex64 { var sum Complex64 for i := range sv.data { a := sv.data[i] b := other.data[i] sum.Real += a.Real*b.Real + a.Imag*b.Imag sum.Imag += a.Real*b.Imag - a.Imag*b.Real } return sum } func RZGate(theta float64) [2][2]Complex64 { c := float32(math.Cos(theta / 2)) s := float32(math.Sin(theta / 2)) return [2][2]Complex64{ {{Real: c, Imag: -s}, {Real: 0, Imag: 0}}, {{Real: 0, Imag: 0}, {Real: c, Imag: s}}, } } func RYGate(theta float64) [2][2]Complex64 { c := float32(math.Cos(theta / 2)) s := float32(math.Sin(theta / 2)) return [2][2]Complex64{ {{Real: c, Imag: 0}, {Real: -s, Imag: 0}}, {{Real: s, Imag: 0}, {Real: c, Imag: 0}}, } } func CZGate() [4][4]Complex64 { return [4][4]Complex64{ {{Real: 1}, {}, {}, {}}, {{}, {Real: 1}, {}, {}}, {{}, {}, {Real: 1}, {}}, {{}, {}, {}, {Real: -1}}, } } type QuantumKernelSVM struct { NQubits int NLayers int Shots int EntGraph [][2]int C float64 Params [][]float64 } func NewQuantumKernelSVM(nQubits, nLayers, shots int) *QuantumKernelSVM { entGraph := make([][2]int, nQubits-1) for i := 0; i < nQubits-1; i++ { entGraph[i] = [2]int{i, i + 1} } params := make([][]float64, nLayers) for l := 0; l < nLayers; l++ { params[l] = make([]float64, 3*nQubits) for p := 0; p < 3*nQubits; p++ { params[l][p] = 1.0 + rand.Float64()*0.2 - 0.1 } } return &QuantumKernelSVM{ NQubits: nQubits, NLayers: nLayers, Shots: shots, EntGraph: entGraph, C: 1.0, Params: params, } } func (svm *QuantumKernelSVM) ApplyFeatureMap(sv *StateVector, features []float64) { for layer := 0; layer < svm.NLayers; layer++ { for q := 0; q < svm.NQubits; q++ { x := features[q%len(features)] tz1 := svm.Params[layer][3*q] ty := svm.Params[layer][3*q+1] tz2 := svm.Params[layer][3*q+2] sv.Apply1Qubit(q, RZGate(2*x*tz1)) sv.Apply1Qubit(q, RYGate(2*x*ty)) sv.Apply1Qubit(q, RZGate(2*x*tz2)) } for _, edge := range svm.EntGraph { sv.Apply2Qubit(edge[0], edge[1], CZGate()) } } } func (svm *QuantumKernelSVM) KernelExact(featuresA, featuresB []float64) float64 { svA := NewStateVector(svm.NQubits) svm.ApplyFeatureMap(svA, featuresA) svB := NewStateVector(svm.NQubits) svm.ApplyFeatureMap(svB, featuresB) ip := svA.InnerProduct(svB) return float64(ip.Real*ip.Real + ip.Imag*ip.Imag) } func (svm *QuantumKernelSVM) KernelShots(featuresA, featuresB []float64) float64 { exact := svm.KernelExact(featuresA, featuresB) p0 := (1.0 + exact) / 2.0 countZero := 0 for s := 0; s < svm.Shots; s++ { if rand.Float64() < p0 { countZero++ } } return 2.0*float64(countZero)/float64(svm.Shots) - 1.0 } func (svm *QuantumKernelSVM) ComputeKernelMatrix(dataset [][]float64) [][]float64 { n := len(dataset) K := make([][]float64, n) for i := range K { K[i] = make([]float64, n) } for i := 0; i < n; i++ { for j := i; j < n; j++ { kij := svm.KernelShots(dataset[i], dataset[j]) K[i][j] = kij K[j][i] = kij } } return K } func (svm *QuantumKernelSVM) SolveDual(K [][]float64, labels []float64) ([]float64, float64) { n := len(labels) alpha := make([]float64, n) b := 0.0 for iter := 0; iter < 1000; iter++ { maxV := 0.0 for i := 0; i < n; i++ { grad := 1.0 for j := 0; j < n; j++ { grad -= alpha[j] * labels[j] * K[i][j] * labels[i] } v := math.Abs(grad) if v > maxV { maxV = v } alpha[i] = math.Max(0, math.Min(svm.C, alpha[i]+0.01*labels[i]*grad)) } if maxV < 1e-4 { break } } svIndices := []int{} for i := 0; i < n; i++ { if alpha[i] > 1e-5 && alpha[i] < svm.C-1e-5 { svIndices = append(svIndices, i) } } if len(svIndices) > 0 { bSum := 0.0 for _, k := range svIndices { sum := 0.0 for j := 0; j < n; j++ { sum += alpha[j] * labels[j] * K[k][j] } bSum += labels[k] - sum } b = bSum / float64(len(svIndices)) } return alpha, b } func main() { rand.Seed(time.Now().UnixNano()) fmt.Println("============================================================") fmt.Println("QUANTUM KERNEL SVM — 5 Qubit Hello World (Go Simulator)") fmt.Println("State Vector Engine | Shot-Based SWAP Test | SMO Solver") fmt.Println("============================================================") fmt.Println() nQubits := 5 nLayers := 2 shots := 1000 svm := NewQuantumKernelSVM(nQubits, nLayers, shots) fmt.Printf("Qubits: %d | Layers: %d | Shots: %d\n", nQubits, nLayers, shots) fmt.Printf("Hilbert space dim: 2^%d = %d\n", nQubits, 1< 1e-5 { svCount++ } } fmt.Printf("Support vectors: %d / %d\n", svCount, len(labels)) fmt.Printf("Bias: %.4f\n\n", bias) fmt.Println("Predictions:") correct := 0 for i := 0; i < len(dataset); i++ { decision := bias for j := 0; j < len(dataset); j++ { decision += alpha[j] * labels[j] * K[j][i] } pred := 1.0 if decision < 0 { pred = -1.0 } match := "OK" if pred != labels[i] { match = "MISS" } else { correct++ } fmt.Printf(" x[%d] -> decision=%.4f, pred=%+.0f, true=%+.0f [%s]\n", i, decision, pred, labels[i], match) } fmt.Printf("\nAccuracy: %d / %d = %.1f%%\n", correct, len(labels), 100*float64(correct)/float64(len(labels))) fmt.Println() fmt.Println("------------------------------------------------------------") fmt.Println("Shot noise analysis (kernel[0,1]):") estimates := make([]float64, 20) for i := range estimates { estimates[i] = svm.KernelShots(dataset[0], dataset[1]) } mean := 0.0 for _, e := range estimates { mean += e } mean /= float64(len(estimates)) variance := 0.0 for _, e := range estimates { variance += (e - mean) * (e - mean) } variance /= float64(len(estimates)) exact := svm.KernelExact(dataset[0], dataset[1]) fmt.Printf(" Mean: %.6f\n", mean) fmt.Printf(" Std: %.6f\n", math.Sqrt(variance)) fmt.Printf(" Exact: %.6f\n", exact) fmt.Println() fmt.Println("============================================================") fmt.Println("HELLO WORLD COMPLETE — 5 qubit quantum kernel executed") fmt.Println("============================================================") }