Download odin/bob_quantum.odin from Snapkitty/sov-kernel-monster: direct link, hf CLI and curl.
- Browser
- Download file 17.5 kB
-
https://huggingface.co/Snapkitty/sov-kernel-monster/resolve/main/odin/bob_quantum.odin
- Command line
-
hf download hf://Snapkitty/sov-kernel-monster/odin/bob_quantum.odin
-
curl -L -o bob_quantum.odin https://huggingface.co/Snapkitty/sov-kernel-monster/resolve/main/odin/bob_quantum.odin
17.5 kB
| package bob_quantum | |
| // BOB Quantum Civilization Engine - Odin Bindings | |
| // VR-optimized quantum simulation for game engines | |
| // High-performance lattice visualization and real-time evolution | |
| import "core:c" | |
| import "core:math" | |
| import "core:mem" | |
| import "core:slice" | |
| // ========================================================================= | |
| // Constants | |
| // ========================================================================= | |
| ERROR_NONE :: 0 | |
| ERROR_MEMORY_ALLOCATION_FAILED :: 1 | |
| ERROR_INVALID_PARAMETER :: 2 | |
| ERROR_INTERNAL_ERROR :: 3 | |
| ERROR_NOT_IMPLEMENTED :: 4 | |
| ERROR_FILE_IO_ERROR :: 5 | |
| ERROR_UNKNOWN_ERROR :: 6 | |
| // Gate type codes | |
| GATE_H :: 0 | |
| GATE_X :: 1 | |
| GATE_Y :: 2 | |
| GATE_Z :: 3 | |
| GATE_S :: 4 | |
| GATE_T :: 5 | |
| GATE_RX :: 6 | |
| GATE_RY :: 7 | |
| GATE_RZ :: 8 | |
| GATE_CX :: 9 | |
| GATE_CY :: 10 | |
| GATE_CZ :: 11 | |
| // Initial state codes | |
| INITIAL_ZERO :: 0 | |
| INITIAL_PLUS :: 1 | |
| INITIAL_RANDOM :: 2 | |
| // Hamiltonian type codes | |
| HAM_SPARSE :: 0 | |
| HAM_DENSE :: 1 | |
| HAM_MPO :: 2 | |
| // ========================================================================= | |
| // FFI Types | |
| // ========================================================================= | |
| RNG_Handle :: distinct rawptr | |
| Lattice_Handle :: distinct rawptr | |
| State_Handle :: distinct rawptr | |
| Hamiltonian_Handle :: distinct rawptr | |
| Quantum_Error :: enum { | |
| None, | |
| MemoryAllocationFailed, | |
| InvalidParameter, | |
| InternalError, | |
| NotImplemented, | |
| FileIOError, | |
| UnknownError, | |
| } | |
| // ========================================================================= | |
| // FFI Foreign Declarations | |
| // ========================================================================= | |
| @(default_calling_convention="c") | |
| foreign "libbob_quantum" { | |
| // RNG functions | |
| bob_rng_create :: proc(rng: ^RNG_Handle) -> c.int --- | |
| bob_rng_destroy :: proc(rng: RNG_Handle) -> c.int --- | |
| bob_rng_seed :: proc(rng: RNG_Handle, seed: c.uint64_t) -> c.int --- | |
| bob_rng_uniform :: proc(rng: RNG_Handle, value: ^f64) -> c.int --- | |
| bob_rng_normal :: proc(rng: RNG_Handle, value: ^f64) -> c.int --- | |
| bob_rng_integer :: proc(rng: RNG_Handle, min: c.int64_t, max: c.int64_t, value: ^c.int64_t) -> c.int --- | |
| // Lattice functions | |
| bob_lattice_create :: proc(nx: c.int, ny: c.int, nz: c.int, coupling: f64, seed: c.uint64_t, lat: ^Lattice_Handle) -> c.int --- | |
| bob_lattice_destroy :: proc(lat: Lattice_Handle) -> c.int --- | |
| bob_lattice_evolve :: proc(lat: Lattice_Handle, steps: c.int, energy: ^f64) -> c.int --- | |
| bob_lattice_energy :: proc(lat: Lattice_Handle, energy: ^f64) -> c.int --- | |
| bob_lattice_entropy :: proc(lat: Lattice_Handle, entropy: ^f64) -> c.int --- | |
| bob_lattice_correlation :: proc(lat: Lattice_Handle, distance: c.int, corr: ^f64) -> c.int --- | |
| bob_lattice_magnetization :: proc(lat: Lattice_Handle, x: c.int, y: c.int, z: c.int, mag: ^f64) -> c.int --- | |
| bob_lattice_apply_field :: proc(lat: Lattice_Handle, min_x: c.int, min_y: c.int, min_z: c.int, max_x: c.int, max_y: c.int, max_z: c.int, strength: f64) -> c.int --- | |
| // State functions | |
| bob_state_create :: proc(n_qubits: c.int, initial: c.int, state: ^State_Handle) -> c.int --- | |
| bob_state_destroy :: proc(state: State_Handle) -> c.int --- | |
| bob_state_measure :: proc(state: State_Handle, qubit: c.int, outcome: ^c.int, prob: ^f64) -> c.int --- | |
| bob_state_measure_multi :: proc(state: State_Handle, qubits: [^]c.int, n_qubits: c.int, outcomes: ^c.int, prob: ^f64) -> c.int --- | |
| bob_state_apply_gate :: proc(state: State_Handle, gate: c.int, qubit: c.int, params: [^]f64, n_params: c.int) -> c.int --- | |
| bob_state_apply_controlled :: proc(state: State_Handle, gate: c.int, control: c.int, target: c.int, params: [^]f64, n_params: c.int) -> c.int --- | |
| bob_state_normalize :: proc(state: State_Handle) -> c.int --- | |
| bob_state_expectation :: proc(state: State_Handle, operator: cstring, value: ^f64) -> c.int --- | |
| bob_state_amplitudes :: proc(state: State_Handle, n: ^c.int, amps: ^rawptr) -> c.int --- | |
| bob_state_clone :: proc(state: State_Handle, cloned: ^State_Handle) -> c.int --- | |
| bob_state_fidelity :: proc(state1: State_Handle, state2: State_Handle, fidelity: ^f64) -> c.int --- | |
| // Hamiltonian functions | |
| bob_hamiltonian_create :: proc(n_qubits: c.int, ham_type: c.int, ham: ^Hamiltonian_Handle) -> c.int --- | |
| bob_hamiltonian_destroy :: proc(ham: Hamiltonian_Handle) -> c.int --- | |
| bob_hamiltonian_add_term :: proc(ham: Hamiltonian_Handle, coeff_re: f64, coeff_im: f64, qubits: [^]c.int, n_qubits: c.int) -> c.int --- | |
| bob_hamiltonian_expectation :: proc(ham: Hamiltonian_Handle, state: State_Handle, exp_re: ^f64, exp_im: ^f64) -> c.int --- | |
| bob_hamiltonian_eigenvalues :: proc(ham: Hamiltonian_Handle, n_vals: c.int, vals: ^rawptr) -> c.int --- | |
| bob_hamiltonian_time_evolve :: proc(ham: Hamiltonian_Handle, state: State_Handle, time: f64, evolved: ^State_Handle) -> c.int --- | |
| } | |
| // ========================================================================= | |
| // Error Handling | |
| // ========================================================================= | |
| error_to_odin :: proc(code: c.int) -> Quantum_Error { | |
| switch code { | |
| case 0: return .None | |
| case 1: return .MemoryAllocationFailed | |
| case 2: return .InvalidParameter | |
| case 3: return .InternalError | |
| case 4: return .NotImplemented | |
| case 5: return .FileIOError | |
| case: return .UnknownError | |
| } | |
| } | |
| // ========================================================================= | |
| // RNG Context | |
| // ========================================================================= | |
| RNG :: struct { | |
| handle: RNG_Handle, | |
| } | |
| rng_create :: proc(seed: u64 = 42) -> (RNG, Quantum_Error) { | |
| handle: RNG_Handle | |
| err := bob_rng_create(&handle) | |
| if err != ERROR_NONE { | |
| return {}, error_to_odin(err) | |
| } | |
| if seed > 0 { | |
| seed_err := bob_rng_seed(handle, seed) | |
| if seed_err != ERROR_NONE { | |
| return {}, error_to_odin(seed_err) | |
| } | |
| } | |
| return {handle}, .None | |
| } | |
| rng_destroy :: proc(rng: ^RNG) -> Quantum_Error { | |
| if rng.handle != nil { | |
| err := bob_rng_destroy(rng.handle) | |
| if err != ERROR_NONE { | |
| return error_to_odin(err) | |
| } | |
| } | |
| return .None | |
| } | |
| rng_seed :: proc(rng: ^RNG, seed: u64) -> Quantum_Error { | |
| err := bob_rng_seed(rng.handle, seed) | |
| return error_to_odin(err) if err != ERROR_NONE else .None | |
| } | |
| rng_uniform :: proc(rng: ^RNG) -> (f64, Quantum_Error) { | |
| value: f64 | |
| err := bob_rng_uniform(rng.handle, &value) | |
| return value, error_to_odin(err) if err != ERROR_NONE else .None | |
| } | |
| rng_normal :: proc(rng: ^RNG) -> (f64, Quantum_Error) { | |
| value: f64 | |
| err := bob_rng_normal(rng.handle, &value) | |
| return value, error_to_odin(err) if err != ERROR_NONE else .None | |
| } | |
| rng_integer :: proc(rng: ^RNG, min: i64, max: i64) -> (i64, Quantum_Error) { | |
| value: c.int64_t | |
| err := bob_rng_integer(rng.handle, min, max, &value) | |
| return i64(value), error_to_odin(err) if err != ERROR_NONE else .None | |
| } | |
| rng_uniform_batch :: proc(rng: ^RNG, count: int, allocator := context.allocator) -> ([]f64, Quantum_Error) { | |
| values := make([]f64, count, allocator) | |
| for i in 0..<count { | |
| v, err := rng_uniform(rng) | |
| if err != .None { | |
| delete(values, allocator) | |
| return nil, err | |
| } | |
| values[i] = v | |
| } | |
| return values, .None | |
| } | |
| // ========================================================================= | |
| // Lattice Context | |
| // ========================================================================= | |
| Lattice :: struct { | |
| handle: Lattice_Handle, | |
| nx: int, | |
| ny: int, | |
| nz: int, | |
| coupling: f64, | |
| } | |
| lattice_create :: proc(nx: int, ny: int, nz: int, coupling: f64, seed: u64 = 42) -> (Lattice, Quantum_Error) { | |
| handle: Lattice_Handle | |
| err := bob_lattice_create(c.int(nx), c.int(ny), c.int(nz), coupling, seed, &handle) | |
| if err != ERROR_NONE { | |
| return {}, error_to_odin(err) | |
| } | |
| return {handle, nx, ny, nz, coupling}, .None | |
| } | |
| lattice_destroy :: proc(lat: ^Lattice) -> Quantum_Error { | |
| if lat.handle != nil { | |
| err := bob_lattice_destroy(lat.handle) | |
| if err != ERROR_NONE { | |
| return error_to_odin(err) | |
| } | |
| } | |
| return .None | |
| } | |
| lattice_evolve :: proc(lat: ^Lattice, steps: int) -> (f64, Quantum_Error) { | |
| energy: f64 | |
| err := bob_lattice_evolve(lat.handle, c.int(steps), &energy) | |
| return energy, error_to_odin(err) if err != ERROR_NONE else .None | |
| } | |
| lattice_energy :: proc(lat: ^Lattice) -> (f64, Quantum_Error) { | |
| energy: f64 | |
| err := bob_lattice_energy(lat.handle, &energy) | |
| return energy, error_to_odin(err) if err != ERROR_NONE else .None | |
| } | |
| lattice_entropy :: proc(lat: ^Lattice) -> (f64, Quantum_Error) { | |
| entropy: f64 | |
| err := bob_lattice_entropy(lat.handle, &entropy) | |
| return entropy, error_to_odin(err) if err != ERROR_NONE else .None | |
| } | |
| lattice_correlation :: proc(lat: ^Lattice, distance: int) -> (f64, Quantum_Error) { | |
| corr: f64 | |
| err := bob_lattice_correlation(lat.handle, c.int(distance), &corr) | |
| return corr, error_to_odin(err) if err != ERROR_NONE else .None | |
| } | |
| lattice_magnetization :: proc(lat: ^Lattice, x: int, y: int, z: int) -> (f64, Quantum_Error) { | |
| mag: f64 | |
| err := bob_lattice_magnetization(lat.handle, c.int(x), c.int(y), c.int(z), &mag) | |
| return mag, error_to_odin(err) if err != ERROR_NONE else .None | |
| } | |
| lattice_apply_field :: proc( | |
| lat: ^Lattice, | |
| min_x: int, min_y: int, min_z: int, | |
| max_x: int, max_y: int, max_z: int, | |
| strength: f64, | |
| ) -> Quantum_Error { | |
| err := bob_lattice_apply_field( | |
| lat.handle, | |
| c.int(min_x), c.int(min_y), c.int(min_z), | |
| c.int(max_x), c.int(max_y), c.int(max_z), | |
| strength, | |
| ) | |
| return error_to_odin(err) if err != ERROR_NONE else .None | |
| } | |
| // ========================================================================= | |
| // Quantum State Context | |
| // ========================================================================= | |
| Quantum_State :: struct { | |
| handle: State_Handle, | |
| n_qubits: int, | |
| } | |
| state_create :: proc(n_qubits: int, initial: int = INITIAL_ZERO) -> (Quantum_State, Quantum_Error) { | |
| handle: State_Handle | |
| err := bob_state_create(c.int(n_qubits), c.int(initial), &handle) | |
| if err != ERROR_NONE { | |
| return {}, error_to_odin(err) | |
| } | |
| return {handle, n_qubits}, .None | |
| } | |
| state_destroy :: proc(state: ^Quantum_State) -> Quantum_Error { | |
| if state.handle != nil { | |
| err := bob_state_destroy(state.handle) | |
| if err != ERROR_NONE { | |
| return error_to_odin(err) | |
| } | |
| } | |
| return .None | |
| } | |
| Measurement :: struct { | |
| outcome: int, | |
| probability: f64, | |
| } | |
| state_measure :: proc(state: ^Quantum_State, qubit: int) -> (Measurement, Quantum_Error) { | |
| outcome: c.int | |
| prob: f64 | |
| err := bob_state_measure(state.handle, c.int(qubit), &outcome, &prob) | |
| if err != ERROR_NONE { | |
| return {}, error_to_odin(err) | |
| } | |
| return {int(outcome), prob}, .None | |
| } | |
| state_apply_gate :: proc(state: ^Quantum_State, gate: int, qubit: int, params: []f64 = {}) -> Quantum_Error { | |
| params_ptr := raw_data(params) if len(params) > 0 else nil | |
| err := bob_state_apply_gate(state.handle, c.int(gate), c.int(qubit), params_ptr, c.int(len(params))) | |
| return error_to_odin(err) if err != ERROR_NONE else .None | |
| } | |
| state_apply_controlled :: proc(state: ^Quantum_State, gate: int, control: int, target: int, params: []f64 = {}) -> Quantum_Error { | |
| params_ptr := raw_data(params) if len(params) > 0 else nil | |
| err := bob_state_apply_controlled(state.handle, c.int(gate), c.int(control), c.int(target), params_ptr, c.int(len(params))) | |
| return error_to_odin(err) if err != ERROR_NONE else .None | |
| } | |
| state_normalize :: proc(state: ^Quantum_State) -> Quantum_Error { | |
| err := bob_state_normalize(state.handle) | |
| return error_to_odin(err) if err != ERROR_NONE else .None | |
| } | |
| state_expectation :: proc(state: ^Quantum_State, operator: cstring) -> (f64, Quantum_Error) { | |
| value: f64 | |
| err := bob_state_expectation(state.handle, operator, &value) | |
| return value, error_to_odin(err) if err != ERROR_NONE else .None | |
| } | |
| Amplitude :: struct { | |
| re: f64, | |
| im: f64, | |
| } | |
| state_amplitudes :: proc(state: ^Quantum_State, allocator := context.allocator) -> ([]Amplitude, Quantum_Error) { | |
| n: c.int | |
| amps_ptr: rawptr | |
| err := bob_state_amplitudes(state.handle, &n, &s_ptr) | |
| if err != ERROR_NONE { | |
| return nil, error_to_odin(err) | |
| } | |
| if n <= 0 { | |
| return make([]Amplitude, 0, allocator), .None | |
| } | |
| amps := make([]Amplitude, int(n), allocator) | |
| doubles := cast([^]f64)amps_ptr | |
| for i in 0..<int(n) { | |
| amps[i].re = doubles[i * 2] | |
| amps[i].im = doubles[i * 2 + 1] | |
| } | |
| return amps, .None | |
| } | |
| state_clone :: proc(state: ^Quantum_State) -> (Quantum_State, Quantum_Error) { | |
| handle: State_Handle | |
| err := bob_state_clone(state.handle, &handle) | |
| if err != ERROR_NONE { | |
| return {}, error_to_odin(err) | |
| } | |
| return {handle, state.n_qubits}, .None | |
| } | |
| state_fidelity :: proc(state1: ^Quantum_State, state2: ^Quantum_State) -> (f64, Quantum_Error) { | |
| fidelity: f64 | |
| err := bob_state_fidelity(state1.handle, state2.handle, &fidelity) | |
| return fidelity, error_to_odin(err) if err != ERROR_NONE else .None | |
| } | |
| // ========================================================================= | |
| // Hamiltonian Context | |
| // ========================================================================= | |
| Hamiltonian :: struct { | |
| handle: Hamiltonian_Handle, | |
| n_qubits: int, | |
| } | |
| hamiltonian_create :: proc(n_qubits: int, ham_type: int = HAM_SPARSE) -> (Hamiltonian, Quantum_Error) { | |
| handle: Hamiltonian_Handle | |
| err := bob_hamiltonian_create(c.int(n_qubits), c.int(ham_type), &handle) | |
| if err != ERROR_NONE { | |
| return {}, error_to_odin(err) | |
| } | |
| return {handle, n_qubits}, .None | |
| } | |
| hamiltonian_destroy :: proc(ham: ^Hamiltonian) -> Quantum_Error { | |
| if ham.handle != nil { | |
| err := bob_hamiltonian_destroy(ham.handle) | |
| if err != ERROR_NONE { | |
| return error_to_odin(err) | |
| } | |
| } | |
| return .None | |
| } | |
| hamiltonian_add_term :: proc(ham: ^Hamiltonian, coeff_re: f64, coeff_im: f64, qubits: []int) -> Quantum_Error { | |
| qubits_c := make([]c.int, len(qubits), context.allocator) | |
| defer delete(qubits_c, context.allocator) | |
| for i, q in qubits { | |
| qubits_c[i] = c.int(q) | |
| } | |
| err := bob_hamiltonian_add_term(ham.handle, coeff_re, coeff_im, raw_data(qubits_c), c.int(len(qubits_c))) | |
| return error_to_odin(err) if err != ERROR_NONE else .None | |
| } | |
| Complex :: struct { | |
| re: f64, | |
| im: f64, | |
| } | |
| hamiltonian_expectation :: proc(ham: ^Hamiltonian, state: ^Quantum_State) -> (Complex, Quantum_Error) { | |
| exp_re: f64 | |
| exp_im: f64 | |
| err := bob_hamiltonian_expectation(ham.handle, state.handle, &exp_re, &exp_im) | |
| return {exp_re, exp_im}, error_to_odin(err) if err != ERROR_NONE else .None | |
| } | |
| hamiltonian_eigenvalues :: proc(ham: ^Hamiltonian, n_vals: int, allocator := context.allocator) -> ([]f64, Quantum_Error) { | |
| vals_ptr: rawptr | |
| err := bob_hamiltonian_eigenvalues(ham.handle, c.int(n_vals), &vals_ptr) | |
| if err != ERROR_NONE { | |
| return nil, error_to_odin(err) | |
| } | |
| if n_vals <= 0 { | |
| return make([]f64, 0, allocator), .None | |
| } | |
| vals := make([]f64, n_vals, allocator) | |
| doubles := cast([^]f64)vals_ptr | |
| for i in 0..<n_vals { | |
| vals[i] = doubles[i] | |
| } | |
| return vals, .None | |
| } | |
| hamiltonian_time_evolve :: proc(ham: ^Hamiltonian, state: ^Quantum_State, time: f64) -> (Quantum_State, Quantum_Error) { | |
| handle: State_Handle | |
| err := bob_hamiltonian_time_evolve(ham.handle, state.handle, time, &handle) | |
| if err != ERROR_NONE { | |
| return {}, error_to_odin(err) | |
| } | |
| return {handle, state.n_qubits}, .None | |
| } | |
| // ========================================================================= | |
| // Examples | |
| // ========================================================================= | |
| example_simple_rng :: proc() { | |
| rng, err := rng_create(12345) | |
| if err != .None { | |
| return | |
| } | |
| defer rng_destroy(&rng) | |
| u, _ := rng_uniform(&rng) | |
| n, _ := rng_normal(&rng) | |
| i, _ := rng_integer(&rng, 0, 100) | |
| fmt.printf("Uniform: %v\n", u) | |
| fmt.printf("Normal: %v\n", n) | |
| fmt.printf("Integer: %v\n", i) | |
| } | |
| example_quantum_circuit :: proc() { | |
| state, err := state_create(2) | |
| if err != .None { | |
| return | |
| } | |
| defer state_destroy(&state) | |
| state_apply_gate(&state, GATE_H, 0) | |
| result, _ := state_measure(&state, 0) | |
| fmt.printf("Measurement: %d with prob %v\n", result.outcome, result.probability) | |
| } | |
| example_lattice_evolution :: proc() { | |
| lattice, err := lattice_create(4, 4, 4, 1.0) | |
| if err != .None { | |
| return | |
| } | |
| defer lattice_destroy(&lattice) | |
| for i in 0..<10 { | |
| energy, _ := lattice_energy(&lattice) | |
| entropy, _ := lattice_entropy(&lattice) | |
| lattice_evolve(&lattice, 1) | |
| fmt.printf("Step %d: E=%v S=%v\n", i, energy, entropy) | |
| } | |
| } | |
| example_vqe :: proc() { | |
| ham, err := hamiltonian_create(2) | |
| if err != .None { | |
| return | |
| } | |
| defer hamiltonian_destroy(&ham) | |
| state, err := state_create(2) | |
| if err != .None { | |
| return | |
| } | |
| defer state_destroy(&state) | |
| state_apply_gate(&state, GATE_RY, 0, {1.5}) | |
| state_apply_gate(&state, GATE_RZ, 0, {0.7}) | |
| hamiltonian_add_term(&ham, 1.0, 0.0, {0}) | |
| hamiltonian_add_term(&ham, 1.0, 0.0, {1}) | |
| exp, _ := hamiltonian_expectation(&ham, &state) | |
| fmt.printf("Expectation: %v + %vi\n", exp.re, exp.im) | |
| } | |