Download smalltalk/BobQuantum.st from Snapkitty/sov-kernel-monster: direct link, hf CLI and curl.
- Browser
- Download file 30.4 kB
-
https://huggingface.co/Snapkitty/sov-kernel-monster/resolve/main/smalltalk/BobQuantum.st
- Command line
-
hf download hf://Snapkitty/sov-kernel-monster/smalltalk/BobQuantum.st
-
curl -L -o BobQuantum.st https://huggingface.co/Snapkitty/sov-kernel-monster/resolve/main/smalltalk/BobQuantum.st
30.4 kB
| Object subclass: #BobQuantumLibrary | |
| instanceVariableNames: 'libraryHandle functionCache' | |
| classVariableNames: 'UniqueInstance' | |
| package: 'BOB-Quantum-FFI' | |
| BobQuantumLibrary class >> initialize [ | |
| UniqueInstance := nil. | |
| ] | |
| BobQuantumLibrary class >> current [ | |
| ^ UniqueInstance ifNil: [ UniqueInstance := self basicNew initializeLibrary; yourself ] | |
| ] | |
| BobQuantumLibrary class >> reset [ | |
| UniqueInstance := nil. | |
| ] | |
| BobQuantumLibrary >> initializeLibrary [ | |
| libraryHandle := nil. | |
| functionCache := IdentityDictionary new. | |
| ^ self loadLibrary | |
| ] | |
| BobQuantumLibrary >> loadLibrary [ | |
| | libName | | |
| libName := self libraryNameForPlatform. | |
| [ libraryHandle := ExternalLibrary open: libName ] | |
| on: Error | |
| do: [ :ex | | |
| self error: 'Failed to load BOB Quantum library: ', libName, '. Error: ', ex messageText | |
| ]. | |
| ^ self | |
| ] | |
| BobQuantumLibrary >> libraryNameForPlatform [ | |
| ^ (Smalltalk platform name = 'unix' or: [ Smalltalk platform name = 'macos' ]) | |
| ifTrue: [ 'bob_quantum' ] | |
| ifFalse: [ 'bob_quantum.dll' ] | |
| ] | |
| BobQuantumLibrary >> function: aSymbol [ | |
| ^ functionCache | |
| at: aSymbol | |
| ifAbsentPut: [ self lookupFunction: aSymbol ] | |
| ] | |
| BobQuantumLibrary >> lookupFunction: aSymbol [ | |
| | funcSpec returnType argTypes func | | |
| funcSpec := self functionSpecFor: aSymbol. | |
| returnType := funcSpec first. | |
| argTypes := funcSpec second. | |
| func := ExternalFunction | |
| library: libraryHandle | |
| function: aSymbol asString | |
| returnType: returnType | |
| argTypes: argTypes. | |
| ^ func | |
| ] | |
| BobQuantumLibrary >> functionSpecFor: aSymbol [ | |
| "Returns an Array: #(returnType argTypesArray). | |
| Types: #void #int #uint #long #ulong #float #double #pointer #bool #char #string" | |
| ^ { | |
| #bob_rng_create -> #(#pointer #(#uint)). | |
| #bob_rng_destroy -> #(#void #(#pointer)). | |
| #bob_rng_next_uint32 -> #(#uint #(#pointer)). | |
| #bob_rng_next_double -> #(#double #(#pointer)). | |
| #bob_rng_next_gaussian -> #(#double #(#pointer #double #double)). | |
| #bob_lattice_create -> #(#pointer #(#int #int #int #double)). | |
| #bob_lattice_destroy -> #(#void #(#pointer)). | |
| #bob_lattice_get_nx -> #(#int #(#pointer)). | |
| #bob_lattice_get_ny -> #(#int #(#pointer)). | |
| #bob_lattice_get_nz -> #(#int #(#pointer)). | |
| #bob_lattice_get_coupling -> #(#double #(#pointer)). | |
| #bob_lattice_get_volume -> #(#int #(#pointer)). | |
| #bob_lattice_get_neighbors -> #(#pointer #(#pointer #int #pointer)). | |
| #bob_lattice_compute_coordination -> #(#int #(#pointer)). | |
| #bob_state_create -> #(#pointer #(#pointer #int)). | |
| #bob_state_destroy -> #(#void #(#pointer)). | |
| #bob_state_copy -> #(#pointer #(#pointer)). | |
| #bob_state_get_amplitude -> #(#pointer #(#pointer #int)). | |
| #bob_state_set_amplitude -> #(#void #(#pointer #int #pointer)). | |
| #bob_state_normalize -> #(#void #(#pointer)). | |
| #bob_state_inner_product -> #(#pointer #(#pointer #pointer)). | |
| #bob_state_expectation_value -> #(#double #(#pointer #pointer)). | |
| #bob_state_entropy -> #(#double #(#pointer)). | |
| #bob_state_fidelity -> #(#double #(#pointer #pointer)). | |
| #bob_hamiltonian_create -> #(#pointer #(#pointer)). | |
| #bob_hamiltonian_destroy -> #(#void #(#pointer)). | |
| #bob_hamiltonian_add_ising_term -> #(#void #(#pointer #double #int #int)). | |
| #bob_hamiltonian_add_transverse_field -> #(#void #(#pointer #double #int)). | |
| #bob_hamiltonian_add_heisenberg_term -> #(#void #(#pointer #double #int #int)). | |
| #bob_hamiltonian_add_custom_term -> #(#void #(#pointer #pointer #int)). | |
| #bob_hamiltonian_build_matrix -> #(#void #(#pointer)). | |
| #bob_hamiltonian_get_matrix -> #(#pointer #(#pointer)). | |
| #bob_hamiltonian_get_eigenvalues -> #(#pointer #(#pointer #pointer #int)). | |
| #bob_world_create -> #(#pointer #(#pointer #pointer #pointer)). | |
| #bob_world_destroy -> #(#void #(#pointer)). | |
| #bob_world_create_lattice -> #(#pointer #(#pointer #int #int #int #double)). | |
| #bob_world_run_simulation -> #(#int #(#pointer #ulong #double)). | |
| #bob_world_get_state -> #(#pointer #(#pointer)). | |
| #bob_world_get_hamiltonian -> #(#pointer #(#pointer)). | |
| #bob_world_get_lattice -> #(#pointer #(#pointer)). | |
| #bob_world_visualize -> #(#void #(#pointer #string #int #int)). | |
| #bob_world_checkpoint -> #(#int #(#pointer #string)). | |
| #bob_world_restore -> #(#int #(#pointer #string)). | |
| #bob_world_get_energy -> #(#double #(#pointer)). | |
| #bob_world_get_magnetization -> #(#double #(#pointer #int)). | |
| #bob_world_get_correlation -> #(#double #(#pointer #int #int)). | |
| } detect: [ :assoc | assoc key = aSymbol ] ifNone: [ self error: 'Unknown function: ', aSymbol ] value | |
| ] | |
| BobQuantumLibrary >> shutdown [ | |
| libraryHandle ifNotNil: [ libraryHandle close. libraryHandle := nil ]. | |
| functionCache := nil. | |
| ] | |
| BobQuantumLibrary >> finalize [ | |
| self shutdown. | |
| ] | |
| "--------------------------------------------------------------------------------" | |
| " BobRNG - Random Number Generator Wrapper | |
| "--------------------------------------------------------------------------------" | |
| Object subclass: #BobRNG | |
| instanceVariableNames: 'handle' | |
| classVariableNames: '' | |
| package: 'BOB-Quantum-FFI' | |
| BobRNG class >> new [ | |
| ^ self basicNew initialize | |
| ] | |
| BobRNG >> initialize [ | |
| handle := BobQuantumLibrary current function: #bob_rng_create value: 12345 asUnsignedInteger. | |
| handle ifNil: [ self error: 'Failed to create RNG handle' ]. | |
| ^ self | |
| ] | |
| BobRNG >> initializeWithSeed: aSeed [ | |
| handle := BobQuantumLibrary current function: #bob_rng_create value: aSeed asUnsignedInteger. | |
| handle ifNil: [ self error: 'Failed to create RNG handle with seed' ]. | |
| ^ self | |
| ] | |
| BobRNG >> nextUInt32 [ | |
| ^ BobQuantumLibrary current function: #bob_rng_next_uint32 value: handle | |
| ] | |
| BobRNG >> nextDouble [ | |
| ^ BobQuantumLibrary current function: #bob_rng_next_double value: handle | |
| ] | |
| BobRNG >> nextGaussianWithMean: mu sigma: sigma [ | |
| ^ BobQuantumLibrary current function: #bob_rng_next_gaussian value: handle value: mu value: sigma | |
| ] | |
| BobRNG >> nextIntegerInRange: min to: max [ | |
| | range rand | | |
| range := max - min + 1. | |
| rand := self nextUInt32. | |
| ^ min + (rand \\ range) | |
| ] | |
| BobRNG >> nextBoolean [ | |
| ^ (self nextUInt32 bitAnd: 1) = 1 | |
| ] | |
| BobRNG >> shuffle: aCollection [ | |
| | n i j temp | | |
| n := aCollection size. | |
| n <= 1 ifTrue: [ ^ aCollection ]. | |
| i := n. | |
| [ i > 1 ] whileTrue: [ | |
| j := self nextIntegerInRange: 1 to: i. | |
| temp := aCollection at: i. | |
| aCollection at: i put: (aCollection at: j). | |
| aCollection at: j put: temp. | |
| i := i - 1. | |
| ]. | |
| ^ aCollection | |
| ] | |
| BobRNG >> destroy [ | |
| handle ifNotNil: [ | |
| BobQuantumLibrary current function: #bob_rng_destroy value: handle. | |
| handle := nil. | |
| ]. | |
| ] | |
| BobRNG >> finalize [ | |
| self destroy. | |
| ] | |
| BobRNG >> handle [ | |
| ^ handle | |
| ] | |
| BobRNG >> isValid [ | |
| ^ handle notNil | |
| ] | |
| "--------------------------------------------------------------------------------" | |
| " BobLattice - Spatial Lattice Structure | |
| "--------------------------------------------------------------------------------" | |
| Object subclass: #BobLattice | |
| instanceVariableNames: 'handle nx ny nz coupling volume coordinationNumber' | |
| classVariableNames: '' | |
| package: 'BOB-Quantum-FFI' | |
| BobLattice class >> create: nx ny: ny nz: nz coupling: j [ | |
| ^ self basicNew initializeWith: nx ny: ny nz: nz coupling: j | |
| ] | |
| BobLattice >> initializeWith: nxArg ny: nyArg nz: nzArg coupling: jArg [ | |
| nx := nxArg. ny := nyArg. nz := nzArg. coupling := jArg. | |
| handle := BobQuantumLibrary current function: #bob_lattice_create value: nx value: ny value: nz value: jArg. | |
| handle ifNil: [ self error: 'Failed to create lattice' ]. | |
| volume := self computeVolume. | |
| coordinationNumber := self computeCoordination. | |
| ^ self | |
| ] | |
| BobLattice >> computeVolume [ | |
| ^ BobQuantumLibrary current function: #bob_lattice_get_volume value: handle | |
| ] | |
| BobLattice >> computeCoordination [ | |
| ^ BobQuantumLibrary current function: #bob_lattice_compute_coordination value: handle | |
| ] | |
| BobLattice >> getNeighborsForSite: siteIndex into: bufferArray [ | |
| "bufferArray must be a pre-allocated Array of size coordinationNumber" | |
| | neighborPtr | | |
| neighborPtr := BobQuantumLibrary current function: #bob_lattice_get_neighbors value: handle value: siteIndex value: bufferArray. | |
| ^ neighborPtr | |
| ] | |
| BobLattice >> neighborsOf: siteIndex [ | |
| | buffer | | |
| buffer := Array new: coordinationNumber withAll: 0. | |
| self getNeighborsForSite: siteIndex into: buffer. | |
| ^ buffer | |
| ] | |
| BobLattice >> allNeighbors [ | |
| | allNeighbors | | |
| allNeighbors := Array new: volume. | |
| 1 to: volume do: [ :i | | |
| allNeighbors at: i put: (self neighborsOf: i - 1) "C uses 0-based" | |
| ]. | |
| ^ allNeighbors | |
| ] | |
| BobLattice >> siteIndexToCoordinates: index [ | |
| | x y z | | |
| z := index // (nx * ny). | |
| y := (index \\ (nx * ny)) // nx. | |
| x := index \\ nx. | |
| ^ { x. y. z } | |
| ] | |
| BobLattice >> coordinatesToSiteIndex: coords [ | |
| ^ (coords third * nx * ny) + (coords second * nx) + coords first | |
| ] | |
| BobLattice >> distanceBetween: i and: j [ | |
| | ci cj dx dy dz | | |
| ci := self siteIndexToCoordinates: i. | |
| cj := self siteIndexToCoordinates: j. | |
| dx := (ci first - cj first) abs. | |
| dy := (ci second - cj second) abs. | |
| dz := (ci third - cj third) abs. | |
| "Periodic boundary conditions" | |
| dx := dx min: (nx - dx). | |
| dy := dy min: (ny - dy). | |
| dz := dz min: (nz - dz). | |
| ^ (dx + dy + dz) asFloat | |
| ] | |
| BobLattice >> destroy [ | |
| handle ifNotNil: [ | |
| BobQuantumLibrary current function: #bob_lattice_destroy value: handle. | |
| handle := nil. | |
| ]. | |
| ] | |
| BobLattice >> finalize [ | |
| self destroy. | |
| ] | |
| BobLattice >> handle [ | |
| ^ handle | |
| ] | |
| BobLattice >> nx [ ^ nx ] | |
| BobLattice >> ny [ ^ ny ] | |
| BobLattice >> nz [ ^ nz ] | |
| BobLattice >> coupling [ ^ coupling ] | |
| BobLattice >> volume [ ^ volume ] | |
| BobLattice >> coordinationNumber [ ^ coordinationNumber ] | |
| BobLattice >> printOn: aStream [ | |
| aStream nextPutAll: 'BobLattice('. | |
| aStream nextPutAll: nx printString; nextPutAll: 'x'; nextPutAll: ny printString; nextPutAll: 'x'; nextPutAll: nz printString. | |
| aStream nextPutAll: ', J='; nextPutAll: coupling printString; nextPutAll: ')'. | |
| ] | |
| "--------------------------------------------------------------------------------" | |
| " BobState - Quantum State Vector (Complex Amplitudes) | |
| "--------------------------------------------------------------------------------" | |
| Object subclass: #BobState | |
| instanceVariableNames: 'handle lattice dimension amplitudesCache' | |
| classVariableNames: '' | |
| package: 'BOB-Quantum-FFI' | |
| BobState class >> forLattice: aLattice [ | |
| ^ self basicNew initializeForLattice: aLattice | |
| ] | |
| BobState class >> forLattice: aLattice dimension: dim [ | |
| ^ self basicNew initializeForLattice: aLattice dimension: dim | |
| ] | |
| BobState >> initializeForLattice: aLattice [ | |
| lattice := aLattice. | |
| dimension := 1 bitShift: aLattice volume. "2^N for qubits, assuming spin-1/2 per site" | |
| self initializeHandle | |
| ] | |
| BobState >> initializeForLattice: aLattice dimension: dim [ | |
| lattice := aLattice. | |
| dimension := dim. | |
| self initializeHandle | |
| ] | |
| BobState >> initializeHandle [ | |
| handle := BobQuantumLibrary current function: #bob_state_create value: lattice handle value: dimension. | |
| handle ifNil: [ self error: 'Failed to create quantum state' ]. | |
| amplitudesCache := nil. | |
| ^ self | |
| ] | |
| BobState >> copy [ | |
| | newHandle newState | | |
| newHandle := BobQuantumLibrary current function: #bob_state_copy value: handle. | |
| newHandle ifNil: [ ^ nil ]. | |
| newState := self class basicNew. | |
| newState handle: newHandle; lattice: lattice; dimension: dimension; yourself. | |
| ^ newState | |
| ] | |
| BobState >> handle: aHandle [ | |
| handle := aHandle. | |
| ] | |
| BobState >> lattice: aLattice [ | |
| lattice := aLattice. | |
| ] | |
| BobState >> dimension: anInt [ | |
| dimension := anInt. | |
| ] | |
| BobState >> getAmplitudeAt: index [ | |
| "Returns a Complex number (Pharo Complex class)" | |
| | ptr real imag | | |
| ptr := BobQuantumLibrary current function: #bob_state_get_amplitude value: handle value: index. | |
| ptr ifNil: [ ^ Complex zero ]. | |
| "Assuming C returns struct { double re; double im; }* or similar packed memory. | |
| We simulate reading memory via ExternalAddress >> getByte / getDouble. | |
| For this binding, we assume a helper or specific ABI. | |
| Here we mock the memory read for completeness." | |
| real := self readDoubleFrom: ptr offset: 0. | |
| imag := self readDoubleFrom: ptr offset: 8. | |
| ^ Complex real: real imaginary: imag | |
| ] | |
| BobState >> setAmplitudeAt: index to: complexValue [ | |
| | ptr | | |
| ptr := self allocateComplexBuffer: complexValue. | |
| BobQuantumLibrary current function: #bob_state_set_amplitude value: handle value: index value: ptr. | |
| self freeBuffer: ptr. | |
| ] | |
| BobState >> allocateComplexBuffer: c [ | |
| | ptr | | |
| ptr := ExternalAddress malloc: 16. "2 doubles" | |
| ptr at: 0 putDouble: c real. | |
| ptr at: 8 putDouble: c imag. | |
| ^ ptr | |
| ] | |
| BobState >> freeBuffer: ptr [ | |
| ptr free. | |
| ] | |
| BobState >> readDoubleFrom: ptr offset: off [ | |
| ^ ptr at: off getDouble. | |
| ] | |
| BobState >> normalize [ | |
| BobQuantumLibrary current function: #bob_state_normalize value: handle. | |
| amplitudesCache := nil. | |
| ] | |
| BobState >> innerProductWith: otherState [ | |
| "Returns Complex" | |
| | ptr real imag | | |
| ptr := BobQuantumLibrary current function: #bob_state_inner_product value: handle value: otherState handle. | |
| ptr ifNil: [ ^ Complex zero ]. | |
| real := self readDoubleFrom: ptr offset: 0. | |
| imag := self readDoubleFrom: ptr offset: 8. | |
| self freeBuffer: ptr. | |
| ^ Complex real: real imaginary: imag | |
| ] | |
| BobState >> expectationValueOf: hamiltonian [ | |
| ^ BobQuantumLibrary current function: #bob_state_expectation_value value: handle value: hamiltonian handle | |
| ] | |
| BobState >> entropy [ | |
| ^ BobQuantumLibrary current function: #bob_state_entropy value: handle | |
| ] | |
| BobState >> fidelityWith: otherState [ | |
| ^ BobQuantumLibrary current function: #bob_state_fidelity value: handle value: otherState handle | |
| ] | |
| BobState >> asArray [ | |
| | arr | | |
| amplitudesCache ifNotNil: [ ^ amplitudesCache ]. | |
| arr := Array new: dimension. | |
| 0 to: dimension - 1 do: [ :i | | |
| arr at: i + 1 put: (self getAmplitudeAt: i) | |
| ]. | |
| amplitudesCache := arr. | |
| ^ arr | |
| ] | |
| BobState >> probabilities [ | |
| ^ self asArray collect: [ :c | c squaredMagnitude ] | |
| ] | |
| BobState >> destroy [ | |
| handle ifNotNil: [ | |
| BobQuantumLibrary current function: #bob_state_destroy value: handle. | |
| handle := nil. | |
| ]. | |
| amplitudesCache := nil. | |
| ] | |
| BobState >> finalize [ | |
| self destroy. | |
| ] | |
| BobState >> handle [ ^ handle ] | |
| BobState >> lattice [ ^ lattice ] | |
| BobState >> dimension [ ^ dimension ] | |
| BobState >> printOn: aStream [ | |
| aStream nextPutAll: 'BobState(dim='; nextPutAll: dimension printString; nextPutAll: ')'. | |
| ] | |
| "--------------------------------------------------------------------------------" | |
| " BobHamiltonian - Quantum Hamiltonian Operator | |
| "--------------------------------------------------------------------------------" | |
| Object subclass: #BobHamiltonian | |
| instanceVariableNames: 'handle lattice matrixCache eigenvaluesCache' | |
| classVariableNames: '' | |
| package: 'BOB-Quantum-FFI' | |
| BobHamiltonian class >> forLattice: aLattice [ | |
| ^ self basicNew initializeForLattice: aLattice | |
| ] | |
| BobHamiltonian >> initializeForLattice: aLattice [ | |
| lattice := aLattice. | |
| handle := BobQuantumLibrary current function: #bob_hamiltonian_create value: lattice handle. | |
| handle ifNil: [ self error: 'Failed to create Hamiltonian' ]. | |
| matrixCache := nil. | |
| eigenvaluesCache := nil. | |
| ^ self | |
| ] | |
| BobHamiltonian >> addIsingTerm: strength siteI: i siteJ: j [ | |
| BobQuantumLibrary current function: #bob_hamiltonian_add_ising_term value: handle value: strength value: i value: j. | |
| matrixCache := nil. | |
| eigenvaluesCache := nil. | |
| ] | |
| BobHamiltonian >> addTransverseField: strength site: i [ | |
| BobQuantumLibrary current function: #bob_hamiltonian_add_transverse_field value: handle value: strength value: i. | |
| matrixCache := nil. | |
| eigenvaluesCache := nil. | |
| ] | |
| BobHamiltonian >> addHeisenbergTerm: strength siteI: i siteJ: j [ | |
| BobQuantumLibrary current function: #bob_hamiltonian_add_heisenberg_term value: handle value: strength value: i value: j. | |
| matrixCache := nil. | |
| eigenvaluesCache := nil. | |
| ] | |
| BobHamiltonian >> addCustomTerm: matrixData size: dim [ | |
| "matrixData: ExternalAddress to double[dim*dim] (row major)" | |
| BobQuantumLibrary current function: #bob_hamiltonian_add_custom_term value: handle value: matrixData value: dim. | |
| matrixCache := nil. | |
| eigenvaluesCache := nil. | |
| ] | |
| BobHamiltonian >> buildMatrix [ | |
| BobQuantumLibrary current function: #bob_hamiltonian_build_matrix value: handle. | |
| matrixCache := nil. | |
| ] | |
| BobHamiltonian >> getMatrix [ | |
| matrixCache ifNotNil: [ ^ matrixCache ]. | |
| | ptr dim data | | |
| dim := lattice volume. | |
| ptr := BobQuantumLibrary current function: #bob_hamiltonian_get_matrix value: handle. | |
| ptr ifNil: [ ^ nil ]. | |
| "Read dim x dim complex matrix (16 bytes per entry)" | |
| data := Matrix rows: dim columns: dim. | |
| 0 to: dim - 1 do: [ :r | | |
| 0 to: dim - 1 do: [ :c | | |
| | offset real imag | | |
| offset := (r * dim + c) * 16. | |
| real := ptr at: offset getDouble. | |
| imag := ptr at: offset + 8 getDouble. | |
| data at: r + 1 at: c + 1 put: (Complex real: real imaginary: imag) | |
| ] | |
| ]. | |
| matrixCache := data. | |
| ^ data | |
| ] | |
| BobHamiltonian >> getEigenvalues: k [ | |
| "Returns lowest k eigenvalues as Array of Doubles" | |
| eigenvaluesCache ifNotNil: [ ^ eigenvaluesCache first: k ]. | |
| | ptr buffer dim | | |
| dim := lattice volume. | |
| k := k min: dim. | |
| buffer := ExternalAddress malloc: (k * 8). | |
| ptr := BobQuantumLibrary current function: #bob_hamiltonian_get_eigenvalues value: handle value: buffer value: k. | |
| ptr ifNil: [ ^ nil ]. | |
| eigenvaluesCache := Array new: k. | |
| 1 to: k do: [ :i | | |
| eigenvaluesCache at: i put: (buffer at: (i-1)*8 getDouble) | |
| ]. | |
| buffer free. | |
| ^ eigenvaluesCache | |
| ] | |
| BobHamiltonian >> groundStateEnergy [ | |
| ^ (self getEigenvalues: 1) first | |
| ] | |
| BobHamiltonian >> destroy [ | |
| handle ifNotNil: [ | |
| BobQuantumLibrary current function: #bob_hamiltonian_destroy value: handle. | |
| handle := nil. | |
| ]. | |
| matrixCache := nil. | |
| eigenvaluesCache := nil. | |
| ] | |
| BobHamiltonian >> finalize [ | |
| self destroy. | |
| ] | |
| BobHamiltonian >> handle [ ^ handle ] | |
| BobHamiltonian >> lattice [ ^ lattice ] | |
| BobHamiltonian >> printOn: aStream [ | |
| aStream nextPutAll: 'BobHamiltonian(for: '; nextPutAll: lattice printString; nextPutAll: ')'. | |
| ] | |
| "--------------------------------------------------------------------------------" | |
| " BobQuantumWorld - High Level Simulation Facade | |
| "--------------------------------------------------------------------------------" | |
| Object subclass: #BobQuantumWorld | |
| instanceVariableNames: 'handle lattice state hamiltonian rng simulationTime stepCount observablesHistory' | |
| classVariableNames: '' | |
| package: 'BOB-Quantum-FFI' | |
| BobQuantumWorld class >> new [ | |
| ^ self basicNew initialize | |
| ] | |
| BobQuantumWorld >> initialize [ | |
| handle := BobQuantumLibrary current function: #bob_world_create value: nil value: nil value: nil. "Null pointers for auto-create" | |
| handle ifNil: [ self error: 'Failed to create Quantum World' ]. | |
| lattice := nil. | |
| state := nil. | |
| hamiltonian := nil. | |
| rng := BobRNG new. | |
| simulationTime := 0.0. | |
| stepCount := 0. | |
| observablesHistory := OrderedCollection new. | |
| ^ self | |
| ] | |
| BobQuantumWorld >> createLattice: nx ny: ny nz: nz coupling: j [ | |
| lattice := BobLattice create: nx ny: ny nz: nz coupling: j. | |
| "Re-initialize world with this lattice" | |
| handle := BobQuantumLibrary current function: #bob_world_create_lattice value: handle value: nx value: ny value: nz value: j. | |
| handle ifNil: [ self error: 'Failed to create lattice in world' ]. | |
| state := BobState forLattice: lattice. | |
| hamiltonian := BobHamiltonian forLattice: lattice. | |
| ^ lattice | |
| ] | |
| BobQuantumWorld >> addIsingInteraction: strength between: i and: j [ | |
| hamiltonian addIsingTerm: strength siteI: i siteJ: j. | |
| ] | |
| BobQuantumWorld >> addTransverseField: strength at: i [ | |
| hamiltonian addTransverseField: strength site: i. | |
| ] | |
| BobQuantumWorld >> addHeisenbergInteraction: strength between: i and: j [ | |
| hamiltonian addHeisenbergTerm: strength siteI: i siteJ: j. | |
| ] | |
| BobQuantumWorld >> buildHamiltonian [ | |
| hamiltonian buildMatrix. | |
| ] | |
| BobQuantumWorld >> initializeState: aStateBlock [ | |
| "aStateBlock: block taking (state, lattice) to populate amplitudes" | |
| aStateBlock value: state value: lattice. | |
| state normalize. | |
| ] | |
| BobQuantumWorld >> initializeRandomState [ | |
| | dim i | | |
| dim := state dimension. | |
| 0 to: dim - 1 do: [ :i | | |
| | re im | | |
| re := rng nextGaussianWithMean: 0 sigma: 1. | |
| im := rng nextGaussianWithMean: 0 sigma: 1. | |
| state setAmplitudeAt: i to: (Complex real: re imaginary: im) | |
| ]. | |
| state normalize. | |
| ] | |
| BobQuantumWorld >> initializeGroundState [ | |
| | evals evecs | | |
| "Requires diagonalization - mocking via lowest eigenvector retrieval" | |
| evals := hamiltonian getEigenvalues: 1. | |
| "In real impl, we'd get eigenvector. Here we mock." | |
| self initializeRandomState. "Placeholder" | |
| ] | |
| BobQuantumWorld >> runSimulation: steps dt: dt [ | |
| | result energy mag | | |
| steps timesRepeat: [ :step | | |
| result := BobQuantumLibrary current function: #bob_world_run_simulation value: handle value: 1 value: dt. | |
| result = 0 ifTrue: [ self error: 'Simulation step failed at step ', step printString ]. | |
| simulationTime := simulationTime + dt. | |
| stepCount := stepCount + 1. | |
| "Record observables" | |
| energy := self currentEnergy. | |
| mag := self currentMagnetization. | |
| observablesHistory add: { #step -> stepCount. #time -> simulationTime. #energy -> energy. #magnetization -> mag }. | |
| ]. | |
| ^ observablesHistory | |
| ] | |
| BobQuantumWorld >> runSimulation: steps dt: dt withCallback: aBlock [ | |
| steps timesRepeat: [ :step | | |
| BobQuantumLibrary current function: #bob_world_run_simulation value: handle value: 1 value: dt. | |
| simulationTime := simulationTime + dt. | |
| stepCount := stepCount + 1. | |
| aBlock value: self value: stepCount value: simulationTime. | |
| ]. | |
| ] | |
| BobQuantumWorld >> currentEnergy [ | |
| ^ BobQuantumLibrary current function: #bob_world_get_energy value: handle | |
| ] | |
| BobQuantumWorld >> currentMagnetization [ | |
| ^ BobQuantumLibrary current function: #bob_world_get_magnetization value: handle value: 0 "Z-axis" | |
| ] | |
| BobQuantumWorld >> correlationBetween: i and: j [ | |
| ^ BobQuantumLibrary current function: #bob_world_get_correlation value: handle value: i value: j | |
| ] | |
| BobQuantumWorld >> visualize [ | |
| self visualizeWithTitle: 'BOB Quantum Simulation' width: 800 height: 600 | |
| ] | |
| BobQuantumWorld >> visualizeWithTitle: title width: w height: h [ | |
| BobQuantumLibrary current function: #bob_world_visualize value: handle value: title value: w value: h. | |
| ] | |
| BobQuantumWorld >> visualizeToFile: filename [ | |
| "Assumes C library supports file output via title path or separate func" | |
| BobQuantumLibrary current function: #bob_world_visualize value: handle value: filename value: 1920 value: 1080. | |
| ] | |
| BobQuantumWorld >> checkpoint: filename [ | |
| | result | | |
| result := BobQuantumLibrary current function: #bob_world_checkpoint value: handle value: filename. | |
| ^ result = 1 | |
| ] | |
| BobQuantumWorld >> restore: filename [ | |
| | result | | |
| result := BobQuantumLibrary current function: #bob_world_restore value: handle value: filename. | |
| result = 1 ifTrue: [ self refreshHandles ]. | |
| ^ result = 1 | |
| ] | |
| BobQuantumWorld >> refreshHandles [ | |
| lattice := BobLattice basicNew handle: (BobQuantumLibrary current function: #bob_world_get_lattice value: handle); yourself. | |
| state := BobState basicNew handle: (BobQuantumLibrary current function: #bob_world_get_state value: handle); lattice: lattice; yourself. | |
| hamiltonian := BobHamiltonian basicNew handle: (BobQuantumLibrary current function: #bob_world_get_hamiltonian value: handle); lattice: lattice; yourself. | |
| ] | |
| BobQuantumWorld >> getState [ | |
| ^ state | |
| ] | |
| BobQuantumWorld >> getHamiltonian [ | |
| ^ hamiltonian | |
| ] | |
| BobQuantumWorld >> getLattice [ | |
| ^ lattice | |
| ] | |
| BobQuantumWorld >> getObservablesHistory [ | |
| ^ observablesHistory | |
| ] | |
| BobQuantumWorld >> exportObservablesAsCSV [ | |
| | stream | | |
| stream := WriteStream on: String new. | |
| stream nextPutAll: 'step,time,energy,magnetization'; cr. | |
| observablesHistory do: [ :obs | | |
| stream | |
| nextPutAll: (obs at: #step) printString; nextPut: $,; | |
| nextPutAll: (obs at: #time) printString; nextPut: $,; | |
| nextPutAll: (obs at: #energy) printString; nextPut: $,; | |
| nextPutAll: (obs at: #magnetization) printString; cr. | |
| ]. | |
| ^ stream contents | |
| ] | |
| BobQuantumWorld >> destroy [ | |
| handle ifNotNil: [ | |
| BobQuantumLibrary current function: #bob_world_destroy value: handle. | |
| handle := nil. | |
| ]. | |
| lattice ifNotNil: [ lattice destroy ]. | |
| state ifNotNil: [ state destroy ]. | |
| hamiltonian ifNotNil: [ hamiltonian destroy ]. | |
| rng ifNotNil: [ rng destroy ]. | |
| ] | |
| BobQuantumWorld >> finalize [ | |
| self destroy. | |
| ] | |
| BobQuantumWorld >> handle [ ^ handle ] | |
| BobQuantumWorld >> simulationTime [ ^ simulationTime ] | |
| BobQuantumWorld >> stepCount [ ^ stepCount ] | |
| BobQuantumWorld >> printOn: aStream [ | |
| aStream nextPutAll: 'BobQuantumWorld('. | |
| aStream nextPutAll: 'steps='; nextPutAll: stepCount printString. | |
| aStream nextPutAll: ', time='; nextPutAll: simulationTime printString. | |
| lattice ifNotNil: [ aStream nextPutAll: ', '; nextPutAll: lattice printString ]. | |
| aStream nextPutAll: ')'. | |
| ] | |
| "--------------------------------------------------------------------------------" | |
| " Utility Extensions & Helpers | |
| "--------------------------------------------------------------------------------" | |
| "ExternalAddress helper methods for structured memory access (simulated for Pharo FFI)" | |
| ExternalAddress >> at: offset putDouble: aDouble [ | |
| "Primitive: write double at offset. Implemented in VM/FFI plugin." | |
| <primitive: 'primitiveExternalAddressAtPutDouble' module: 'FFI'> | |
| ^ self primitiveFailed | |
| ] | |
| ExternalAddress >> at: offset getDouble [ | |
| "Primitive: read double at offset." | |
| <primitive: 'primitiveExternalAddressAtGetDouble' module: 'FFI'> | |
| ^ self primitiveFailed | |
| ] | |
| ExternalAddress >> malloc: size [ | |
| "Primitive: allocate memory." | |
| <primitive: 'primitiveExternalAddressMalloc' module: 'FFI'> | |
| ^ self primitiveFailed | |
| ] | |
| ExternalAddress >> free [ | |
| "Primitive: free memory." | |
| <primitive: 'primitiveExternalAddressFree' module: 'FFI'> | |
| ^ self primitiveFailed | |
| ] | |
| "Complex Number Support (Pharo Kernel)" | |
| Object subclass: #Complex [ | |
| instanceVariableNames: 'real imag' | |
| classVariableNames: '' | |
| package: 'BOB-Quantum-Math' | |
| ] | |
| Complex class >> real: r imaginary: i [ | |
| ^ self basicNew setReal: r imaginary: i; yourself | |
| ] | |
| Complex >> setReal: r imaginary: i [ | |
| real := r. imag := i. ^ self | |
| ] | |
| Complex class >> zero [ ^ self real: 0 imaginary: 0 ] | |
| Complex class >> one [ ^ self real: 1 imaginary: 0 ] | |
| Complex class >> i [ ^ self real: 0 imaginary: 1 ] | |
| Complex >> real [ ^ real ] | |
| Complex >> imag [ ^ imag ] | |
| Complex >> + aComplex [ | |
| ^ Complex real: real + aComplex real imaginary: imag + aComplex imag | |
| ] | |
| Complex >> - aComplex [ | |
| ^ Complex real: real - aComplex real imaginary: imag - aComplex imag | |
| ] | |
| Complex >> * aComplex [ | |
| ^ Complex | |
| real: (real * aComplex real) - (imag * aComplex imag) | |
| imaginary: (real * aComplex imag) + (imag * aComplex real) | |
| ] | |
| Complex >> / aComplex [ | |
| | denom | | |
| denom := aComplex squaredMagnitude. | |
| ^ Complex | |
| real: ((real * aComplex real) + (imag * aComplex imag)) / denom | |
| imaginary: ((imag * aComplex real) - (real * aComplex imag)) / denom | |
| ] | |
| Complex >> squaredMagnitude [ | |
| ^ real * real + imag * imag | |
| ] | |
| Complex >> magnitude [ | |
| ^ self squaredMagnitude sqrt | |
| ] | |
| Complex >> conjugate [ | |
| ^ Complex real: real imaginary: imag negated | |
| ] | |
| Complex >> exp [ | |
| | r | | |
| r := real exp. | |
| ^ Complex real: r * imag cos imaginary: r * imag sin | |
| ] | |
| Complex >> printOn: aStream [ | |
| aStream nextPutAll: '('; nextPutAll: real printString. | |
| imag >= 0 ifTrue: [ aStream nextPutAll: '+' ]. | |
| aStream nextPutAll: imag printString; nextPutAll: 'i)'. | |
| ] | |
| Complex >> = aComplex [ | |
| ^ real = aComplex real and: [ imag = aComplex imag ] | |
| ] | |
| Complex >> hash [ | |
| ^ real hash bitXor: imag hash | |
| ] | |
| "Matrix Helper (Simple Array of Arrays wrapper)" | |
| Object subclass: #Matrix [ | |
| instanceVariableNames: 'rows columns data' | |
| classVariableNames: '' | |
| package: 'BOB-Quantum-Math' | |
| ] | |
| Matrix class >> rows: r columns: c [ | |
| ^ self basicNew initializeRows: r columns: c | |
| ] | |
| Matrix >> initializeRows: r columns: c [ | |
| rows := r. columns := c. | |
| data := Array new: r * c withAll: Complex zero. | |
| ^ self | |
| ] | |
| Matrix >> at: r at: c [ | |
| ^ data at: ((r - 1) * columns + c) | |
| ] | |
| Matrix >> at: r at: c put: val [ | |
| data at: ((r - 1) * columns + c) put: val. | |
| ] | |
| Matrix >> row: r [ | |
| | arr | | |
| arr := Array new: columns. | |
| 1 to: columns do: [ :c | arr at: c put: (self at: r at: c) ]. | |
| ^ arr | |
| ] | |
| Matrix >> column: c [ | |
| | arr |