Download quantum-piper/bindings/zig/bob_quantum.zig from Snapkitty/bob-ide: direct link, hf CLI and curl.
- Browser
- Download file 15.7 kB
-
https://huggingface.co/Snapkitty/bob-ide/resolve/main/quantum-piper/bindings/zig/bob_quantum.zig
- Command line
-
hf download hf://Snapkitty/bob-ide/quantum-piper/bindings/zig/bob_quantum.zig
-
curl -L -o bob_quantum.zig https://huggingface.co/Snapkitty/bob-ide/resolve/main/quantum-piper/bindings/zig/bob_quantum.zig
15.7 kB
| // BOB Quantum Civilization Engine - Zig Bindings | |
| // Systems-level quantum simulation with memory safety | |
| // High-performance FFI to C library with zero-copy operations | |
| const std = @import("std"); | |
| const c = @cImport({ | |
| @cInclude("bob_quantum.h"); | |
| }); | |
| /// Error type for quantum operations | |
| pub const QuantumError = error{ | |
| MemoryAllocationFailed, | |
| InvalidParameter, | |
| InternalError, | |
| NotImplemented, | |
| FileIOError, | |
| UnknownError, | |
| }; | |
| /// Error code mapping | |
| fn errorCodeToError(code: i32) QuantumError!void { | |
| switch (code) { | |
| 0 => return, // BOB_ERROR_NONE | |
| 1 => return QuantumError.MemoryAllocationFailed, | |
| 2 => return QuantumError.InvalidParameter, | |
| 3 => return QuantumError.InternalError, | |
| 4 => return QuantumError.NotImplemented, | |
| 5 => return QuantumError.FileIOError, | |
| else => return QuantumError.UnknownError, | |
| } | |
| } | |
| /// ========================================================================= | |
| /// RNG Subsystem | |
| /// ========================================================================= | |
| pub const RNG = struct { | |
| handle: ?*c.bob_rng_handle_t, | |
| allocator: std.mem.Allocator, | |
| pub fn create(allocator: std.mem.Allocator, seed: u64) QuantumError!RNG { | |
| var rng_ptr: ?*c.bob_rng_handle_t = null; | |
| const err = c.bob_rng_create(&rng_ptr); | |
| try errorCodeToError(err); | |
| if (err == 0 and seed > 0) { | |
| const seed_err = c.bob_rng_seed(rng_ptr, seed); | |
| try errorCodeToError(seed_err); | |
| } | |
| return RNG{ | |
| .handle = rng_ptr, | |
| .allocator = allocator, | |
| }; | |
| } | |
| pub fn destroy(self: *RNG) QuantumError!void { | |
| if (self.handle != null) { | |
| const err = c.bob_rng_destroy(self.handle); | |
| try errorCodeToError(err); | |
| } | |
| } | |
| pub fn seed(self: *RNG, new_seed: u64) QuantumError!void { | |
| const err = c.bob_rng_seed(self.handle, new_seed); | |
| try errorCodeToError(err); | |
| } | |
| pub fn uniform(self: *RNG) QuantumError!f64 { | |
| var value: f64 = 0.0; | |
| const err = c.bob_rng_uniform(self.handle, &value); | |
| try errorCodeToError(err); | |
| return value; | |
| } | |
| pub fn normal(self: *RNG) QuantumError!f64 { | |
| var value: f64 = 0.0; | |
| const err = c.bob_rng_normal(self.handle, &value); | |
| try errorCodeToError(err); | |
| return value; | |
| } | |
| pub fn integer(self: *RNG, min: i64, max: i64) QuantumError!i64 { | |
| var value: i64 = 0; | |
| const err = c.bob_rng_integer(self.handle, min, max, &value); | |
| try errorCodeToError(err); | |
| return value; | |
| } | |
| pub fn uniformBatch(self: *RNG, allocator: std.mem.Allocator, count: usize) QuantumError![]f64 { | |
| var values = try allocator.alloc(f64, count); | |
| errdefer allocator.free(values); | |
| for (values) |*val| { | |
| val.* = try self.uniform(); | |
| } | |
| return values; | |
| } | |
| pub fn normalBatch(self: *RNG, allocator: std.mem.Allocator, count: usize) QuantumError![]f64 { | |
| var values = try allocator.alloc(f64, count); | |
| errdefer allocator.free(values); | |
| for (values) |*val| { | |
| val.* = try self.normal(); | |
| } | |
| return values; | |
| } | |
| }; | |
| /// ========================================================================= | |
| /// Lattice Subsystem | |
| /// ========================================================================= | |
| pub const Lattice = struct { | |
| handle: ?*c.bob_lattice_handle_t, | |
| nx: i32, | |
| ny: i32, | |
| nz: i32, | |
| coupling: f64, | |
| allocator: std.mem.Allocator, | |
| pub fn create( | |
| allocator: std.mem.Allocator, | |
| nx: i32, | |
| ny: i32, | |
| nz: i32, | |
| coupling: f64, | |
| seed: u64, | |
| ) QuantumError!Lattice { | |
| var lat_ptr: ?*c.bob_lattice_handle_t = null; | |
| const err = c.bob_lattice_create(nx, ny, nz, coupling, seed, &lat_ptr); | |
| try errorCodeToError(err); | |
| return Lattice{ | |
| .handle = lat_ptr, | |
| .nx = nx, | |
| .ny = ny, | |
| .nz = nz, | |
| .coupling = coupling, | |
| .allocator = allocator, | |
| }; | |
| } | |
| pub fn destroy(self: *Lattice) QuantumError!void { | |
| if (self.handle != null) { | |
| const err = c.bob_lattice_destroy(self.handle); | |
| try errorCodeToError(err); | |
| } | |
| } | |
| pub fn evolve(self: *Lattice, steps: i32) QuantumError!f64 { | |
| var energy: f64 = 0.0; | |
| const err = c.bob_lattice_evolve(self.handle, steps, &energy); | |
| try errorCodeToError(err); | |
| return energy; | |
| } | |
| pub fn energy(self: *Lattice) QuantumError!f64 { | |
| var value: f64 = 0.0; | |
| const err = c.bob_lattice_energy(self.handle, &value); | |
| try errorCodeToError(err); | |
| return value; | |
| } | |
| pub fn entropy(self: *Lattice) QuantumError!f64 { | |
| var value: f64 = 0.0; | |
| const err = c.bob_lattice_entropy(self.handle, &value); | |
| try errorCodeToError(err); | |
| return value; | |
| } | |
| pub fn correlation(self: *Lattice, distance: i32) QuantumError!f64 { | |
| var value: f64 = 0.0; | |
| const err = c.bob_lattice_correlation(self.handle, distance, &value); | |
| try errorCodeToError(err); | |
| return value; | |
| } | |
| pub fn magnetization( | |
| self: *Lattice, | |
| x: i32, | |
| y: i32, | |
| z: i32, | |
| ) QuantumError!f64 { | |
| var value: f64 = 0.0; | |
| const err = c.bob_lattice_magnetization(self.handle, x, y, z, &value); | |
| try errorCodeToError(err); | |
| return value; | |
| } | |
| pub fn applyField( | |
| self: *Lattice, | |
| min_x: i32, | |
| min_y: i32, | |
| min_z: i32, | |
| max_x: i32, | |
| max_y: i32, | |
| max_z: i32, | |
| strength: f64, | |
| ) QuantumError!void { | |
| const err = c.bob_lattice_apply_field( | |
| self.handle, | |
| min_x, | |
| min_y, | |
| min_z, | |
| max_x, | |
| max_y, | |
| max_z, | |
| strength, | |
| ); | |
| try errorCodeToError(err); | |
| } | |
| }; | |
| /// ========================================================================= | |
| /// Quantum State Subsystem | |
| /// ========================================================================= | |
| pub const InitialState = enum(i32) { | |
| zero = 0, | |
| plus = 1, | |
| random = 2, | |
| }; | |
| pub const QuantumState = struct { | |
| handle: ?*c.bob_state_handle_t, | |
| n_qubits: i32, | |
| allocator: std.mem.Allocator, | |
| pub fn create( | |
| allocator: std.mem.Allocator, | |
| n_qubits: i32, | |
| initial: InitialState, | |
| ) QuantumError!QuantumState { | |
| var state_ptr: ?*c.bob_state_handle_t = null; | |
| const err = c.bob_state_create(n_qubits, @enumToInt(initial), &state_ptr); | |
| try errorCodeToError(err); | |
| return QuantumState{ | |
| .handle = state_ptr, | |
| .n_qubits = n_qubits, | |
| .allocator = allocator, | |
| }; | |
| } | |
| pub fn destroy(self: *QuantumState) QuantumError!void { | |
| if (self.handle != null) { | |
| const err = c.bob_state_destroy(self.handle); | |
| try errorCodeToError(err); | |
| } | |
| } | |
| pub fn measure(self: *QuantumState, qubit: i32) QuantumError!struct { outcome: i32, prob: f64 } { | |
| var outcome: i32 = 0; | |
| var prob: f64 = 0.0; | |
| const err = c.bob_state_measure(self.handle, qubit, &outcome, &prob); | |
| try errorCodeToError(err); | |
| return .{ .outcome = outcome, .prob = prob }; | |
| } | |
| pub fn applyGate( | |
| self: *QuantumState, | |
| gate_type: i32, | |
| qubit: i32, | |
| params: ?[]const f64, | |
| ) QuantumError!void { | |
| const params_ptr = if (params) |p| @ptrCast(?[*]const f64, p.ptr) else null; | |
| const n_params = if (params) |p| @intCast(i32, p.len) else 0; | |
| const err = c.bob_state_apply_gate( | |
| self.handle, | |
| gate_type, | |
| qubit, | |
| params_ptr, | |
| n_params, | |
| ); | |
| try errorCodeToError(err); | |
| } | |
| pub fn applyControlledGate( | |
| self: *QuantumState, | |
| gate_type: i32, | |
| control: i32, | |
| target: i32, | |
| params: ?[]const f64, | |
| ) QuantumError!void { | |
| const params_ptr = if (params) |p| @ptrCast(?[*]const f64, p.ptr) else null; | |
| const n_params = if (params) |p| @intCast(i32, p.len) else 0; | |
| const err = c.bob_state_apply_controlled( | |
| self.handle, | |
| gate_type, | |
| control, | |
| target, | |
| params_ptr, | |
| n_params, | |
| ); | |
| try errorCodeToError(err); | |
| } | |
| pub fn normalize(self: *QuantumState) QuantumError!void { | |
| const err = c.bob_state_normalize(self.handle); | |
| try errorCodeToError(err); | |
| } | |
| pub fn expectation(self: *QuantumState, operator: [*:0]const u8) QuantumError!f64 { | |
| var value: f64 = 0.0; | |
| const err = c.bob_state_expectation(self.handle, operator, &value); | |
| try errorCodeToError(err); | |
| return value; | |
| } | |
| pub fn amplitudes(self: *QuantumState, allocator: std.mem.Allocator) QuantumError![]struct { re: f64, im: f64 } { | |
| var n: i32 = 0; | |
| var amps_ptr: ?*anyopaque = null; | |
| const err = c.bob_state_amplitudes(self.handle, &n, &s_ptr); | |
| try errorCodeToError(err); | |
| if (n <= 0) return allocator.alloc(struct { re: f64, im: f64 }, 0); | |
| var result = try allocator.alloc(struct { re: f64, im: f64 }, @intCast(usize, n)); | |
| errdefer allocator.free(result); | |
| const doubles = @ptrCast([*]f64, @alignCast(@alignOf(f64), amps_ptr)); | |
| for (result) |*amp, i| { | |
| amp.re = doubles[i * 2]; | |
| amp.im = doubles[i * 2 + 1]; | |
| } | |
| return result; | |
| } | |
| pub fn clone(self: *QuantumState) QuantumError!QuantumState { | |
| var cloned_ptr: ?*c.bob_state_handle_t = null; | |
| const err = c.bob_state_clone(self.handle, &cloned_ptr); | |
| try errorCodeToError(err); | |
| return QuantumState{ | |
| .handle = cloned_ptr, | |
| .n_qubits = self.n_qubits, | |
| .allocator = self.allocator, | |
| }; | |
| } | |
| pub fn fidelity(self: *QuantumState, other: *QuantumState) QuantumError!f64 { | |
| var value: f64 = 0.0; | |
| const err = c.bob_state_fidelity(self.handle, other.handle, &value); | |
| try errorCodeToError(err); | |
| return value; | |
| } | |
| }; | |
| /// ========================================================================= | |
| /// Hamiltonian Subsystem | |
| /// ========================================================================= | |
| pub const HamiltonianType = enum(i32) { | |
| sparse = 0, | |
| dense = 1, | |
| mpo = 2, | |
| }; | |
| pub const Hamiltonian = struct { | |
| handle: ?*c.bob_hamiltonian_handle_t, | |
| n_qubits: i32, | |
| allocator: std.mem.Allocator, | |
| pub fn create( | |
| allocator: std.mem.Allocator, | |
| n_qubits: i32, | |
| ham_type: HamiltonianType, | |
| ) QuantumError!Hamiltonian { | |
| var ham_ptr: ?*c.bob_hamiltonian_handle_t = null; | |
| const err = c.bob_hamiltonian_create(n_qubits, @enumToInt(ham_type), &ham_ptr); | |
| try errorCodeToError(err); | |
| return Hamiltonian{ | |
| .handle = ham_ptr, | |
| .n_qubits = n_qubits, | |
| .allocator = allocator, | |
| }; | |
| } | |
| pub fn destroy(self: *Hamiltonian) QuantumError!void { | |
| if (self.handle != null) { | |
| const err = c.bob_hamiltonian_destroy(self.handle); | |
| try errorCodeToError(err); | |
| } | |
| } | |
| pub fn addTerm( | |
| self: *Hamiltonian, | |
| coeff_re: f64, | |
| coeff_im: f64, | |
| qubits: []const i32, | |
| ) QuantumError!void { | |
| const err = c.bob_hamiltonian_add_term( | |
| self.handle, | |
| coeff_re, | |
| coeff_im, | |
| @ptrCast(?[*]const i32, qubits.ptr), | |
| @intCast(i32, qubits.len), | |
| ); | |
| try errorCodeToError(err); | |
| } | |
| pub fn expectation(self: *Hamiltonian, state: *QuantumState) QuantumError!struct { re: f64, im: f64 } { | |
| var exp_re: f64 = 0.0; | |
| var exp_im: f64 = 0.0; | |
| const err = c.bob_hamiltonian_expectation(self.handle, state.handle, &exp_re, &exp_im); | |
| try errorCodeToError(err); | |
| return .{ .re = exp_re, .im = exp_im }; | |
| } | |
| pub fn eigenvalues(self: *Hamiltonian, allocator: std.mem.Allocator, n_vals: i32) QuantumError![]f64 { | |
| var vals_ptr: ?*f64 = null; | |
| const err = c.bob_hamiltonian_eigenvalues(self.handle, n_vals, @ptrCast(?*?*f64, &vals_ptr)); | |
| try errorCodeToError(err); | |
| if (n_vals <= 0) return allocator.alloc(f64, 0); | |
| var result = try allocator.alloc(f64, @intCast(usize, n_vals)); | |
| errdefer allocator.free(result); | |
| for (result) |*val, i| { | |
| val.* = vals_ptr.?[i]; | |
| } | |
| return result; | |
| } | |
| pub fn timeEvolve( | |
| self: *Hamiltonian, | |
| state: *QuantumState, | |
| time: f64, | |
| ) QuantumError!QuantumState { | |
| var evolved_ptr: ?*c.bob_state_handle_t = null; | |
| const err = c.bob_hamiltonian_time_evolve(self.handle, state.handle, time, &evolved_ptr); | |
| try errorCodeToError(err); | |
| return QuantumState{ | |
| .handle = evolved_ptr, | |
| .n_qubits = state.n_qubits, | |
| .allocator = state.allocator, | |
| }; | |
| } | |
| }; | |
| /// ========================================================================= | |
| /// Example Functions | |
| /// ========================================================================= | |
| pub fn example_simple_rng(allocator: std.mem.Allocator) !void { | |
| var rng = try RNG.create(allocator, 12345); | |
| defer _ = rng.destroy() catch {}; | |
| const u1 = try rng.uniform(); | |
| const n1 = try rng.normal(); | |
| const i1 = try rng.integer(0, 100); | |
| std.debug.print("Uniform: {}\n", .{u1}); | |
| std.debug.print("Normal: {}\n", .{n1}); | |
| std.debug.print("Integer: {}\n", .{i1}); | |
| } | |
| pub fn example_quantum_circuit(allocator: std.mem.Allocator) !void { | |
| var state = try QuantumState.create(allocator, 2, .zero); | |
| defer _ = state.destroy() catch {}; | |
| try state.applyGate(0, 0, null); // Hadamard on qubit 0 | |
| const result = try state.measure(0); | |
| std.debug.print("Measurement: {} with prob {}\n", .{ result.outcome, result.prob }); | |
| } | |
| pub fn example_lattice_evolution(allocator: std.mem.Allocator) !void { | |
| var lattice = try Lattice.create(allocator, 4, 4, 4, 1.0, 42); | |
| defer _ = lattice.destroy() catch {}; | |
| for (0..10) |i| { | |
| const energy = try lattice.energy(); | |
| const entropy = try lattice.entropy(); | |
| _ = try lattice.evolve(1); | |
| std.debug.print("Step {}: E={} S={}\n", .{ i, energy, entropy }); | |
| } | |
| } | |
| pub fn example_vqe_ansatz(allocator: std.mem.Allocator) !void { | |
| var ham = try Hamiltonian.create(allocator, 2, .sparse); | |
| defer _ = ham.destroy() catch {}; | |
| var state = try QuantumState.create(allocator, 2, .zero); | |
| defer _ = state.destroy() catch {}; | |
| const params1 = [_]f64{1.5}; | |
| const params2 = [_]f64{0.7}; | |
| try state.applyGate(7, 0, ¶ms1); // RY on qubit 0 | |
| try state.applyGate(8, 0, ¶ms2); // RZ on qubit 0 | |
| try ham.addTerm(1.0, 0.0, &[_]i32{0}); | |
| try ham.addTerm(1.0, 0.0, &[_]i32{1}); | |
| const exp = try ham.expectation(&state); | |
| std.debug.print("Expectation: {} + {}i\n", .{ exp.re, exp.im }); | |
| } | |