diff --git a/previews/PR308/.documenter-siteinfo.json b/previews/PR308/.documenter-siteinfo.json index bde813e4c..8b88c9cf5 100644 --- a/previews/PR308/.documenter-siteinfo.json +++ b/previews/PR308/.documenter-siteinfo.json @@ -1 +1 @@ -{"documenter":{"julia_version":"1.11.3","generation_timestamp":"2025-02-01T04:52:39","documenter_version":"1.8.0"}} \ No newline at end of file +{"documenter":{"julia_version":"1.11.3","generation_timestamp":"2025-02-01T13:05:18","documenter_version":"1.8.0"}} \ No newline at end of file diff --git a/previews/PR308/API.html b/previews/PR308/API.html index d56304f74..3e3058b16 100644 --- a/previews/PR308/API.html +++ b/previews/PR308/API.html @@ -1,16 +1,16 @@ -API · Rimu.jl

API

Rimu

Rimu.RimuModule
Rimu

Random integrators for many-body quantum systems

Welcome to Rimu version 0.14.0. Read the documentation online.

source
Rimu.AllOverlapsType
AllOverlaps(n_replicas=2; operator=nothing, transform=nothing, vecnorm=true)
+API · Rimu.jl

API

Rimu

Rimu.RimuModule
Rimu

Random integrators for many-body quantum systems

Welcome to Rimu version 0.14.0. Read the documentation online.

source
Rimu.AllOverlapsType
AllOverlaps(n_replicas=2; operator=nothing, transform=nothing, vecnorm=true)
     <: ReplicaStrategy{n_replicas}

Run n_replicas replicas and report overlaps between all pairs of replica vectors. If operator is not nothing, the overlap dot(c1, operator, c2) is reported as well. If operator is a tuple of operators, the overlaps are computed for all operators.

Column names in the report are of the form c{i}_dot_c{j} for vector-vector overlaps, and c{i}_Op{k}_c{j} for operator overlaps.

See ProjectorMonteCarloProblem, ReplicaStrategy and AbstractOperator (for an interface for implementing operators).

Transformed Hamiltonians

If a transformed Hamiltonian G has been passed to ProjectorMonteCarloProblem then overlaps can be calculated by passing the same transformed Hamiltonian to AllOverlaps by setting transform=G. A warning is given if these two Hamiltonians do not match.

Implemented transformations are:

In the case of a transformed Hamiltonian the overlaps are defined as follows. For a similarity transformation G of the Hamiltonian (see e.g. GutzwillerSampling.)

\[ \hat{G} = f \hat{H} f^{-1}.\]

The expectation value of an operator $\hat{A}$ is

\[ \langle \hat{A} \rangle = \langle \psi | \hat{A} | \psi \rangle - = \frac{\langle \phi | f^{-1} \hat{A} f^{-1} | \phi \rangle}{\langle \phi | f^{-2} | \phi \rangle}\]

where

\[ | \phi \rangle = f | \psi \rangle\]

is the (right) eigenvector of $\hat{G}$ and $| \psi \rangle$ is an eigenvector of $\hat{H}$.

For a K-tuple of input operators $(\hat{A}_1, ..., \hat{A}_K)$, overlaps of $\langle \phi | f^{-1} \hat{A} f^{-1} | \phi \rangle$ are reported as c{i}_Op{k}_c{j}. The correct vector-vector overlap $\langle \phi | f^{-2} | \phi \rangle$ is reported last as c{i}_Op{K+1}_c{j}. This is in addition to the bare vector-vector overlap $\langle \phi | f^{-2} | \phi \rangle$ that is reported as c{i}_dot_c{j}.

In either case the c{i}_dot_c{j} overlap can be omitted with the flag vecnorm=false.

source
Rimu.DoubleLogProjectedType
DoubleLogProjected(; target, projector, ζ = 0.08, ξ = ζ^2/4) <: ShiftStrategy

Strategy for updating the shift according to the log formula with damping parameter ζ and ξ after projecting onto projector.

\[S^{n+1} = S^n -\frac{ζ}{dτ}\ln\left(\frac{P⋅Ψ^{(n+1)}}{P⋅Ψ^{(n)}}\right)-\frac{ξ}{dτ}\ln\left(\frac{P⋅Ψ^{(n+1)}}{\text{target}}\right)\]

Note that adjusting the keyword maxlength in ProjectorMonteCarloProblem is advised as the default may not be appropriate.

See ShiftStrategy, ProjectorMonteCarloProblem.

source
Rimu.DoubleLogSumUpdateType
DoubleLogSumUpdate(; target_walkers = 1000, ζ = 0.08, ξ = ζ^2/4, α = 1/2) <: ShiftStrategy

Strategy for updating the shift according to the log formula with damping parameters ζ and ξ.

\[S^{n+1} = S^n -\frac{ζ}{dτ}\ln\left(\frac{N_\mathrm{w}^{n+1}}{N_\mathrm{w}^n}\right) -- \frac{ξ}{dτ}\ln\left(\frac{N_\mathrm{w}^{n+1}}{N_\mathrm{w}^\text{target}}\right),\]

where $N_\mathrm{w} =$ (1-α)*walkernumber() + α*UniformProjector()⋅ψ computed with walkernumber() and UniformProjector(). When ξ = ζ^2/4 this corresponds to critical damping with a damping time scale T = 2/ζ.

See ShiftStrategy, ProjectorMonteCarloProblem.

source
Rimu.DoubleLogUpdateType
DoubleLogUpdate(; target_walkers = 1_000, ζ = 0.08, ξ = ζ^2/4) <: ShiftStrategy

Strategy for updating the shift according to the log formula with damping parameter ζ and ξ.

\[S^{n+1} = S^n -\frac{ζ}{dτ}\ln\left(\frac{\|Ψ\|_1^{n+1}}{\|Ψ\|_1^n}\right)-\frac{ξ}{dτ}\ln\left(\frac{\|Ψ\|_1^{n+1}}{\|Ψ\|_1^\text{target}}\right)\]

When ξ = ζ^2/4 this corresponds to critical damping with a damping time scale T = 2/ζ.

See ShiftStrategy, ProjectorMonteCarloProblem.

source
Rimu.FCIQMCType
FCIQMC(; kwargs...) <: PMCAlgorithm

Algorithm for the full configuration interaction quantum Monte Carlo (FCIQMC) method. The default algorithm for ProjectorMonteCarloProblem.

Keyword arguments and defaults:

  • shift_strategy = DoubleLogUpdate(; targetwalkers = 1_000, ζ = 0.08, ξ = ζ^2/4): How to update the shift.
  • time_step_strategy = ConstantTimeStep(): Adjust time step or not.

See also ProjectorMonteCarloProblem, ShiftStrategy, TimeStepStrategy, DoubleLogUpdate, ConstantTimeStep.

source
Rimu.FirstOrderTransitionOperatorType
FirstOrderTransitionOperator(hamiltonian, shift, time_step) <: AbstractHamiltonian
-FirstOrderTransitionOperator(sp::DefaultShiftParameters, hamiltonian)

First order transition operator

\[𝐓 = 1 + dτ(S - 𝐇)\]

where $𝐇$ is the hamiltonian, $dτ$ the time_step and $S$ is the shift.

$𝐓$ represents the first order expansion of the exponential evolution operator of the imaginary-time Schrödinger equation (Euler step) and repeated application will project out the ground state eigenvector of the hamiltonian. It is the transition operator used in FCIQMC.

source
Rimu.GramSchmidtType
GramSchmidt(S; orthogonalization_interval = 1) <: SpectralStrategy{S}

Use the Gram-Schmidt procedure to orthogonalize the excited states. A total of S spectral states are used in the simulation, and they are orthogonalized every orthogonalization_interval steps.

Use with the keyword argument spectral_strategy in ProjectorMonteCarloProblem.

source
Rimu.MultiScalarType
MultiScalar

Wrapper over a tuple that supports +, *, min, and max. Used with MPI communication because SVectors are treated as arrays by MPI.Allreduce and Tuples do not support scalar operations.

Example

Suppose you want to compute the sum of a vector dv and also get the number of positive elements it has in a single pass. You can use MultiScalar:

julia> dv = DVec(:a => 1, :b => -2, :c => 1);
+        = \frac{\langle \phi | f^{-1} \hat{A} f^{-1} | \phi \rangle}{\langle \phi | f^{-2} | \phi \rangle}\]

where

\[ | \phi \rangle = f | \psi \rangle\]

is the (right) eigenvector of $\hat{G}$ and $| \psi \rangle$ is an eigenvector of $\hat{H}$.

For a K-tuple of input operators $(\hat{A}_1, ..., \hat{A}_K)$, overlaps of $\langle \phi | f^{-1} \hat{A} f^{-1} | \phi \rangle$ are reported as c{i}_Op{k}_c{j}. The correct vector-vector overlap $\langle \phi | f^{-2} | \phi \rangle$ is reported last as c{i}_Op{K+1}_c{j}. This is in addition to the bare vector-vector overlap $\langle \phi | f^{-2} | \phi \rangle$ that is reported as c{i}_dot_c{j}.

In either case the c{i}_dot_c{j} overlap can be omitted with the flag vecnorm=false.

source
Rimu.DoubleLogProjectedType
DoubleLogProjected(; target, projector, ζ = 0.08, ξ = ζ^2/4) <: ShiftStrategy

Strategy for updating the shift according to the log formula with damping parameter ζ and ξ after projecting onto projector.

\[S^{n+1} = S^n -\frac{ζ}{dτ}\ln\left(\frac{P⋅Ψ^{(n+1)}}{P⋅Ψ^{(n)}}\right)-\frac{ξ}{dτ}\ln\left(\frac{P⋅Ψ^{(n+1)}}{\text{target}}\right)\]

Note that adjusting the keyword maxlength in ProjectorMonteCarloProblem is advised as the default may not be appropriate.

See ShiftStrategy, ProjectorMonteCarloProblem.

source
Rimu.DoubleLogSumUpdateType
DoubleLogSumUpdate(; target_walkers = 1000, ζ = 0.08, ξ = ζ^2/4, α = 1/2) <: ShiftStrategy

Strategy for updating the shift according to the log formula with damping parameters ζ and ξ.

\[S^{n+1} = S^n -\frac{ζ}{dτ}\ln\left(\frac{N_\mathrm{w}^{n+1}}{N_\mathrm{w}^n}\right) +- \frac{ξ}{dτ}\ln\left(\frac{N_\mathrm{w}^{n+1}}{N_\mathrm{w}^\text{target}}\right),\]

where $N_\mathrm{w} =$ (1-α)*walkernumber() + α*UniformProjector()⋅ψ computed with walkernumber() and UniformProjector(). When ξ = ζ^2/4 this corresponds to critical damping with a damping time scale T = 2/ζ.

See ShiftStrategy, ProjectorMonteCarloProblem.

source
Rimu.DoubleLogUpdateType
DoubleLogUpdate(; target_walkers = 1_000, ζ = 0.08, ξ = ζ^2/4) <: ShiftStrategy

Strategy for updating the shift according to the log formula with damping parameter ζ and ξ.

\[S^{n+1} = S^n -\frac{ζ}{dτ}\ln\left(\frac{\|Ψ\|_1^{n+1}}{\|Ψ\|_1^n}\right)-\frac{ξ}{dτ}\ln\left(\frac{\|Ψ\|_1^{n+1}}{\|Ψ\|_1^\text{target}}\right)\]

When ξ = ζ^2/4 this corresponds to critical damping with a damping time scale T = 2/ζ.

See ShiftStrategy, ProjectorMonteCarloProblem.

source
Rimu.FCIQMCType
FCIQMC(; kwargs...) <: PMCAlgorithm

Algorithm for the full configuration interaction quantum Monte Carlo (FCIQMC) method. The default algorithm for ProjectorMonteCarloProblem.

Keyword arguments and defaults:

  • shift_strategy = DoubleLogUpdate(; targetwalkers = 1_000, ζ = 0.08, ξ = ζ^2/4): How to update the shift.
  • time_step_strategy = ConstantTimeStep(): Adjust time step or not.

See also ProjectorMonteCarloProblem, ShiftStrategy, TimeStepStrategy, DoubleLogUpdate, ConstantTimeStep.

source
Rimu.FirstOrderTransitionOperatorType
FirstOrderTransitionOperator(hamiltonian, shift, time_step) <: AbstractHamiltonian
+FirstOrderTransitionOperator(sp::DefaultShiftParameters, hamiltonian)

First order transition operator

\[𝐓 = 1 + dτ(S - 𝐇)\]

where $𝐇$ is the hamiltonian, $dτ$ the time_step and $S$ is the shift.

$𝐓$ represents the first order expansion of the exponential evolution operator of the imaginary-time Schrödinger equation (Euler step) and repeated application will project out the ground state eigenvector of the hamiltonian. It is the transition operator used in FCIQMC.

source
Rimu.GramSchmidtType
GramSchmidt(S; orthogonalization_interval = 1) <: SpectralStrategy{S}

Use the Gram-Schmidt procedure to orthogonalize the excited states. A total of S spectral states are used in the simulation, and they are orthogonalized every orthogonalization_interval steps.

Use with the keyword argument spectral_strategy in ProjectorMonteCarloProblem.

source
Rimu.MultiScalarType
MultiScalar

Wrapper over a tuple that supports +, *, min, and max. Used with MPI communication because SVectors are treated as arrays by MPI.Allreduce and Tuples do not support scalar operations.

Example

Suppose you want to compute the sum of a vector dv and also get the number of positive elements it has in a single pass. You can use MultiScalar:

julia> dv = DVec(:a => 1, :b => -2, :c => 1);
 
 julia> s, p = mapreduce(+, values(dv)) do v
     Rimu.MultiScalar(v, Int(sign(v) == 1))
 end;
 
 julia> s, p
-(0, 2)

Note that only MultiScalars with the same types can be operated on. This is a feature, as it forces type stability.

source
Rimu.PMCSimulationType
PMCSimulation

Holds the state and the results of a projector quantum Monte Carlo (PMC) simulation. Is returned by init(::ProjectorMonteCarloProblem) and solved with solve!(::PMCSimulation).

Obtain the results of a simulation sm as a DataFrame with DataFrame(sm).

Fields

  • problem::ProjectorMonteCarloProblem: The problem that was solved
  • state::Rimu.ReplicaState: The current state of the simulation
  • report::Rimu.Report: The report of the simulation
  • modified::Bool: Whether the simulation has been modified
  • aborted::Bool: Whether the simulation has been aborted
  • success::Bool: Whether the simulation has been completed successfully
  • message::String: A message about the simulation status
  • elapsed_time::Float64: The time elapsed during the simulation

See also state_vectors, ProjectorMonteCarloProblem, init, solve!.

source
Rimu.PostStepStrategyType
PostStepStrategy

Subtypes of PostStepStrategy can be used to perform arbitrary computation on a single state after an FCIQMC step is finished and report the results.

Implemented strategies:

Note: A tuple of multiple strategies can be passed to ProjectorMonteCarloProblem. In that case, all reported column names must be distinct.

Interface:

A subtype of this type must implement post_step_action(::PostStepStrategy, ::SingleState, step::Int).

source
Rimu.ProjectedEnergyType
ProjectedEnergy(hamiltonian, projector; hproj=:hproj, vproj=:vproj) <: PostStepStrategy

After every step, compute hproj = dot(projector, hamiltonian, dv) and vproj = dot(projector, dv), where dv is the instantaneous coefficient vector. projector can be an AbstractDVec, or an AbstractProjector.

Reports to columns hproj and vproj, which can be used to compute projective energy, e.g. with projected_energy. The keyword arguments hproj and vproj can be used to change the names of these columns. This can be used to make the names unique when computing projected energies with different projectors in the same run.

See also projected_energy, ratio_of_means, mixed_estimator, and PostStepStrategy.

source
Rimu.ProjectorMonteCarloProblemType
ProjectorMonteCarloProblem(hamiltonian::AbstractHamiltonian; kwargs...)

Defines a problem to be solved by projector quantum Monte Carlo (QMC) methods, such as the the FCIQMC algorithm.

Common keyword arguments and defaults:

  • time_step = 0.01: Initial time step size.
  • last_step = 100: Controls the number of steps.
  • target_walkers = 1_000: Target for the 1-norm of the coefficient vector.
  • start_at = starting_address(hamiltonian): Define the initial state vector(s). An $r × s$ matrix of state vectors can be passed where $r$ is the number of replicas and $s$ the number of spectral states. See also default_starting_vector.
  • style = IsDynamicSemistochastic(): The StochasticStyle of the simulation.
  • initiator = false: Whether to use initiators. Can be true, false, or a valid InitiatorRule.
  • threading: Default is to use multithreading and/or MPI if available. Set to true to force PDVec for the starting vector, false for serial computation; may be overridden by start_at.
  • reporting_strategy = ReportDFAndInfo(): How and when to report results, see ReportingStrategy.
  • post_step_strategy = (): Extract observables (e.g. ProjectedEnergy), see PostStepStrategy.
  • n_replicas = 1: Number of synchronised independent simulations.
  • replica_strategy = NoStats(n_replicas): Which results to report from replica simulations, see ReplicaStrategy.
  • n_spectral = 1: Number of targeted spectral states. Set n_spectral > 1 to find excited states.
  • spectral_strategy = GramSchmidt(n_spectral): The SpectralStrategy used for orthogonalizing spectral states.

Example

julia> hamiltonian = HubbardReal1D(BoseFS(1,2,3));
+(0, 2)

Note that only MultiScalars with the same types can be operated on. This is a feature, as it forces type stability.

source
Rimu.PMCSimulationType
PMCSimulation

Holds the state and the results of a projector quantum Monte Carlo (PMC) simulation. Is returned by init(::ProjectorMonteCarloProblem) and solved with solve!(::PMCSimulation).

Obtain the results of a simulation sm as a DataFrame with DataFrame(sm).

Fields

  • problem::ProjectorMonteCarloProblem: The problem that was solved
  • state::Rimu.ReplicaState: The current state of the simulation
  • report::Rimu.Report: The report of the simulation
  • modified::Bool: Whether the simulation has been modified
  • aborted::Bool: Whether the simulation has been aborted
  • success::Bool: Whether the simulation has been completed successfully
  • message::String: A message about the simulation status
  • elapsed_time::Float64: The time elapsed during the simulation

See also state_vectors, ProjectorMonteCarloProblem, init, solve!.

source
Rimu.PostStepStrategyType
PostStepStrategy

Subtypes of PostStepStrategy can be used to perform arbitrary computation on a single state after an FCIQMC step is finished and report the results.

Implemented strategies:

Note: A tuple of multiple strategies can be passed to ProjectorMonteCarloProblem. In that case, all reported column names must be distinct.

Interface:

A subtype of this type must implement post_step_action(::PostStepStrategy, ::SingleState, step::Int).

source
Rimu.ProjectedEnergyType
ProjectedEnergy(hamiltonian, projector; hproj=:hproj, vproj=:vproj) <: PostStepStrategy

After every step, compute hproj = dot(projector, hamiltonian, dv) and vproj = dot(projector, dv), where dv is the instantaneous coefficient vector. projector can be an AbstractDVec, or an AbstractProjector.

Reports to columns hproj and vproj, which can be used to compute projective energy, e.g. with projected_energy. The keyword arguments hproj and vproj can be used to change the names of these columns. This can be used to make the names unique when computing projected energies with different projectors in the same run.

See also projected_energy, ratio_of_means, mixed_estimator, and PostStepStrategy.

source
Rimu.ProjectorMonteCarloProblemType
ProjectorMonteCarloProblem(hamiltonian::AbstractHamiltonian; kwargs...)

Defines a problem to be solved by projector quantum Monte Carlo (QMC) methods, such as the the FCIQMC algorithm.

Common keyword arguments and defaults:

  • time_step = 0.01: Initial time step size.
  • last_step = 100: Controls the number of steps.
  • target_walkers = 1_000: Target for the 1-norm of the coefficient vector.
  • start_at = starting_address(hamiltonian): Define the initial state vector(s). An $r × s$ matrix of state vectors can be passed where $r$ is the number of replicas and $s$ the number of spectral states. See also default_starting_vector.
  • style = IsDynamicSemistochastic(): The StochasticStyle of the simulation.
  • initiator = false: Whether to use initiators. Can be true, false, or a valid InitiatorRule.
  • threading: Default is to use multithreading and/or MPI if available. Set to true to force PDVec for the starting vector, false for serial computation; may be overridden by start_at.
  • reporting_strategy = ReportDFAndInfo(): How and when to report results, see ReportingStrategy.
  • post_step_strategy = (): Extract observables (e.g. ProjectedEnergy), see PostStepStrategy.
  • n_replicas = 1: Number of synchronised independent simulations.
  • replica_strategy = NoStats(n_replicas): Which results to report from replica simulations, see ReplicaStrategy.
  • n_spectral = 1: Number of targeted spectral states. Set n_spectral > 1 to find excited states.
  • spectral_strategy = GramSchmidt(n_spectral): The SpectralStrategy used for orthogonalizing spectral states.

Example

julia> hamiltonian = HubbardReal1D(BoseFS(1,2,3));
 
 julia> problem = ProjectorMonteCarloProblem(hamiltonian; target_walkers = 500, last_step = 100);
 
@@ -20,20 +20,20 @@
 true
 
 julia> size(DataFrame(simulation))
-(100, 9)

Further keyword arguments:

  • starting_step = 1: Starting step of the simulation.
  • wall_time = Inf: Maximum time allowed for the simulation.
  • simulation_plan = SimulationPlan(; starting_step, last_step, wall_time): Defines the duration of the simulation. Takes precedence over last_step and wall_time.
  • ζ = 0.08: Damping parameter for the shift update.
  • ξ = ζ^2/4: Forcing parameter for the shift update.
  • shift_strategy = DoubleLogUpdate(; target_walkers, ζ, ξ): How to update the shift, see ShiftStrategy.
  • time_step_strategy = ConstantTimeStep(): Adjust time step or not, see TimeStepStrategy.
  • algorithm = FCIQMC(; shift_strategy, time_step_strategy): The algorithm to use. Currenlty only FCIQMC is implemented.
  • shift: Initial shift value or collection of shift values. Determined by default from the Hamiltonian and the starting vectors.
  • initial_shift_parameters: Initial shift parameters or collection of initial shift parameters. Overrides shift if provided.
  • max_length = 2 * target_walkers + 100: Maximum length of the vectors.
  • display_name = "PMCSimulation": Name displayed in progress bar (via ProgressLogging).
  • metadata: User-supplied metadata to be added to the report. Must be an iterable of pairs or a NamedTuple, e.g. metadata = ("key1" => "value1", "key2" => "value2"). All metadata is converted to strings.
  • random_seed = true: Provide and store a seed for the random number generator. If set to true, a new random seed is generated from RandomDevice(). If set to number, this number is used as the seed. This seed is used by solve (and init) to re-seed the default random number generator (consistently on each MPI rank) such that solveing the same ProjectorMonteCarloProblem twice will yield identical results. If set to false, no seed is used and consecutive random numbers are used.
  • minimum_size = 2*num_spectral_states(spectral_strategy): The minimum size of the basis used to construct starting vectors for simulations of spectral states, if start_at is not provided.

See also init, solve.

source
Rimu.ReplicaStateType
ReplicaState <: AbstractMatrix{SingleState}

Holds information about multiple replicas of SpectralStates. Indexing the ReplicaState state[i, j] returns a SingleState from the ith replica and jth spectral state.

Fields

  • spectral_states: Tuple of SpectralStates
  • max_length::Ref{Int}: Maximum length of the simulation
  • step::Ref{Int}: Current step of the simulation
  • simulation_plan: Simulation plan
  • reporting_strategy: Reporting strategy
  • post_step_strategy: Post-step strategy
  • replica_strategy: Replica strategy

See also ReplicaStrategy, Rimu.SpectralState, Rimu.SingleState, Rimu.PMCSimulation.

source
Rimu.ReplicaStrategyType
ReplicaStrategy{N}

Supertype for strategies that can be passed to ProjectorMonteCarloProblem and control how many replicas are used, and what information is computed and returned. The number of replicas is N.

Concrete implementations

  • NoStats: run (possibly one) replica(s), but don't report any additional info.
  • AllOverlaps: report overlaps between all pairs of replica vectors.

Interface

A subtype of ReplicaStrategy{N} must implement the following function:

source
Rimu.ReportDFAndInfoType
ReportDFAndInfo(; reporting_interval=1, info_interval=100, io=stdout, writeinfo=false) <: ReportingStrategy

The default ReportingStrategy for ProjectorMonteCarloProblem. Report every reporting_intervalth step to a DataFrame and write info message to io every info_intervalth reported step (unless writeinfo == false). The flag writeinfo is useful for controlling info messages in MPI codes, e.g. by setting writeinfo =is_mpi_root().

See also ProjectorMonteCarloProblem, ReportToFile.

source
Rimu.ReportToFileType
ReportToFile(; kwargs...) <: ReportingStrategy

ReportingStrategy for ProjectorMonteCarloProblem that writes the report directly to a file in the Arrow format. Useful when dealing with long jobs or large numbers of replicas, when the report can incur a significant memory cost.

The arrow file can be read back in with load_df(filename) or using Arrow; Arrow.Table(filename).

Keyword arguments

  • filename = "out.arrow": the file to report to. If the file already exists, a new file is created.
  • reporting_interval = 1: interval between simulation steps that are reported.
  • chunk_size = 1000: the size of each chunk that is written to the file. A DataFrame of this size is collected in memory and written to disk. When saving, an info message is also printed to io.
  • save_if =is_mpi_root(): if this value is true, save the report, otherwise ignore it.
  • return_df = false: if this value is true, read the file and return the data frame at the end of computation. Otherwise, an empty DataFrame is returned.
  • io = stdout: The IO to print messages to. Set to devnull if you don't want to see messages printed out.
  • compress = :zstd: compression algorithm to use. Can be :zstd, :lz4 or nothing.

See also load_df, save_df, ReportDFAndInfo, and ProjectorMonteCarloProblem.

source
Rimu.RunTillLastStepType
RunTillLastStep(step::Int = 0 # number of current/starting timestep
+(100, 9)

Further keyword arguments:

  • starting_step = 1: Starting step of the simulation.
  • wall_time = Inf: Maximum time allowed for the simulation.
  • simulation_plan = SimulationPlan(; starting_step, last_step, wall_time): Defines the duration of the simulation. Takes precedence over last_step and wall_time.
  • ζ = 0.08: Damping parameter for the shift update.
  • ξ = ζ^2/4: Forcing parameter for the shift update.
  • shift_strategy = DoubleLogUpdate(; target_walkers, ζ, ξ): How to update the shift, see ShiftStrategy.
  • time_step_strategy = ConstantTimeStep(): Adjust time step or not, see TimeStepStrategy.
  • algorithm = FCIQMC(; shift_strategy, time_step_strategy): The algorithm to use. Currenlty only FCIQMC is implemented.
  • shift: Initial shift value or collection of shift values. Determined by default from the Hamiltonian and the starting vectors.
  • initial_shift_parameters: Initial shift parameters or collection of initial shift parameters. Overrides shift if provided.
  • max_length = 2 * target_walkers + 100: Maximum length of the vectors.
  • display_name = "PMCSimulation": Name displayed in progress bar (via ProgressLogging).
  • metadata: User-supplied metadata to be added to the report. Must be an iterable of pairs or a NamedTuple, e.g. metadata = ("key1" => "value1", "key2" => "value2"). All metadata is converted to strings.
  • random_seed = true: Provide and store a seed for the random number generator. If set to true, a new random seed is generated from RandomDevice(). If set to number, this number is used as the seed. This seed is used by solve (and init) to re-seed the default random number generator (consistently on each MPI rank) such that solveing the same ProjectorMonteCarloProblem twice will yield identical results. If set to false, no seed is used and consecutive random numbers are used.
  • minimum_size = 2*num_spectral_states(spectral_strategy): The minimum size of the basis used to construct starting vectors for simulations of spectral states, if start_at is not provided.

See also init, solve.

source
Rimu.ReplicaStateType
ReplicaState <: AbstractMatrix{SingleState}

Holds information about multiple replicas of SpectralStates. Indexing the ReplicaState state[i, j] returns a SingleState from the ith replica and jth spectral state.

Fields

  • spectral_states: Tuple of SpectralStates
  • max_length::Ref{Int}: Maximum length of the simulation
  • step::Ref{Int}: Current step of the simulation
  • simulation_plan: Simulation plan
  • reporting_strategy: Reporting strategy
  • post_step_strategy: Post-step strategy
  • replica_strategy: Replica strategy

See also ReplicaStrategy, Rimu.SpectralState, Rimu.SingleState, Rimu.PMCSimulation.

source
Rimu.ReplicaStrategyType
ReplicaStrategy{N}

Supertype for strategies that can be passed to ProjectorMonteCarloProblem and control how many replicas are used, and what information is computed and returned. The number of replicas is N.

Concrete implementations

  • NoStats: run (possibly one) replica(s), but don't report any additional info.
  • AllOverlaps: report overlaps between all pairs of replica vectors.

Interface

A subtype of ReplicaStrategy{N} must implement the following function:

source
Rimu.ReportDFAndInfoType
ReportDFAndInfo(; reporting_interval=1, info_interval=100, io=stdout, writeinfo=false) <: ReportingStrategy

The default ReportingStrategy for ProjectorMonteCarloProblem. Report every reporting_intervalth step to a DataFrame and write info message to io every info_intervalth reported step (unless writeinfo == false). The flag writeinfo is useful for controlling info messages in MPI codes, e.g. by setting writeinfo =is_mpi_root().

See also ProjectorMonteCarloProblem, ReportToFile.

source
Rimu.ReportToFileType
ReportToFile(; kwargs...) <: ReportingStrategy

ReportingStrategy for ProjectorMonteCarloProblem that writes the report directly to a file in the Arrow format. Useful when dealing with long jobs or large numbers of replicas, when the report can incur a significant memory cost.

The arrow file can be read back in with load_df(filename) or using Arrow; Arrow.Table(filename).

Keyword arguments

  • filename = "out.arrow": the file to report to. If the file already exists, a new file is created.
  • reporting_interval = 1: interval between simulation steps that are reported.
  • chunk_size = 1000: the size of each chunk that is written to the file. A DataFrame of this size is collected in memory and written to disk. When saving, an info message is also printed to io.
  • save_if =is_mpi_root(): if this value is true, save the report, otherwise ignore it.
  • return_df = false: if this value is true, read the file and return the data frame at the end of computation. Otherwise, an empty DataFrame is returned.
  • io = stdout: The IO to print messages to. Set to devnull if you don't want to see messages printed out.
  • compress = :zstd: compression algorithm to use. Can be :zstd, :lz4 or nothing.

See also load_df, save_df, ReportDFAndInfo, and ProjectorMonteCarloProblem.

source
Rimu.RunTillLastStepType
RunTillLastStep(step::Int = 0 # number of current/starting timestep
              laststep::Int = 100 # number of final timestep
              shiftMode::Bool = false # whether to adjust shift
              shift = 0.0 # starting/current value of shift
              dτ::Float64 = 0.01 # current value of time step
-) <: FciqmcRunStrategy

Parameters for running lomc!() for a fixed number of time steps. For alternative strategies, see FciqmcRunStrategy.

Warning

The use of this strategy is deprecated. Pass the relevant arguments directly to ProjectorMonteCarloProblem or to lomc!() instead.

source
Rimu.ShiftStrategyType
ShiftStrategy

Abstract type for defining the strategy for controlling the norm, potentially by updating the shift. Passed as a parameter to ProjectorMonteCarloProblem or to FCIQMC.

Implemented strategies:

Extended help

Internally To implement a custom strategy, define a new subtype of Rimu.ShiftStrategy and implement methods for:

source
Rimu.SignCoherenceType
SignCoherence(reference[; name=:coherence]) <: PostStepStrategy

After each step, compute the proportion of configurations that have the same sign as they do in the reference_dvec. Reports to a column named name, which defaults to coherence.

source
Rimu.SingleParticleDensityType
SingleParticleDensity(; save_every=1, component) <: PostStepStrategy

PostStepStrategy to compute the diagonal single_particle_density. It records a Tuple with the same eltype as the vector.

Computing the density at every time step can be expensive. This cost can be reduced by setting the save_every argument to a higher value. If the value is set, a vector of zeros is recorded when the saving is skipped.

If the address type has multiple components, the component argument can be used to compute the density on a per-component basis.

The density is not normalized, and must be divided by the vector norm(⋅,2) squared.

See also

source
Rimu.SingleStateType
SingleState(hamiltonian, algorithm, v, wm, pnorm, params, id)

Struct that holds a single state vector and all information needed for an independent run of the algorithm. Can be advanced a step forward with Rimu.advance!.

Fields

  • hamiltonian: Hamiltonian
  • algorithm: Algorithm
  • v: Vector
  • pv: Previous vector
  • wm: Working memory
  • shift_parameters: Shift parameters
  • id::String: id is appended to column names

See also SpectralStrategy, ReplicaStrategy, Rimu.SpectralState, Rimu.ReplicaState, Rimu.replica_stats, Rimu.PMCSimulation.

source
Rimu.SpectralStrategyType
SpectralStrategy{S}

Abstract type for spectral strategies. The spectral strategy is used to control the number of spectral states used in the simulation.

Implemented Strategies

  • GramSchmidt: Orthogonalize the spectral states using the Gram-Schmidt procedure.
source
Rimu.TimerType
Timer <: PostStepStrategy

Record current time after every step. See Base.Libc.time for information on what time is recorded.

source
Rimu.WalkerLonelinessType
WalkerLoneliness(threshold=1) <: PostStepStrategy

After each step, compute the proportion of configurations that are occupied by at most threshold walkers. Reports to a column named loneliness.

source
CommonSolve.solve!Method
solve!(sm::PMCSimulation; kwargs...)::PMCSimulation

Solve a Rimu.PMCSimulation until the last step is completed or the wall time limit is reached.

To continue a previously completed simulation, set a new last_step or wall_time using the keyword arguments. Optionally, changes can be made to the replica_strategy, the post_step_strategy, or the reporting_strategy.

Optional keyword arguments:

  • last_step = nothing: Set the last step to a new value and continue the simulation.
  • wall_time = nothing: Set the allowed wall time to a new value and continue the simulation.
  • reset_time = false: Reset the elapsed_time counter and continue the simulation.
  • empty_report = false: Empty the report before continuing the simulation.
  • replica_strategy = nothing: Change the replica strategy. Requires the number of replicas to match the number of replicas in the simulation sm. Implies empty_report = true.
  • post_step_strategy = nothing: Change the post-step strategy. Implies empty_report = true.
  • reporting_strategy = nothing: Change the reporting strategy. Implies empty_report = true.
  • metadata = nothing: Add metadata to the report.

See also ProjectorMonteCarloProblem, init, solve, step!, Rimu.PMCSimulation.

source
Rimu.advance!Method
advance!(algorithm::PMCAlgorithm, report::Report, state::ReplicaState, s_state::SingleState)

Advance the s_state by one step according to the algorithm. The state is used only to access the various strategies involved. Steps, stats, and computed quantities are written to the report.

Returns true if the step was successful and calculation should proceed, false when it should terminate.

See also solve!, step!.

source
Rimu.all_overlapsMethod
all_overlaps(operators, vectors, working_memories, vecnorm=true)

Get all overlaps between vectors and operators. The flag vecnorm can disable the vector-vector overlap c{i}_dot_c{j}.

source
Rimu.clean_and_warn_if_others_presentMethod
clean_and_warn_if_others_present(nt::NamedTuple{names}, keys) where {names}

Remove keys from a NamedTuple that are not in keys and issue a warning if they are present.

source
Rimu.default_loggerMethod
default_logger(args...)

Reset the global_logger to Logging.ConsoleLogger. Undoes the effect of smart_logger. Arguments are passed on to Logging.ConsoleLogger.

source
Rimu.ShiftStrategyType
ShiftStrategy

Abstract type for defining the strategy for controlling the norm, potentially by updating the shift. Passed as a parameter to ProjectorMonteCarloProblem or to FCIQMC.

Implemented strategies:

Extended help

Internally To implement a custom strategy, define a new subtype of Rimu.ShiftStrategy and implement methods for:

source
Rimu.SignCoherenceType
SignCoherence(reference[; name=:coherence]) <: PostStepStrategy

After each step, compute the proportion of configurations that have the same sign as they do in the reference_dvec. Reports to a column named name, which defaults to coherence.

source
Rimu.SingleParticleDensityType
SingleParticleDensity(; save_every=1, component) <: PostStepStrategy

PostStepStrategy to compute the diagonal single_particle_density. It records a Tuple with the same eltype as the vector.

Computing the density at every time step can be expensive. This cost can be reduced by setting the save_every argument to a higher value. If the value is set, a vector of zeros is recorded when the saving is skipped.

If the address type has multiple components, the component argument can be used to compute the density on a per-component basis.

The density is not normalized, and must be divided by the vector norm(⋅,2) squared.

See also

source
Rimu.SingleStateType
SingleState(hamiltonian, algorithm, v, wm, pnorm, params, id)

Struct that holds a single state vector and all information needed for an independent run of the algorithm. Can be advanced a step forward with Rimu.advance!.

Fields

  • hamiltonian: Hamiltonian
  • algorithm: Algorithm
  • v: Vector
  • pv: Previous vector
  • wm: Working memory
  • shift_parameters: Shift parameters
  • id::String: id is appended to column names

See also SpectralStrategy, ReplicaStrategy, Rimu.SpectralState, Rimu.ReplicaState, Rimu.replica_stats, Rimu.PMCSimulation.

source
Rimu.SpectralStrategyType
SpectralStrategy{S}

Abstract type for spectral strategies. The spectral strategy is used to control the number of spectral states used in the simulation.

Implemented Strategies

  • GramSchmidt: Orthogonalize the spectral states using the Gram-Schmidt procedure.
source
Rimu.TimerType
Timer <: PostStepStrategy

Record current time after every step. See Base.Libc.time for information on what time is recorded.

source
Rimu.WalkerLonelinessType
WalkerLoneliness(threshold=1) <: PostStepStrategy

After each step, compute the proportion of configurations that are occupied by at most threshold walkers. Reports to a column named loneliness.

source
CommonSolve.solve!Method
solve!(sm::PMCSimulation; kwargs...)::PMCSimulation

Solve a Rimu.PMCSimulation until the last step is completed or the wall time limit is reached.

To continue a previously completed simulation, set a new last_step or wall_time using the keyword arguments. Optionally, changes can be made to the replica_strategy, the post_step_strategy, or the reporting_strategy.

Optional keyword arguments:

  • last_step = nothing: Set the last step to a new value and continue the simulation.
  • wall_time = nothing: Set the allowed wall time to a new value and continue the simulation.
  • reset_time = false: Reset the elapsed_time counter and continue the simulation.
  • empty_report = false: Empty the report before continuing the simulation.
  • replica_strategy = nothing: Change the replica strategy. Requires the number of replicas to match the number of replicas in the simulation sm. Implies empty_report = true.
  • post_step_strategy = nothing: Change the post-step strategy. Implies empty_report = true.
  • reporting_strategy = nothing: Change the reporting strategy. Implies empty_report = true.
  • metadata = nothing: Add metadata to the report.

See also ProjectorMonteCarloProblem, init, solve, step!, Rimu.PMCSimulation.

source
Rimu.advance!Method
advance!(algorithm::PMCAlgorithm, report::Report, state::ReplicaState, s_state::SingleState)

Advance the s_state by one step according to the algorithm. The state is used only to access the various strategies involved. Steps, stats, and computed quantities are written to the report.

Returns true if the step was successful and calculation should proceed, false when it should terminate.

See also solve!, step!.

source
Rimu.all_overlapsMethod
all_overlaps(operators, vectors, working_memories, vecnorm=true)

Get all overlaps between vectors and operators. The flag vecnorm can disable the vector-vector overlap c{i}_dot_c{j}.

source
Rimu.clean_and_warn_if_others_presentMethod
clean_and_warn_if_others_present(nt::NamedTuple{names}, keys) where {names}

Remove keys from a NamedTuple that are not in keys and issue a warning if they are present.

source
Rimu.default_loggerMethod
default_logger(args...)

Reset the global_logger to Logging.ConsoleLogger. Undoes the effect of smart_logger. Arguments are passed on to Logging.ConsoleLogger.

source
Rimu.default_starting_vectorMethod
default_starting_vector(hamiltonian::AbstractHamiltonian; kwargs...)
 default_starting_vector(
     address=starting_address(hamiltonian);
     style=IsDynamicSemistochastic(),
     initiator=NonInitiator(),
     threading=nothing,
     population=10
-)

Return a default starting vector for ProjectorMonteCarloProblem. The default choice for the starting vector is

v = PDVec(address => population; style, initiator)

if threading is available, or otherwise

v = DVec(address => population; style)

if initiator == NonInitiator(), and

v = InitiatorDVec(address => population; style, initiator)

if not. See PDVec, DVec, InitiatorDVec, StochasticStyle, and InitiatorRule.

source
Rimu.delete_and_warn_if_presentMethod
delete_and_warn_if_present(nt::NamedTuple, keys)

Delete keys from a NamedTuple and issue a warning if they are present. This is useful for removing unused keyword arguments.

source
Rimu.finalize_report!Method
finalize_report!(::ReportingStrategy, report)

Finalize the report. This function is called after all steps in solve! have finished.

source
Rimu.lomc!Method
lomc!(ham::AbstractHamiltonian, [v]; kwargs...) -> df, state
+)

Return a default starting vector for ProjectorMonteCarloProblem. The default choice for the starting vector is

v = PDVec(address => population; style, initiator)

if threading is available, or otherwise

v = DVec(address => population; style)

if initiator == NonInitiator(), and

v = InitiatorDVec(address => population; style, initiator)

if not. See PDVec, DVec, InitiatorDVec, StochasticStyle, and InitiatorRule.

source
Rimu.delete_and_warn_if_presentMethod
delete_and_warn_if_present(nt::NamedTuple, keys)

Delete keys from a NamedTuple and issue a warning if they are present. This is useful for removing unused keyword arguments.

source
Rimu.finalize_report!Method
finalize_report!(::ReportingStrategy, report)

Finalize the report. This function is called after all steps in solve! have finished.

source
Rimu.lomc!Method
lomc!(ham::AbstractHamiltonian, [v]; kwargs...) -> df, state
 lomc!(state::ReplicaState, [df]; kwargs...) -> df, state

Linear operator Monte Carlo: Perform a projector quantum Monte Carlo simulation for determining the lowest eigenvalue of ham. The details of the simulation are controlled by the optional keyword arguments and by the type of the optional starting vector v. Alternatively, a ReplicaState can be passed in to continue a previous simulation.

Common keyword arguments and defaults:

  • laststep = 100 - controls the number of steps.
  • dτ = 0.01 - time step.
  • targetwalkers = 1000 - target for the 1-norm of the coefficient vector.
  • address = starting_address(ham) - set starting address for default v and shift.
  • style = IsStochasticInteger() - set StochasticStyle for default v; unused if v is specified.
  • initiator = NonInitiator() - set InitiatorRule for default v; unused if v is specified.
  • threading - default is to use multithreading and MPI if multiple threads are available. Set to true to force PDVec for the starting vector, false for serial computation; unused if v is specified.
  • shift = diagonal_element(ham, address) - initial value of shift.
  • post_step_strategy::NTuple{N,<:PostStepStrategy} = () - extract observables (e.g. ProjectedEnergy), see PostStepStrategy. (Deprecated: post_step is accepted as an alias for post_step_strategy.)
  • replica_strategy::ReplicaStrategy = NoStats(1) - run several synchronised simulations, see ReplicaStrategy. (Deprecated: replica is accepted as an alias for replica_strategy.)
  • reporting_strategy::ReportingStrategy = ReportDFAndInfo() - how and when to report results, see ReportingStrategy. (Deprecated: r_strat is accepted as an alias for reporting_strategy.)
  • name = "lomc!" - name displayed in progress bar (via ProgressLogging)
  • metadata - user-supplied metadata to be added to the report df. Must be an iterable of pairs or a NamedTuple, e.g. metadata = ("key1" => "value1", "key2" => "value2"). All metadata is converted to strings.

Some metadata is automatically added to the report df including Rimu.PACKAGE_VERSION and data from state.

Return values

lomc! returns a named tuple with the following fields:

  • df: a DataFrame with all statistics being reported.
  • state: a ReplicaState that can be used for continuations.

Example

julia> address = BoseFS(1,2,3);
 
 julia> hamiltonian = HubbardReal1D(address);
@@ -52,12 +52,12 @@
 "cont"
 
 julia> metadata(df2, "hamiltonian") # some metadata is automatically added
-"HubbardReal1D(fs\"|1 2 3⟩\"; u=1.0, t=1.0)"

Further keyword arguments and defaults:

  • τ_strat::TimeStepStrategy = ConstantTimeStep() - adjust time step or not, see TimeStepStrategy
  • s_strat::ShiftStrategy = DoubleLogUpdate(; target_walkers=targetwalkers, ζ = 0.08, ξ = ζ^2/4) - how to update the shift, see ShiftStrategy.
  • maxlength = 2 * s_strat.target_walkers + 100 - upper limit on the length of v; when reached, lomc! will abort
  • wm - working memory for re-use in subsequent calculations; is mutated.
  • df = DataFrame() - when called with AbstractHamiltonian argument, a DataFrame can be passed for merging with the report df.

The default choice for the starting vector is v = default_starting_vector(; address, style, threading, initiator). See default_starting_vector, PDVec, DVec, StochasticStyle, and InitiatorRule.

Warning

The use of this lomc! is deprecated. Use ProjectorMonteCarloProblem and solve instead.

source
Rimu.mpi_allprintlnMethod
mpi_allprintln(args...)

Print a message to stdout from each rank separately, in order. MPI synchronizing.

source
Rimu.mpi_barrierFunction
mpi_barrier(comm = mpi_comm())

The MPI barrier with optional argument. MPI syncronizing.

source
Rimu.mpi_seed!Function
mpi_seed!(seed = rand(Random.RandomDevice(), UInt))

Re-seed the random number generators in an MPI-safe way. If seed is provided, the random numbers from rand will follow a deterministic sequence.

Independence of the random number generators on different MPI ranks is achieved by adding hash(mpi_rank()) to seed.

source
Rimu.num_replicasMethod
num_replicas(state_or_strategy)

Return the number of replicas used in the simulation.

source
Rimu.refine_reporting_strategyMethod
refine_reporting_strategy(reporting_strategy::ReportingStrategy) -> reporting_strategy

Initialize the reporting strategy. This can be used to set up filenames or other attributes that need to be unique for a run of FCIQMC.

source
Rimu.replace_keysMethod
replace_keys(nt::NamedTuple, (:old1 => :new1, :old2 => :new2, ...))

Replace keys in a NamedTuple with new keys. This is useful for renaming fields in a NamedTuple. Ignores keys that are not present in the NamedTuple.

source
Rimu.replica_statsFunction
replica_stats(RS::ReplicaStrategy{N}, spectral_states::NTuple{N,SingleState}) -> (names, values)

Return the names and values of statistics related to N replica states consistent with the ReplicaStrategy RS. names should be a tuple of Symbols or Strings and values should be a tuple of the same length. This function will be called every reporting_interval steps from ProjectorMonteCarloProblem, or once per time step if reporting_interval is not defined.

Part of the ReplicaStrategy interface. See also SingleState.

source
Rimu.report!Method
 report!(::ReportingStrategy, step, report::Report, keys, values, id="")
- report!(::ReportingStrategy, step, report::Report, nt, id="")

Report keys and values to report, which will be converted to a DataFrame before ProjectorMonteCarloProblem exits. Alternatively, a nt::NamedTuple can be passed in place of keys and values. If id is specified, it is appended to all keys. This is used to differentiate between values reported by different replicas.

To overload this function for a new ReportingStrategy, overload report!(::ReportingStrategy, step, args...) and apply the report by calling report!(args...).

source
Rimu.report!Method
report!(report::Report, df::DataFrame)

Convert the DataFrame df to a Report. This function does not copy the data.

source
Rimu.report!Method
report!(report, keys, values, id="")
-report!(report, pairs, id="")

Write keys, values pairs to report that will be converted to a DataFrame later. Alternatively, a named tuple or a collection of pairs can be passed instead of keys and values.

The value of id is appended to the name of the column, e.g. report!(report, :key, value, :_1) will report value to a column named :key_1.

source
Rimu.report_metadata!Method
report_metadata!(report::Report, key, value)
-report_metadata!(report::Report, kvpairs)

Set metadata key to value in report. key and value are converted to Strings. Alternatively, an iterable of key-value pairs or a NamedTuple can be passed.

See also get_metadata, report!, Report.

source
Rimu.reporting_intervalMethod
reporting_interval(::ReportingStrategy)

Get the interval between steps for which non-essential statistics are reported. Defaults to 1 if chosen ReportingStrategy does not specify an interval.

source
Rimu.set_up_initial_shift_parametersMethod
set_up_initial_shift_parameters(
+"HubbardReal1D(fs\"|1 2 3⟩\"; u=1.0, t=1.0)"

Further keyword arguments and defaults:

  • τ_strat::TimeStepStrategy = ConstantTimeStep() - adjust time step or not, see TimeStepStrategy
  • s_strat::ShiftStrategy = DoubleLogUpdate(; target_walkers=targetwalkers, ζ = 0.08, ξ = ζ^2/4) - how to update the shift, see ShiftStrategy.
  • maxlength = 2 * s_strat.target_walkers + 100 - upper limit on the length of v; when reached, lomc! will abort
  • wm - working memory for re-use in subsequent calculations; is mutated.
  • df = DataFrame() - when called with AbstractHamiltonian argument, a DataFrame can be passed for merging with the report df.

The default choice for the starting vector is v = default_starting_vector(; address, style, threading, initiator). See default_starting_vector, PDVec, DVec, StochasticStyle, and InitiatorRule.

Warning

The use of this lomc! is deprecated. Use ProjectorMonteCarloProblem and solve instead.

source
Rimu.mpi_allprintlnMethod
mpi_allprintln(args...)

Print a message to stdout from each rank separately, in order. MPI synchronizing.

source
Rimu.mpi_barrierFunction
mpi_barrier(comm = mpi_comm())

The MPI barrier with optional argument. MPI syncronizing.

source
Rimu.mpi_seed!Function
mpi_seed!(seed = rand(Random.RandomDevice(), UInt))

Re-seed the random number generators in an MPI-safe way. If seed is provided, the random numbers from rand will follow a deterministic sequence.

Independence of the random number generators on different MPI ranks is achieved by adding hash(mpi_rank()) to seed.

source
Rimu.num_replicasMethod
num_replicas(state_or_strategy)

Return the number of replicas used in the simulation.

source
Rimu.refine_reporting_strategyMethod
refine_reporting_strategy(reporting_strategy::ReportingStrategy) -> reporting_strategy

Initialize the reporting strategy. This can be used to set up filenames or other attributes that need to be unique for a run of FCIQMC.

source
Rimu.replace_keysMethod
replace_keys(nt::NamedTuple, (:old1 => :new1, :old2 => :new2, ...))

Replace keys in a NamedTuple with new keys. This is useful for renaming fields in a NamedTuple. Ignores keys that are not present in the NamedTuple.

source
Rimu.replica_statsFunction
replica_stats(RS::ReplicaStrategy{N}, spectral_states::NTuple{N,SingleState}) -> (names, values)

Return the names and values of statistics related to N replica states consistent with the ReplicaStrategy RS. names should be a tuple of Symbols or Strings and values should be a tuple of the same length. This function will be called every reporting_interval steps from ProjectorMonteCarloProblem, or once per time step if reporting_interval is not defined.

Part of the ReplicaStrategy interface. See also SingleState.

source
Rimu.report!Method
 report!(::ReportingStrategy, step, report::Report, keys, values, id="")
+ report!(::ReportingStrategy, step, report::Report, nt, id="")

Report keys and values to report, which will be converted to a DataFrame before ProjectorMonteCarloProblem exits. Alternatively, a nt::NamedTuple can be passed in place of keys and values. If id is specified, it is appended to all keys. This is used to differentiate between values reported by different replicas.

To overload this function for a new ReportingStrategy, overload report!(::ReportingStrategy, step, args...) and apply the report by calling report!(args...).

source
Rimu.report!Method
report!(report::Report, df::DataFrame)

Convert the DataFrame df to a Report. This function does not copy the data.

source
Rimu.report!Method
report!(report, keys, values, id="")
+report!(report, pairs, id="")

Write keys, values pairs to report that will be converted to a DataFrame later. Alternatively, a named tuple or a collection of pairs can be passed instead of keys and values.

The value of id is appended to the name of the column, e.g. report!(report, :key, value, :_1) will report value to a column named :key_1.

source
Rimu.report_metadata!Method
report_metadata!(report::Report, key, value)
+report_metadata!(report::Report, kvpairs)

Set metadata key to value in report. key and value are converted to Strings. Alternatively, an iterable of key-value pairs or a NamedTuple can be passed.

See also get_metadata, report!, Report.

source
Rimu.reporting_intervalMethod
reporting_interval(::ReportingStrategy)

Get the interval between steps for which non-essential statistics are reported. Defaults to 1 if chosen ReportingStrategy does not specify an interval.

source
Rimu.set_up_initial_shift_parametersMethod
set_up_initial_shift_parameters(
     algorithm::FCIQMC, hamiltonian, starting_vectors, shift, time_step, initial_shift_parameters
-)

Set up the initial shift parameters for the FCIQMC algorithm.

source
Rimu.single_particle_densityMethod
single_particle_density(dvec; component)
 single_particle_density(add; component)

Compute the diagonal single particle density of vector dvec or address add. If the component argument is given, only that component of the addresses is taken into account. The result is always normalized so that sum(result) ≈ num_particles(address).

Examples

julia> v = DVec(fs"|⋅↑⇅↓⋅⟩" => 1.0, fs"|↓↓⋅↑↑⟩" => 0.5)
 DVec{FermiFS2C{2, 2, 5, 4, FermiFS{2, 5, BitString{5, 1, UInt8}}, FermiFS{2, 5, BitString{5, 1, UInt8}}},Float64} with 2 entries, style = IsDeterministic{Float64}()
   fs"|↓↓⋅↑↑⟩" => 0.5
@@ -67,8 +67,8 @@
 (0.2, 1.0, 1.6, 1.0, 0.2)
 
 julia> single_particle_density(v; component=1)
-(0.0, 0.8, 0.8, 0.2, 0.2)

See also

source
Rimu.smart_loggerMethod
smart_logger(args...)

Enable terminal progress bar during interactive use (i.e. unless running on CI or HPC). Arguments are passed on to the logger. This is run once during Rimu startup. Undo with default_logger or by setting Base.global_logger().

source
Rimu.state_vectorsMethod
state_vectors(state::ReplicaState)
-state_vectors(sim::PMCSimulation)

Return an r×s AbstractMatrix of configuration vectors from the state, or the result of solve(::ProjectorMonteCarloProblem). The vectors can be accessed by indexing the resulting collection, where the row index corresponds to the replica index and the column index corresponds to the spectral state index.

See also ProjectorMonteCarloProblem, Rimu.PMCSimulation, Rimu.SingleState, Rimu.ReplicaState, Rimu.SpectralState.

source
Rimu.smart_loggerMethod
smart_logger(args...)

Enable terminal progress bar during interactive use (i.e. unless running on CI or HPC). Arguments are passed on to the logger. This is run once during Rimu startup. Undo with default_logger or by setting Base.global_logger().

source
Rimu.state_vectorsMethod
state_vectors(state::ReplicaState)
+state_vectors(sim::PMCSimulation)

Return an r×s AbstractMatrix of configuration vectors from the state, or the result of solve(::ProjectorMonteCarloProblem). The vectors can be accessed by indexing the resulting collection, where the row index corresponds to the replica index and the column index corresponds to the spectral state index.

See also ProjectorMonteCarloProblem, Rimu.PMCSimulation, Rimu.SingleState, Rimu.ReplicaState, Rimu.SpectralState.

source
Rimu.update_time_stepMethod
update_time_step(s<:TimeStepStrategy, time_step, tnorm) -> new_time_step

Update the time step according to the strategy s.

source
Rimu.@mpi_rootMacro
@mpi_root expr

Evaluate expression only on the root rank. Extra care needs to be taken as expr must not contain any code that involves syncronising MPI operations, i.e. actions that would require syncronous action of all MPI ranks.

Example:

wn = walkernumber(dv)   # an MPI syncronising function call that gathers
+) -> shift_stats, proceed

Update the shift_parameters according to strategy s. See ShiftStrategy. Returns a named tuple of the shift statistics and a boolean proceed indicating whether the simulation should proceed.

See initialise_shift_parameters, ShiftStrategy.

source
Rimu.update_time_stepMethod
update_time_step(s<:TimeStepStrategy, time_step, tnorm) -> new_time_step

Update the time step according to the strategy s.

source
Rimu.@mpi_rootMacro
@mpi_root expr

Evaluate expression only on the root rank. Extra care needs to be taken as expr must not contain any code that involves syncronising MPI operations, i.e. actions that would require syncronous action of all MPI ranks.

Example:

wn = walkernumber(dv)   # an MPI syncronising function call that gathers
                         # information from all MPI ranks
-@mpi_root @info "The current walker number is" wn # print info message on root only
source

Reexported Submodules

ExactDiagonalization

See Exact Diagonalization

Interfaces

See Module Interfaces

StochasticStyles

See Module StochasticStyles

Hamiltonians

See Module Hamiltonians

BitStringAddresses

See Module BitStringAddresses

DictVectors

See Module DictVectors

StatsTools

See Module StatsTools

Index

+@mpi_root @info "The current walker number is" wn # print info message on root only
source

Reexported Submodules

ExactDiagonalization

See Exact Diagonalization

Interfaces

See Module Interfaces

StochasticStyles

See Module StochasticStyles

Hamiltonians

See Module Hamiltonians

BitStringAddresses

See Module BitStringAddresses

DictVectors

See Module DictVectors

StatsTools

See Module StatsTools

Index

diff --git a/previews/PR308/addresses.html b/previews/PR308/addresses.html index b18cbb38a..0a37f66dd 100644 --- a/previews/PR308/addresses.html +++ b/previews/PR308/addresses.html @@ -1,5 +1,5 @@ -BitString addresses · Rimu.jl

Module BitStringAddresses

This module contains the implementations of BitString and various Fock addresses. The addresses serve as a basis for a Hamiltonian.

While there are not restrictions on the type of address a Hamiltonian uses, Rimu provides implementations for Bosonic, Fermionic, and mixed Fock States.

When implementing a new address type, care must be taken to make them space-efficient and stack-allocated - avoid using (heap-allocated) arrays to represent your addresses at all costs!

Fock addresses

Rimu provides a variety of address implementations that should make it straightforward to implement efficient Hamiltonians. Examples are:

  • BoseFS Single-component bosonic Fock state with fixed particle and mode number.
  • FermiFS Single-component fermionic Fock state with fixed particle and mode number.
  • CompositeFS Multi-component Fock state composed of the above types.
  • OccupationNumberFS Single-component bosonic Fock state with a fixed number of modes. The number of particles is not part of the type and can be changed by operators.

Fock address API

Rimu.BitStringAddresses.BoseFSIndexType
BoseFSIndex

Struct used for indexing and performing excitations on a BoseFS.

Fields:

  • occnum: the occupation number.
  • mode: the index of the mode.
  • offset: the position of the mode in the address. This is the bit offset of the mode when

the address is represented by a bitstring, and the position in the list when it is represented by SortedParticleList.

source
Rimu.BitStringAddresses.FermiFSIndexType
FermiFSIndex

Struct used for indexing and performing excitations on a FermiFS.

Fields:

  • occnum: the occupation number.
  • mode: the index of the mode.
  • offset: the position of the mode in the address. This is mode - 1 when the address is represented by a bitstring, and the position in the list when using SortedParticleList.
source
Rimu.BitStringAddresses.OccupiedModeMapType
OccupiedModeMap(addr) <: AbstractVector

Get a map of occupied modes in address as an AbstractVector of indices compatible with excitation - BoseFSIndex or FermiFSIndex.

OccupiedModeMap(addr)[i] contains the index for the i-th occupied mode. This is useful because repeatedly looking for occupied modes with find_occupied_mode can be time-consuming. OccupiedModeMap(addr) is an eager version of the iterator returned by occupied_modes. It is similar to onr but contains more information.

Example

julia> b = BoseFS(10, 0, 0, 0, 2, 0, 1)
+BitString addresses · Rimu.jl

Module BitStringAddresses

This module contains the implementations of BitString and various Fock addresses. The addresses serve as a basis for a Hamiltonian.

While there are not restrictions on the type of address a Hamiltonian uses, Rimu provides implementations for Bosonic, Fermionic, and mixed Fock States.

When implementing a new address type, care must be taken to make them space-efficient and stack-allocated - avoid using (heap-allocated) arrays to represent your addresses at all costs!

Fock addresses

Rimu provides a variety of address implementations that should make it straightforward to implement efficient Hamiltonians. Examples are:

  • BoseFS Single-component bosonic Fock state with fixed particle and mode number.
  • FermiFS Single-component fermionic Fock state with fixed particle and mode number.
  • CompositeFS Multi-component Fock state composed of the above types.
  • OccupationNumberFS Single-component bosonic Fock state with a fixed number of modes. The number of particles is not part of the type and can be changed by operators.

Fock address API

Rimu.BitStringAddresses.BoseFSIndexType
BoseFSIndex

Struct used for indexing and performing excitations on a BoseFS.

Fields:

  • occnum: the occupation number.
  • mode: the index of the mode.
  • offset: the position of the mode in the address. This is the bit offset of the mode when

the address is represented by a bitstring, and the position in the list when it is represented by SortedParticleList.

source
Rimu.BitStringAddresses.FermiFSIndexType
FermiFSIndex

Struct used for indexing and performing excitations on a FermiFS.

Fields:

  • occnum: the occupation number.
  • mode: the index of the mode.
  • offset: the position of the mode in the address. This is mode - 1 when the address is represented by a bitstring, and the position in the list when using SortedParticleList.
source
Rimu.BitStringAddresses.OccupiedModeMapType
OccupiedModeMap(addr) <: AbstractVector

Get a map of occupied modes in address as an AbstractVector of indices compatible with excitation - BoseFSIndex or FermiFSIndex.

OccupiedModeMap(addr)[i] contains the index for the i-th occupied mode. This is useful because repeatedly looking for occupied modes with find_occupied_mode can be time-consuming. OccupiedModeMap(addr) is an eager version of the iterator returned by occupied_modes. It is similar to onr but contains more information.

Example

julia> b = BoseFS(10, 0, 0, 0, 2, 0, 1)
 BoseFS{13,7}(10, 0, 0, 0, 2, 0, 1)
 
 julia> mb = OccupiedModeMap(b)
@@ -26,7 +26,7 @@
 11
 
 julia> dot(mf, 1:20)
-17

See also dot, SingleComponentFockAddress.

source
Rimu.BitStringAddresses.OccupiedPairsMapType
OccupiedPairsMap(addr::SingleComponentFockAddress) <: AbstractVector

Get a map of all distinct pairs of indices in addr. Pairs involving multiply-occupied modes are counted once, (including self-pairing). This is useful for cases where identifying pairs of particles for eg. interactions is not well-defined or efficient to do on the fly. This is an eager iterator whose elements are a tuple of particle indices that can be given to excitation

Example

julia> addr = BoseFS(10, 0, 0, 0, 2, 0, 1)
+17

See also dot, SingleComponentFockAddress.

source
Rimu.BitStringAddresses.OccupiedPairsMapType
OccupiedPairsMap(addr::SingleComponentFockAddress) <: AbstractVector

Get a map of all distinct pairs of indices in addr. Pairs involving multiply-occupied modes are counted once, (including self-pairing). This is useful for cases where identifying pairs of particles for eg. interactions is not well-defined or efficient to do on the fly. This is an eager iterator whose elements are a tuple of particle indices that can be given to excitation

Example

julia> addr = BoseFS(10, 0, 0, 0, 2, 0, 1)
 BoseFS{13,7}(10, 0, 0, 0, 2, 0, 1)
 
 julia> pairs = OccupiedPairsMap(addr)
@@ -38,7 +38,7 @@
  (BoseFSIndex(occnum=1, mode=7, offset=18), BoseFSIndex(occnum=2, mode=5, offset=14))
 
 julia> excitation(addr, pairs[2], pairs[4])
-(BoseFS{13,7}(9, 0, 0, 0, 4, 0, 0), 10.954451150103322)

See also OccupiedModeMap.

source
Rimu.BitStringAddresses.SingleComponentFockAddressType
SingleComponentFockAddress{N,M} <: AbstractFockAddress{N,M}

A type representing a single component Fock state with N particles and M modes.

Implemented subtypes: BoseFS, FermiFS.

Supported functionality

See also CompositeFS, AbstractFockAddress.

source
Rimu.BitStringAddresses.excitationFunction
excitation(addr::SingleComponentFockAddress, creations::NTuple, destructions::NTuple)

Generate an excitation on address addr by applying creations and destructions, which are tuples of the appropriate address indices (i.e. BoseFSIndex for bosons, or FermiFSIndex for fermions).

\[a^†_{c_1} a^†_{c_2} \ldots a_{d_1} a_{d_2} \ldots |\mathrm{addr}\rangle \to +(BoseFS{13,7}(9, 0, 0, 0, 4, 0, 0), 10.954451150103322)

See also OccupiedModeMap.

source
Rimu.BitStringAddresses.SingleComponentFockAddressType
SingleComponentFockAddress{N,M} <: AbstractFockAddress{N,M}

A type representing a single component Fock state with N particles and M modes.

Implemented subtypes: BoseFS, FermiFS.

Supported functionality

See also CompositeFS, AbstractFockAddress.

source
Rimu.BitStringAddresses.excitationFunction
excitation(addr::SingleComponentFockAddress, creations::NTuple, destructions::NTuple)

Generate an excitation on address addr by applying creations and destructions, which are tuples of the appropriate address indices (i.e. BoseFSIndex for bosons, or FermiFSIndex for fermions).

\[a^†_{c_1} a^†_{c_2} \ldots a_{d_1} a_{d_2} \ldots |\mathrm{addr}\rangle \to α|\mathrm{naddr}\rangle\]

Returns the new address naddr and the factor α. The value of α is given by the square root of the product of mode occupations before destruction and after creation. If the excitation is illegal, returns an arbitrary address and the value 0.0.

Example

julia> f = FermiFS(1,1,0,0,1,1,1,1)
 FermiFS{6,8}(1, 1, 0, 0, 1, 1, 1, 1)
 
@@ -46,11 +46,11 @@
 (FermiFSIndex(occnum=0, mode=3, offset=2), FermiFSIndex(occnum=0, mode=4, offset=3), FermiFSIndex(occnum=1, mode=2, offset=1), FermiFSIndex(occnum=1, mode=5, offset=4))
 
 julia> excitation(f, (i,j), (k,l))
-(FermiFS{6,8}(1, 0, 1, 1, 0, 1, 1, 1), -1.0)

See SingleComponentFockAddress.

source
Rimu.BitStringAddresses.find_occupied_modeFunction
find_occupied_mode(::SingleComponentFockAddress, k)
 find_occupied_mode(::BoseFS, k, [n])

Find the k-th occupied mode in address (with at least n particles). Returns BoseFSIndex for BoseFS, and FermiFSIndex for FermiFS. When unsuccessful it returns a zero index.

Example

julia> find_occupied_mode(FermiFS(1, 1, 1, 0), 2)
 FermiFSIndex(occnum=1, mode=2, offset=1)
 
@@ -58,13 +58,13 @@
 BoseFSIndex(occnum=1, mode=1, offset=0)
 
 julia> find_occupied_mode(BoseFS(1, 0, 2), 1, 2)
-BoseFSIndex(occnum=2, mode=3, offset=3)

See also occupied_modes, OccupiedModeMap, SingleComponentFockAddress.

source
Rimu.BitStringAddresses.occupied_modesFunction
occupied_modes(::SingleComponentFockAddress)

Return a lazy iterator over all occupied modes in an address. Iterates over BoseFSIndexs for BoseFS, and over FermiFSIndexs for FermiFS. See OccupiedModeMap for an eager version.

Example

julia> b = BoseFS((1,5,0,4));
 
 julia> foreach(println, occupied_modes(b))
 BoseFSIndex(occnum=1, mode=1, offset=0)
@@ -75,8 +75,8 @@
 FermiFSIndex(occnum=1, mode=1, offset=0)
 FermiFSIndex(occnum=1, mode=2, offset=1)
 FermiFSIndex(occnum=1, mode=4, offset=3)
-FermiFSIndex(occnum=1, mode=7, offset=6)

See also find_occupied_mode, SingleComponentFockAddress.

source
Rimu.BitStringAddresses.onrFunction
occupation_number_representation(fs::SingleComponentFockAddress)
-onr(fs::SingleComponentFockAddress)

Compute and return the occupation number representation of the Fock state fs as an SVector{M}, where M is the number of modes.

source
Rimu.BitStringAddresses.onrFunction
occupation_number_representation(fs::SingleComponentFockAddress)
+onr(fs::SingleComponentFockAddress)

Compute and return the occupation number representation of the Fock state fs as an SVector{M}, where M is the number of modes.

source
Rimu.BitStringAddresses.@fs_strMacro
fs"$(string)"

Parse the compact representation of a Fock state. Useful for copying the printout from a vector to the REPL.

Example

julia> DVec(BoseFS{3,4}(0, 1, 2, 0) => 1)
 DVec{BoseFS{3, 4, BitString{6, 1, UInt8}},Int64} with 1 entry, style = IsStochasticInteger{Int64}()
   fs"|0 1 2 0⟩" => 1
 
@@ -100,10 +100,10 @@
 
 julia> [s] # prints out with the signifcant number of bits specified in braces
 1-element Vector{OccupationNumberFS{4, UInt8}}:
- fs"|0 1 2 0⟩{8}"

See also FermiFS, BoseFS, CompositeFS, FermiFS2C, OccupationNumberFS.

source
Rimu.BitStringAddresses.BoseFSType
BoseFS{N,M,S} <: SingleComponentFockAddress

Address type that represents a Fock state of N spinless bosons in M modes by wrapping a BitString, or a SortedParticleList. Which is wrapped is chosen automatically based on the properties of the address.

Constructors

  • BoseFS{[N,M]}(val::Integer...): Create BoseFS{N,M} from occupation numbers. This is type-stable if the number of modes M and the number of particles N are provided. Otherwise, M and N are inferred from the arguments.

  • BoseFS{[N,M]}(onr): Create BoseFS{N,M} from occupation number representation, see onr. This is efficient if N and M are provided, and onr is a statically-sized collection, such as a Tuple or SVector.

  • BoseFS{[N,M]}([M, ]pairs...): Provide the number of modes M and mode => occupation_number pairs. If M is provided as a type parameter, it should not be provided as the first argument. Useful for creating sparse addresses. pairs can be multiple arguments or an iterator of pairs.

  • BoseFS{N,M,S}(bs::S): Unsafe constructor. Does not check whether the number of particles in bs is equal to N.

  • @fs_str: Addresses are sometimes printed in a compact manner. This representation can also be used as a constructor. See the last example below.

Examples

julia> BoseFS{6,5}(0, 1, 2, 3, 0)
+ fs"|0 1 2 0⟩{8}"

See also FermiFS, BoseFS, CompositeFS, FermiFS2C, OccupationNumberFS.

source
Rimu.BitStringAddresses.BoseFSType
BoseFS{N,M,S} <: SingleComponentFockAddress

Address type that represents a Fock state of N spinless bosons in M modes by wrapping a BitString, or a SortedParticleList. Which is wrapped is chosen automatically based on the properties of the address.

Constructors

  • BoseFS{[N,M]}(val::Integer...): Create BoseFS{N,M} from occupation numbers. This is type-stable if the number of modes M and the number of particles N are provided. Otherwise, M and N are inferred from the arguments.

  • BoseFS{[N,M]}(onr): Create BoseFS{N,M} from occupation number representation, see onr. This is efficient if N and M are provided, and onr is a statically-sized collection, such as a Tuple or SVector.

  • BoseFS{[N,M]}([M, ]pairs...): Provide the number of modes M and mode => occupation_number pairs. If M is provided as a type parameter, it should not be provided as the first argument. Useful for creating sparse addresses. pairs can be multiple arguments or an iterator of pairs.

  • BoseFS{N,M,S}(bs::S): Unsafe constructor. Does not check whether the number of particles in bs is equal to N.

  • @fs_str: Addresses are sometimes printed in a compact manner. This representation can also be used as a constructor. See the examples below.

Examples

julia> BoseFS{6,5}(0, 1, 2, 3, 0)
 BoseFS{6,5}(0, 1, 2, 3, 0)
 
-julia> BoseFS([abs(i - 3) ≤ 1 ? i - 1 : 0 for i in 1:5])
+julia> BoseFS(abs(i - 3) ≤ 1 ? i - 1 : 0 for i in 1:5)
 BoseFS{6,5}(0, 1, 2, 3, 0)
 
 julia> BoseFS(5, 2 => 1, 3 => 2, 4 => 3)
@@ -116,10 +116,10 @@
 BoseFS{6,5}(0, 1, 2, 3, 0)
 
 julia> fs"|b 5: 2 3 3 4 4 4⟩"
-BoseFS{6,5}(0, 1, 2, 3, 0)

See also: SingleComponentFockAddress, OccupationNumberFS, FermiFS, CompositeFS, FermiFS2C.

source
Rimu.BitStringAddresses.bose_hubbard_interactionMethod
bose_hubbard_interaction(address)

Return $Σ_i n_i (n_i-1)$ for computing the Bose-Hubbard on-site interaction (without the $U$ prefactor.)

Example

julia> Hamiltonians.bose_hubbard_interaction(BoseFS{4,4}((2,1,1,0)))
 2
 julia> Hamiltonians.bose_hubbard_interaction(BoseFS{4,4}((3,0,1,0)))
-6
source
Rimu.BitStringAddresses.hopnextneighbourMethod
new_address, value = hopnextneighbour(add, chosen, boundary_condition)

Compute the new address of a hopping event for the Hubbard model. Returns the new address and the square root of product of occupation numbers of the involved modes multiplied by a term consistent with boundary condition as the value. The following boundary conditions are supported:

  • :periodic: hopping over the boundary gives does not change the value.
  • :twisted: hopping over the boundary flips the sign of the value.
  • :hard_wall: hopping over the boundary gives a value of zero.
  • θ <: Number: hopping over the boundary gives a value multiplied by $\exp(iθ)$ or $\exp(−iθ)$ depending on the direction of hopping.

The off-diagonals are indexed as follows:

  • (chosen + 1) ÷ 2 selects the hopping site.
  • Even chosen indicates a hop to the left.
  • Odd chosen indicates a hop to the right.

Example

julia> using Rimu.Hamiltonians: hopnextneighbour
+6
source
Rimu.BitStringAddresses.hopnextneighbourMethod
new_address, value = hopnextneighbour(add, chosen, boundary_condition)

Compute the new address of a hopping event for the Hubbard model. Returns the new address and the square root of product of occupation numbers of the involved modes multiplied by a term consistent with boundary condition as the value. The following boundary conditions are supported:

  • :periodic: hopping over the boundary gives does not change the value.
  • :twisted: hopping over the boundary flips the sign of the value.
  • :hard_wall: hopping over the boundary gives a value of zero.
  • θ <: Number: hopping over the boundary gives a value multiplied by $\exp(iθ)$ or $\exp(−iθ)$ depending on the direction of hopping.

The off-diagonals are indexed as follows:

  • (chosen + 1) ÷ 2 selects the hopping site.
  • Even chosen indicates a hop to the left.
  • Odd chosen indicates a hop to the right.

Example

julia> using Rimu.Hamiltonians: hopnextneighbour
 
 julia> hopnextneighbour(BoseFS(1, 0, 1), 3)
 (BoseFS{2,3}(2, 0, 0), 1.4142135623730951)
@@ -134,11 +134,11 @@
 (BoseFS{2,3}(2, 0, 0), 0.0)
 
 julia> hopnextneighbour(BoseFS(1, 0, 1), 3, π/4)
-(BoseFS{2,3}(2, 0, 0), 1.0000000000000002 + 1.0im)
source
Rimu.BitStringAddresses.near_uniformMethod
near_uniform(BoseFS{N,M}) -> BoseFS{N,M}

Create bosonic Fock state with near uniform occupation number of M modes with a total of N particles.

Examples

julia> near_uniform(BoseFS{7,5})
+(BoseFS{2,3}(2, 0, 0), 1.0000000000000002 + 1.0im)
source
Rimu.BitStringAddresses.near_uniformMethod
near_uniform(BoseFS{N,M}) -> BoseFS{N,M}

Create bosonic Fock state with near uniform occupation number of M modes with a total of N particles.

Examples

julia> near_uniform(BoseFS{7,5})
 BoseFS{7,5}(2, 2, 1, 1, 1)
 
 julia> near_uniform(FermiFS{3,5})
-FermiFS{3,5}(1, 1, 1, 0, 0)
source
Rimu.BitStringAddresses.FermiFSType
FermiFS{N,M,S} <: SingleComponentFockAddress

Address type that represents a Fock state of N fermions of the same spin in M modes by wrapping a BitString, or a SortedParticleList. Which is wrapped is chosen automatically based on the properties of the address.

Constructors

  • FermiFS{[N,M]}(val::Integer...): Create FermiFS{N,M} from occupation numbers. This is type-stable if the number of modes M and the number of particles N are provided. Otherwise, M and N are inferred from the arguments.

  • FermiFS{[N,M]}(onr): Create FermiFS{N,M} from occupation number representation, see onr. This is efficient if N and M are provided, and onr is a statically-sized collection, such as a Tuple{M} or SVector{M}.

  • FermiFS{[N,M]}([M, ]pairs...): Provide the number of modes M and pairs of the form mode => 1. If M is provided as a type parameter, it should not be provided as the first argument. Useful for creating sparse addresses. pairs can be multiple arguments or an iterator of pairs.

  • FermiFS{N,M,S}(bs::S): Unsafe constructor. Does not check whether the number of particles in bs is equal to N, or whether each mode only contains one particle.

  • @fs_str: Addresses are sometimes printed in a compact manner. This representation can also be used as a constructor. See the last example below.

Examples

julia> FermiFS{3,5}(0, 1, 1, 1, 0)
+FermiFS{3,5}(1, 1, 1, 0, 0)
source
Rimu.BitStringAddresses.FermiFSType
FermiFS{N,M,S} <: SingleComponentFockAddress

Address type that represents a Fock state of N fermions of the same spin in M modes by wrapping a BitString, or a SortedParticleList. Which is wrapped is chosen automatically based on the properties of the address.

Constructors

  • FermiFS{[N,M]}(val::Integer...): Create FermiFS{N,M} from occupation numbers. This is type-stable if the number of modes M and the number of particles N are provided. Otherwise, M and N are inferred from the arguments.

  • FermiFS{[N,M]}(onr): Create FermiFS{N,M} from occupation number representation, see onr. This is efficient if N and M are provided, and onr is a statically-sized collection, such as a Tuple{M} or SVector{M}.

  • FermiFS{[N,M]}([M, ]pairs...): Provide the number of modes M and pairs of the form mode => 1. If M is provided as a type parameter, it should not be provided as the first argument. Useful for creating sparse addresses. pairs can be multiple arguments or an iterator of pairs.

  • FermiFS{N,M,S}(bs::S): Unsafe constructor. Does not check whether the number of particles in bs is equal to N, or whether each mode only contains one particle.

  • @fs_str: Addresses are sometimes printed in a compact manner. This representation can also be used as a constructor. See the examples below.

Examples

julia> FermiFS{3,5}(0, 1, 1, 1, 0)
 FermiFS{3,5}(0, 1, 1, 1, 0)
 
 julia> FermiFS([abs(i - 3) ≤ 1 for i in 1:5])
@@ -154,7 +154,7 @@
 FermiFS{3,5}(0, 1, 1, 1, 0)
 
 julia> fs"|f 5: 2 3 4⟩"
-FermiFS{3,5}(0, 1, 1, 1, 0)

See also: SingleComponentFockAddress, BoseFS, CompositeFS, FermiFS2C, BitString, OccupationNumberFS.

source
Rimu.BitStringAddresses.FermiFS2CType
FermiFS2C <: AbstractFockAddress
 FermiFS2C(onr_a, onr_b)

Fock state address with two fermionic (spin) components. Alias for CompositeFS with two FermiFS components. Construct by specifying either two compatible FermiFSs, two onrs, or the number of modes followed by mode => occupation_number pairs, where occupation_number=1 will put a particle in the first component and occupation_number=-1 will put a particle in the second component. See examples below.

Examples

julia> FermiFS2C(FermiFS(1,0,0), FermiFS(0,1,1))
 CompositeFS(
   FermiFS{1,3}(1, 0, 0),
@@ -177,7 +177,7 @@
 CompositeFS(
   FermiFS{1,3}(1, 0, 0),
   FermiFS{2,3}(0, 1, 1),
-)
source
Rimu.BitStringAddresses.time_reverseMethod
time_reverse(addr)

Apply the time-reversal operation on a two-component Fock address that flips all the spins.

Requires each component address to have the same type.

source
Rimu.BitStringAddresses.OccupationNumberFSType
OccupationNumberFS{M,T} <: SingleComponentFockAddress

Address type that stores the occupation numbers of a single component bosonic Fock state with M modes. The occupation numbers must fit into the type T <: Unsigned. The number of particles is runtime data, and can be retrieved with num_particles(address).

Constructors

  • OccupationNumberFS(val::Integer...): Construct from occupation numbers. Must be < 256 to fit into UInt8.
  • OccupationNumberFS{[M,T]}(onr): Construct from collection onr with M occupation numbers with type T. If unspecified, the type T of the occupation numbers is inferred from the type of the arguments.
  • OccupationNumberFS{M[,T]}(onr): Construct a vacuum state with M modes. If T is unspecified, UInt8 is used.
  • OccupationNumberFS(fs::BoseFS): Construct from BoseFS.
  • With shortform macro @fs_str. Specify the number of significant bits in braces. See example below.

Examples

julia> ofs = OccupationNumberFS(1,2,3)
+)
source
Rimu.BitStringAddresses.time_reverseMethod
time_reverse(addr)

Apply the time-reversal operation on a two-component Fock address that flips all the spins.

Requires each component address to have the same type.

source
Rimu.BitStringAddresses.OccupationNumberFSType
OccupationNumberFS{M,T} <: SingleComponentFockAddress

Address type that stores the occupation numbers of a single component bosonic Fock state with M modes. The occupation numbers must fit into the type T <: Unsigned. The number of particles is runtime data, and can be retrieved with num_particles(address).

Constructors

  • OccupationNumberFS(val::Integer...): Construct from occupation numbers. Must be < 256 to fit into UInt8.
  • OccupationNumberFS{[M,T]}(onr): Construct from collection onr with M occupation numbers with type T. If unspecified, the type T of the occupation numbers is inferred from the type of the arguments.
  • OccupationNumberFS{M[,T]}(): Construct a vacuum state with M modes. If T is unspecified, UInt8 is used.
  • OccupationNumberFS(fs::BoseFS): Construct from BoseFS.
  • With shortform macro @fs_str. Specify the number of significant bits in braces. See example below.

Examples

julia> ofs = OccupationNumberFS(1,2,3)
 OccupationNumberFS{3, UInt8}(1, 2, 3)
 
 julia> ofs == fs"|1 2 3⟩{8}"
@@ -187,7 +187,13 @@
 6
 
 julia> OccupationNumberFS{5}() # vacuum state with 5 modes
-OccupationNumberFS{5, UInt8}(0, 0, 0, 0, 0)
source
Rimu.BitStringAddresses.excitationMethod
excitation(addr::OccupationNumberFS, c::NTuple, d::NTuple)
+OccupationNumberFS{5, UInt8}(0, 0, 0, 0, 0)
+
+julia> OccupationNumberFS(i for i in 1:3) # use list comprehension
+OccupationNumberFS{3, UInt8}(1, 2, 3)
+
+julia> OccupationNumberFS(4, 1=>2, 3=>4) # sparse constructor
+OccupationNumberFS{4, UInt8}(2, 0, 4, 0)
source
Rimu.BitStringAddresses.excitationMethod
excitation(addr::OccupationNumberFS, c::NTuple, d::NTuple)
 → (nadd, α)

Generate an excitation on an OccupationNumberFS by applying the creation and destruction operators specified by the tuples of mode numbers c and d to the Fock state addr. The modes are indexed by integers (starting at 1), or by indices of type BoseFSIndex. The value of α is given by the square root of the product of mode occupations before destruction and after creation.

The number of particles may change by this type of excitation.

Example

julia> s = fs"|1 2 3⟩{8}"
 OccupationNumberFS{3, UInt8}(1, 2, 3)
 
@@ -198,4 +204,4 @@
 (OccupationNumberFS{3, UInt8}(3, 2, 2), 4.242640687119285)
 
 julia> num_particles(es)
-7
source

Internal representations

The atomic addresses, BoseFS and FermiFS, are implemented as either bitstrings or sorted lists of particles. Using these approaches over an occupation number representation makes the addresses much more space-efficient.

Therewhile OccupationNumberFS internally uses the occupation number representation, which allows it to handle excitation operations that change the particle number. This is fast but requires more storage space.

Internal APIs

Rimu.BitStringAddresses.BitStringType
BitString{B,N,T<:Unsigned}

Type for storing bitstrings of static size. Holds B bits in N chunks, where each chunk is of type T.

N is chosen automatically to accommodate B bits as efficiently as possible.

Constructors

  • BitString{B,N,T}(::SVector{N,T}): unsafe constructor. Does not check for ghost bits.

  • BitString{B,N,T}(i::T): as above, but sets i as the rightmost chunk.

  • BitString{B}(::Integer): Convert integer to BitString. Integer is truncated to the correct number of bits.

source
Rimu.BitStringAddresses.SortedParticleListType
SortedParticleList{N,M,T<:Unsigned}

Type for storing sparse Fock states. Stores the mode number of each particle as an entry with only its mode stored. The entries are always kept sorted.

Iterating over SortedParticleLists yields occupied modes as a tuple of occupation number, mode number, and position in list.

Constructors

  • SortedParticleList{N,M,T}(::SVector{N,T}): unsafe constructor. Does not sort input.

  • SortedParticleList(arr::AbstractVector): convert ONR to SortedParticleList

source

Index

+7
source

Internal representations

The atomic addresses, BoseFS and FermiFS, are implemented as either bitstrings or sorted lists of particles. Using these approaches over an occupation number representation makes the addresses much more space-efficient.

Therewhile OccupationNumberFS internally uses the occupation number representation, which allows it to handle excitation operations that change the particle number. This is fast but requires more storage space.

Internal APIs

Rimu.BitStringAddresses.BitStringType
BitString{B,N,T<:Unsigned}

Type for storing bitstrings of static size. Holds B bits in N chunks, where each chunk is of type T.

N is chosen automatically to accommodate B bits as efficiently as possible.

Constructors

  • BitString{B,N,T}(::SVector{N,T}): unsafe constructor. Does not check for ghost bits.

  • BitString{B,N,T}(i::T): as above, but sets i as the rightmost chunk.

  • BitString{B}(::Integer): Convert integer to BitString. Integer is truncated to the correct number of bits.

source
Rimu.BitStringAddresses.SortedParticleListType
SortedParticleList{N,M,T<:Unsigned}

Type for storing sparse Fock states. Stores the mode number of each particle as an entry with only its mode stored. The entries are always kept sorted.

Iterating over SortedParticleLists yields occupied modes as a tuple of occupation number, mode number, and position in list.

Constructors

  • SortedParticleList{N,M,T}(::SVector{N,T}): unsafe constructor. Does not sort input.

  • SortedParticleList(arr::AbstractVector): convert ONR to SortedParticleList

source

Index

diff --git a/previews/PR308/custom_hamiltonians.html b/previews/PR308/custom_hamiltonians.html index 2d3f95202..585f38f3c 100644 --- a/previews/PR308/custom_hamiltonians.html +++ b/previews/PR308/custom_hamiltonians.html @@ -1,5 +1,5 @@ -Custom Hamiltonians · Rimu.jl

Advanced operator usage and custom Hamiltonians

Rimu can be used to work with custom Hamiltonians and observables that are user-defined and not part of the Rimu.jl package. To make this possible and reliable, Rimu exposes a number of interfaces and provides helper functions to test compliance with the interfaces through the submodule Rimu.InterfaceTests, see Interface tests. This section covers the relevant interfaces, the interface functions as well as potentially useful helper functions.

In order to define custom Hamiltonians or observables it is useful to know how the operator type hierarchy works in Rimu. For an example of how to implement custom Hamiltonians that are not part of the Rimu.jl package, see RimuLegacyHamiltonians.jl.

Operator type hierarchy

Rimu offers a hierarchy of abstract types that define interfaces with different requirements for operators:

AbstractHamiltonian <: AbstractOperator <: AbstractObservable

The different abstract types have different requirements and are meant to be used for different purposes.

Hamiltonians interface

Behind the implementation of a particular model is a more abstract interface for defining Hamiltonians. If you want to define a new model you should make use of this interface. A new model Hamiltonian should subtype to AbstractHamiltonian and implement the relevant methods.

Rimu.Interfaces.AbstractHamiltonianType
AbstractHamiltonian{T} <: AbstractOperator{T}

Supertype that provides an interface for linear operators over a linear space with scalar type T that are suitable for FCIQMC (with ProjectorMonteCarloProblem). Indexing is done with addresses (typically not integers) from an address space that may be large (and will not need to be completely generated).

AbstractHamiltonian instances operate on vectors of type AbstractDVec from the module DictVectors and work well with addresses of type AbstractFockAddress from the module BitStringAddresses. The type works well with the external package KrylovKit.jl.

For available implementations see Hamiltonians.

Interface

Basic interface methods to implement:

Optional additional methods to implement:

Provides the following functions and methods:

  • offdiagonals: iterator over reachable off-diagonal matrix elements
  • random_offdiagonal: function to generate random off-diagonal matrix element
  • *(H, v): deterministic matrix-vector multiply (allocating)
  • H(v): equivalent to H * v.
  • mul!(w, H, v): mutating matrix-vector multiply.
  • dot(x, H, v): compute x⋅(H*v) minimizing allocations.
  • H[address1, address2]: indexing with getindex() - mostly for testing purposes (slow!)
  • BasisSetRepresentation: construct a basis set repesentation
  • sparse, Matrix: construct a (sparse) matrix representation

Alternatively to the above, offdiagonals can be implemented instead of get_offdiagonal. Sometimes this can be done efficiently. In this case num_offdiagonals should provide an upper bound on the number of elements obtained when iterating offdiagonals.

See also Hamiltonians, Interfaces, AbstractOperator, AbstractObservable.

source
Rimu.Interfaces.offdiagonalsFunction
offdiagonals(h::AbstractHamiltonian, address)

Return an iterator over nonzero off-diagonal matrix elements of h in the same column as address. Will iterate over pairs (newaddress, matrixelement).

Example

julia> address = BoseFS(3,2,1);
+Custom Hamiltonians · Rimu.jl

Advanced operator usage and custom Hamiltonians

Rimu can be used to work with custom Hamiltonians and observables that are user-defined and not part of the Rimu.jl package. To make this possible and reliable, Rimu exposes a number of interfaces and provides helper functions to test compliance with the interfaces through the submodule Rimu.InterfaceTests, see Interface tests. This section covers the relevant interfaces, the interface functions as well as potentially useful helper functions.

In order to define custom Hamiltonians or observables it is useful to know how the operator type hierarchy works in Rimu. For an example of how to implement custom Hamiltonians that are not part of the Rimu.jl package, see RimuLegacyHamiltonians.jl.

Operator type hierarchy

Rimu offers a hierarchy of abstract types that define interfaces with different requirements for operators:

AbstractHamiltonian <: AbstractOperator <: AbstractObservable

The different abstract types have different requirements and are meant to be used for different purposes.

Hamiltonians interface

Behind the implementation of a particular model is a more abstract interface for defining Hamiltonians. If you want to define a new model you should make use of this interface. A new model Hamiltonian should subtype to AbstractHamiltonian and implement the relevant methods.

Rimu.Interfaces.AbstractHamiltonianType
AbstractHamiltonian{T} <: AbstractOperator{T}

Supertype that provides an interface for linear operators over a linear space with scalar type T that are suitable for FCIQMC (with ProjectorMonteCarloProblem). Indexing is done with addresses (typically not integers) from an address space that may be large (and will not need to be completely generated).

AbstractHamiltonian instances operate on vectors of type AbstractDVec from the module DictVectors and work well with addresses of type AbstractFockAddress from the module BitStringAddresses. The type works well with the external package KrylovKit.jl.

For available implementations see Hamiltonians.

Interface

Basic interface methods to implement:

Optional additional methods to implement:

Provides the following functions and methods:

  • offdiagonals: iterator over reachable off-diagonal matrix elements
  • random_offdiagonal: function to generate random off-diagonal matrix element
  • *(H, v): deterministic matrix-vector multiply (allocating)
  • H(v): equivalent to H * v.
  • mul!(w, H, v): mutating matrix-vector multiply.
  • dot(x, H, v): compute x⋅(H*v) minimizing allocations.
  • H[address1, address2]: indexing with getindex() - mostly for testing purposes (slow!)
  • BasisSetRepresentation: construct a basis set repesentation
  • sparse, Matrix: construct a (sparse) matrix representation

Alternatively to the above, offdiagonals can be implemented instead of get_offdiagonal. Sometimes this can be done efficiently. In this case num_offdiagonals should provide an upper bound on the number of elements obtained when iterating offdiagonals.

See also Hamiltonians, Interfaces, AbstractOperator, AbstractObservable.

source
Rimu.Interfaces.offdiagonalsFunction
offdiagonals(h::AbstractHamiltonian, address)

Return an iterator over nonzero off-diagonal matrix elements of h in the same column as address. Will iterate over pairs (newaddress, matrixelement).

Example

julia> address = BoseFS(3,2,1);
 
 
 julia> H = HubbardReal1D(address);
@@ -12,36 +12,36 @@
  (fs"|3 1 2⟩", -2.0)
  (fs"|4 1 1⟩", -2.8284271247461903)
  (fs"|4 2 0⟩", -2.0)
- (fs"|3 3 0⟩", -1.7320508075688772)

Part of the AbstractHamiltonian interface.

Extemded help

offdiagonals return and iterator of type <:AbstractOffdiagonals. It defaults to returning Offdiagonals(h, a)

See also Offdiagonals, AbstractOffdiagonals.

source
Rimu.Interfaces.diagonal_elementFunction
diagonal_element(ham, address)

Compute the diagonal matrix element of the linear operator ham at address address.

Example

julia> address = BoseFS((3, 2, 1));
+ (fs"|3 3 0⟩", -1.7320508075688772)

Part of the AbstractHamiltonian interface.

Extemded help

offdiagonals return and iterator of type <:AbstractOffdiagonals. It defaults to returning Offdiagonals(h, a)

See also Offdiagonals, AbstractOffdiagonals.

source
Rimu.Interfaces.diagonal_elementFunction
diagonal_element(ham, address)

Compute the diagonal matrix element of the linear operator ham at address address.

Example

julia> address = BoseFS((3, 2, 1));
 
 
 julia> H = HubbardMom1D(address);
 
 
 julia> diagonal_element(H, address)
-8.666666666666664

Part of the AbstractHamiltonian interface.

source
Rimu.Interfaces.starting_addressFunction
starting_address(h)

Return the starting address for Hamiltonian h. When called on an AbstractMatrix, starting_address returns the index of the lowest diagonal element.

Example

julia> address = BoseFS((3, 2, 1));
+8.666666666666664

Part of the AbstractHamiltonian interface.

source
Rimu.Interfaces.starting_addressFunction
starting_address(h)

Return the starting address for Hamiltonian h. When called on an AbstractMatrix, starting_address returns the index of the lowest diagonal element.

Example

julia> address = BoseFS((3, 2, 1));
 
 
 julia> H = HubbardMom1D(address);
 
 
 julia> address == starting_address(H)
-true

Part of the AbstractHamiltonian interface.

source

The following functions may be implemented instead of offdiagonals.

The following functions may be implemented instead of offdiagonals.

Rimu.Interfaces.num_offdiagonalsFunction
num_offdiagonals(ham, address)

Compute the number of number of reachable configurations from address address.

Example

julia> address = BoseFS((3, 2, 1));
 
 
 julia> H = HubbardMom1D(address);
 
 
 julia> num_offdiagonals(H, address)
-10

Part of the AbstractHamiltonian interface.

source
Rimu.Interfaces.get_offdiagonalFunction
newadd, me = get_offdiagonal(ham, address, chosen)

Compute value me and new address newadd of a single (off-diagonal) matrix element in a Hamiltonian ham. The off-diagonal element is in the same column as address address and is indexed by integer index chosen.

Example

julia> addr = BoseFS(3, 2, 1);
+10

Part of the AbstractHamiltonian interface.

source
Rimu.Interfaces.get_offdiagonalFunction
newadd, me = get_offdiagonal(ham, address, chosen)

Compute value me and new address newadd of a single (off-diagonal) matrix element in a Hamiltonian ham. The off-diagonal element is in the same column as address address and is indexed by integer index chosen.

Example

julia> addr = BoseFS(3, 2, 1);
 
 julia> H = HubbardMom1D(addr);
 
 julia> get_offdiagonal(H, addr, 3)
-(BoseFS{6,3}(2, 1, 3), 1.0)

Part of the AbstractHamiltonian interface.

source

The following functions come with default implementations, but may be customized.

The following functions come with default implementations, but may be customized.

Rimu.Interfaces.random_offdiagonalFunction
random_offdiagonal(offdiagonals::AbstractOffdiagonals)
 random_offdiagonal(ham::AbstractHamiltonian, address)
--> newaddress, probability, matrixelement

Generate a single random excitation, i.e. choose from one of the accessible off-diagonal elements in the column corresponding to address in the Hamiltonian matrix represented by ham. Alternatively, pass as argument an iterator over the accessible matrix elements.

Part of the AbstractHamiltonian interface.

source
Rimu.Interfaces.LOStructureType
LOStructure(op::AbstractHamiltonian)
-LOStructure(typeof(op))

Return information about the structure of the linear operator op. LOStructure is used as a trait to speficy symmetries or other properties of the linear operator op that may simplify or speed up calculations. Implemented instances are:

  • IsDiagonal(): The operator is diagonal.
  • IsHermitian(): The operator is complex and Hermitian or real and symmetric.
  • AdjointKnown(): The operator is not Hermitian, but its adjoint is implemented.
  • AdjointUnknown(): adjoint for this operator is not implemented.

Part of the AbstractHamiltonian interface.

In order to define this trait for a new linear operator type, define a method for LOStructure(::Type{<:MyNewLOType}) = ….

source
Rimu.Hamiltonians.dimensionFunction
dimension(h::AbstractHamiltonian, addr=starting_address(h))
+-> newaddress, probability, matrixelement

Generate a single random excitation, i.e. choose from one of the accessible off-diagonal elements in the column corresponding to address in the Hamiltonian matrix represented by ham. Alternatively, pass as argument an iterator over the accessible matrix elements.

Part of the AbstractHamiltonian interface.

source
Rimu.Interfaces.LOStructureType
LOStructure(op::AbstractHamiltonian)
+LOStructure(typeof(op))

Return information about the structure of the linear operator op. LOStructure is used as a trait to speficy symmetries or other properties of the linear operator op that may simplify or speed up calculations. Implemented instances are:

  • IsDiagonal(): The operator is diagonal.
  • IsHermitian(): The operator is complex and Hermitian or real and symmetric.
  • AdjointKnown(): The operator is not Hermitian, but its adjoint is implemented.
  • AdjointUnknown(): adjoint for this operator is not implemented.

Part of the AbstractHamiltonian interface.

In order to define this trait for a new linear operator type, define a method for LOStructure(::Type{<:MyNewLOType}) = ….

source
Rimu.Hamiltonians.dimensionFunction
dimension(h::AbstractHamiltonian, addr=starting_address(h))
 dimension(h::AbstractObservable, addr)
 dimension(addr::AbstractFockAddress)
 dimension(::Type{<:AbstractFockAddress})

Return the estimated dimension of Hilbert space. May return a BigInt number.

When called on an address or address type, the dimension of the linear space spanned by the address type is returned. When called on an AbstractHamiltonian, an upper bound on the dimension of the matrix representing the Hamiltonian is returned.

Examples

julia> dimension(OccupationNumberFS(1,2,3))
@@ -54,7 +54,7 @@
 1386083821086188248261127842108801860093488668581216236221011219101585442774669540
 
 julia> Float64(ans)
-1.3860838210861882e81

Part of the AbstractHamiltonian interface. See also BasisSetRepresentation.

Extended Help

The default fallback for dimension called on an AbstractHamiltonian is to return the dimension of the address space, which provides an upper bound. For new Hamiltonians a tighter bound can be provided by defining a custom method.

When extending AbstractHamiltonian, define a method for the two-argument form dimension(h::MyNewHamiltonian, addr). For number-conserving Hamiltonians, the function Hamiltonians.number_conserving_dimension may be useful.

When extending AbstractFockAddress, define a method for dimension(::Type{MyNewFockAddress}).

source
Rimu.Interfaces.allows_address_typeFunction
allows_address_type(operator, addr_or_type)

Returns true if addr_or_type is a valid address for operator. Otherwise, returns false.

Part of the AbstractHamiltonian interface.

Extended help

Defaults to addr_or_type <: typeof(starting_address(operator)). Overload this function if the operator can be used with addresses of different types.

source
Base.eltypeFunction
eltype(op::AbstractObservable)

Return the type of the elements of the operator. This can be a vector value. For the underlying scalar type use scalartype.

Part of the AbstractObservable interface.

Note

New types do not have to implement this method explicitly. An implementation is provided based on the AbstractObservable's type parameter.

source
VectorInterface.scalartypeFunction
scalartype(op::AbstractObservable)

Return the type of the underlying scalar field of the operator. This may be different from the element type of the operator returned by eltype, which can be a vector value.

Part of the AbstractObservable interface.

Note

New types do not have to implement this method explicitly. An implementation is provided based on the AbstractObservable's type parameter.

source
LinearAlgebra.mul!Function
LinearAlgebra.mul!(w::AbstractDVec, op::AbstractOperator, v::AbstractDVec)

In place multiplication of op with v and storing the result in w. The result is returned. Note that w needs to have a valtype that can hold a product of instances of eltype(op) and valtype(v). Moreover, the StochasticStyle of w needs to be <:IsDeterministic.

Part of the AbstractOperator interface.

The default implementation relies of diagonal_element and offdiagonals to access the elements of the operator. The function can be overloaded for custom operators.

source

This interface relies on unexported functionality, including

LinearAlgebra.dotFunction
dot(w, op::AbstractObservable, v)

Evaluate w⋅op(v) minimizing memory allocations.

source
Rimu.Hamiltonians.AbstractOffdiagonalsType
AbstractOffdiagonals{A,T}<:AbstractVector{Tuple{A,T}}

Iterator over new address and matrix elements for reachable off-diagonal matrix elements of a linear operator.

See Offdiagonals for a default implementation.

Methods to define

  • offdiagonals(h, a)::AbstractOffdiagonals: This function is used to construct the correct type of offdiagonals for a given combination of Hamiltonian h and Fock address a.
  • Base.getindex(::AbstractOffdiagonals, i): should be equivalent to get_offdiagonal(h, a, i).
  • Base.size(::AbstractOffdiagonals): should be equivalent to num_offdiagonals(h, a).

See also offdiagonals, AbstractHamiltonian, AbstractOperator.

source
Rimu.Hamiltonians.OffdiagonalsType
Offdiagonals(h, address) <: AbstractOffdiagonals

Iterator over new address and matrix element for reachable off-diagonal matrix elements of linear operator h from address address. Represents an abstract vector containing the non-zero off-diagonal matrix elements of the column of h indexed by address. To construct this iterator use offdiagonals.

This is the default implementation of AbstractOffdiagonals defined in terms of num_offdiagonals and get_offdiagonal.

See also offdiagonals, AbstractHamiltonian, AbstractOperator.

source
Rimu.Hamiltonians.check_address_typeFunction
check_address_type(h::AbstractObservable, addr_or_type)

Throw an ArgumentError if addr_or_type is not compatible with h, otherwise return true. Acceptable arguments are either an address or an address type, or a tuple or array thereof.

See also allows_address_type.

source

Operator and observable interface

Rimu.Interfaces.AbstractObservableType
AbstractObservable{T}

Most permissive supertype for operators in the type hierarchy:

AbstractHamiltonian{T} <: AbstractOperator{T} <: AbstractObservable{T}

AbstractObservable provides an interface for operators that can appear in a three-way dot product dot(x, op, y) with two vectors of type AbstractDVec. The result is a value of type T, which is also returned by the eltype function. This may be a vector type associated with a scalar type returned by the scalartype function.

The AbstractObservable type is useful for defining observables that can be calculated in the context of a ProjectorMonteCarloProblem using AllOverlaps.

Interface

Basic interface methods to implement:

Optional additional methods to implement:

See also AbstractOperator, AbstractHamiltonian, Interfaces.

source
Rimu.Interfaces.AbstractOperatorType
AbstractOperator{T} <: AbstractObservable{T}

Supertype that provides an interface for linear operators over a linear space with elements of type T (returned by eltype) and general (custom type) indices called 'addresses'.

AbstractOperator instances operate on vectors of type AbstractDVec from the module DictVectors and work well with addresses of type AbstractFockAddress from the module BitStringAddresses.

The defining feature of an AbstractOperator is that it can be applied to a vector with mul!(y, op, x) and that three-way dot products can be calculated with dot(x, op, y).

The AbstractOperator type is useful for defining operators that are not necessarily Hamiltonians, but that can be used in the context of a ProjectorMonteCarloProblem as observable operators in a ReplicaStrategy, e.g. for defining correlation functions. In contrast to AbstractHamiltonians, AbstractOperators do not need to have a starting_address. Moreover, the eltype of an AbstractOperator can be a vector value whereas AbstractHamiltonians requre a scalar eltype.

AbstractHamiltonian{T} <: AbstractOperator{T} <: AbstractObservable{T}

The AbstractOperator type is part of the AbstractObservable hierarchy. It is more restrictive than AbstractObservable in that it requires the interface for the generation of diagonal and off-diagonal elements.

For concrete implementations see Hamiltonians. In order to implement a Hamiltonian for use in ProjectorMonteCarloProblem or ExactDiagonalizationProblem use the type AbstractHamiltonian instead.

Interface

Basic interface methods to implement:

Optional additional methods to implement:

In order to calculate observables efficiently, it may make sense to implement custom methods for Interfaces.dot_from_right(x, op, y) and LinearAlgebra.mul!(y, op, x).

See also AbstractHamiltonian, Interfaces.

source

Interface tests

Helper functions that can be used for testing the various interfaces are provided in the (unexported) submodule Rimu.InterfaceTests.

Testing functions

Rimu.InterfaceTests.test_hamiltonian_interfaceFunction
test_hamiltonian_interface(h, addr=starting_address(h); test_spawning=true)

The main purpose of this test function is to check that all required methods of the AbstractHamiltonian interface are defined and work as expected.

Set test_spawning=false to skip tests that require offdiagonals to return an AbstractVector.

This function also tests the following properties of the Hamiltonian:

  • dimension(h) ≥ dimension(h, addr)
  • scalartype(h) === eltype(h)
  • Hamiltonian action on a vector <: AbstractDVec
  • starting_address returns an allows_address_type address
  • LOStructure is one of IsDiagonal, IsHermitian, AdjointKnown
  • the AbstractOperator interface is tested
  • the AbstractObservable interface is tested

Example

julia> using Rimu.InterfaceTests
+1.3860838210861882e81

Part of the AbstractHamiltonian interface. See also BasisSetRepresentation.

Extended Help

The default fallback for dimension called on an AbstractHamiltonian is to return the dimension of the address space, which provides an upper bound. For new Hamiltonians a tighter bound can be provided by defining a custom method.

When extending AbstractHamiltonian, define a method for the two-argument form dimension(h::MyNewHamiltonian, addr). For number-conserving Hamiltonians, the function Hamiltonians.number_conserving_dimension may be useful.

When extending AbstractFockAddress, define a method for dimension(::Type{MyNewFockAddress}).

source
Rimu.Interfaces.allows_address_typeFunction
allows_address_type(operator, addr_or_type)

Returns true if addr_or_type is a valid address for operator. Otherwise, returns false.

Part of the AbstractHamiltonian interface.

Extended help

Defaults to addr_or_type <: typeof(starting_address(operator)). Overload this function if the operator can be used with addresses of different types.

source
Base.eltypeFunction
eltype(op::AbstractObservable)

Return the type of the elements of the operator. This can be a vector value. For the underlying scalar type use scalartype.

Part of the AbstractObservable interface.

Note

New types do not have to implement this method explicitly. An implementation is provided based on the AbstractObservable's type parameter.

source
VectorInterface.scalartypeFunction
scalartype(op::AbstractObservable)

Return the type of the underlying scalar field of the operator. This may be different from the element type of the operator returned by eltype, which can be a vector value.

Part of the AbstractObservable interface.

Note

New types do not have to implement this method explicitly. An implementation is provided based on the AbstractObservable's type parameter.

source
LinearAlgebra.mul!Function
LinearAlgebra.mul!(w::AbstractDVec, op::AbstractOperator, v::AbstractDVec)

In place multiplication of op with v and storing the result in w. The result is returned. Note that w needs to have a valtype that can hold a product of instances of eltype(op) and valtype(v). Moreover, the StochasticStyle of w needs to be <:IsDeterministic.

Part of the AbstractOperator interface.

The default implementation relies of diagonal_element and offdiagonals to access the elements of the operator. The function can be overloaded for custom operators.

source

This interface relies on unexported functionality, including

LinearAlgebra.dotFunction
dot(w, op::AbstractObservable, v)

Evaluate w⋅op(v) minimizing memory allocations.

source
Rimu.Hamiltonians.AbstractOffdiagonalsType
AbstractOffdiagonals{A,T}<:AbstractVector{Tuple{A,T}}

Iterator over new address and matrix elements for reachable off-diagonal matrix elements of a linear operator.

See Offdiagonals for a default implementation.

Methods to define

  • offdiagonals(h, a)::AbstractOffdiagonals: This function is used to construct the correct type of offdiagonals for a given combination of Hamiltonian h and Fock address a.
  • Base.getindex(::AbstractOffdiagonals, i): should be equivalent to get_offdiagonal(h, a, i).
  • Base.size(::AbstractOffdiagonals): should be equivalent to num_offdiagonals(h, a).

See also offdiagonals, AbstractHamiltonian, AbstractOperator.

source
Rimu.Hamiltonians.OffdiagonalsType
Offdiagonals(h, address) <: AbstractOffdiagonals

Iterator over new address and matrix element for reachable off-diagonal matrix elements of linear operator h from address address. Represents an abstract vector containing the non-zero off-diagonal matrix elements of the column of h indexed by address. To construct this iterator use offdiagonals.

This is the default implementation of AbstractOffdiagonals defined in terms of num_offdiagonals and get_offdiagonal.

See also offdiagonals, AbstractHamiltonian, AbstractOperator.

source
Rimu.Hamiltonians.check_address_typeFunction
check_address_type(h::AbstractObservable, addr_or_type)

Throw an ArgumentError if addr_or_type is not compatible with h, otherwise return true. Acceptable arguments are either an address or an address type, or a tuple or array thereof.

See also allows_address_type.

source

Operator and observable interface

Rimu.Interfaces.AbstractObservableType
AbstractObservable{T}

Most permissive supertype for operators in the type hierarchy:

AbstractHamiltonian{T} <: AbstractOperator{T} <: AbstractObservable{T}

AbstractObservable provides an interface for operators that can appear in a three-way dot product dot(x, op, y) with two vectors of type AbstractDVec. The result is a value of type T, which is also returned by the eltype function. This may be a vector type associated with a scalar type returned by the scalartype function.

The AbstractObservable type is useful for defining observables that can be calculated in the context of a ProjectorMonteCarloProblem using AllOverlaps.

Interface

Basic interface methods to implement:

Optional additional methods to implement:

See also AbstractOperator, AbstractHamiltonian, Interfaces.

source
Rimu.Interfaces.AbstractOperatorType
AbstractOperator{T} <: AbstractObservable{T}

Supertype that provides an interface for linear operators over a linear space with elements of type T (returned by eltype) and general (custom type) indices called 'addresses'.

AbstractOperator instances operate on vectors of type AbstractDVec from the module DictVectors and work well with addresses of type AbstractFockAddress from the module BitStringAddresses.

The defining feature of an AbstractOperator is that it can be applied to a vector with mul!(y, op, x) and that three-way dot products can be calculated with dot(x, op, y).

The AbstractOperator type is useful for defining operators that are not necessarily Hamiltonians, but that can be used in the context of a ProjectorMonteCarloProblem as observable operators in a ReplicaStrategy, e.g. for defining correlation functions. In contrast to AbstractHamiltonians, AbstractOperators do not need to have a starting_address. Moreover, the eltype of an AbstractOperator can be a vector value whereas AbstractHamiltonians requre a scalar eltype.

AbstractHamiltonian{T} <: AbstractOperator{T} <: AbstractObservable{T}

The AbstractOperator type is part of the AbstractObservable hierarchy. It is more restrictive than AbstractObservable in that it requires the interface for the generation of diagonal and off-diagonal elements.

For concrete implementations see Hamiltonians. In order to implement a Hamiltonian for use in ProjectorMonteCarloProblem or ExactDiagonalizationProblem use the type AbstractHamiltonian instead.

Interface

Basic interface methods to implement:

Optional additional methods to implement:

In order to calculate observables efficiently, it may make sense to implement custom methods for Interfaces.dot_from_right(x, op, y) and LinearAlgebra.mul!(y, op, x).

See also AbstractHamiltonian, Interfaces.

source

Interface tests

Helper functions that can be used for testing the various interfaces are provided in the (unexported) submodule Rimu.InterfaceTests.

Testing functions

Rimu.InterfaceTests.test_hamiltonian_interfaceFunction
test_hamiltonian_interface(h, addr=starting_address(h); test_spawning=true)

The main purpose of this test function is to check that all required methods of the AbstractHamiltonian interface are defined and work as expected.

Set test_spawning=false to skip tests that require offdiagonals to return an AbstractVector.

This function also tests the following properties of the Hamiltonian:

  • dimension(h) ≥ dimension(h, addr)
  • scalartype(h) === eltype(h)
  • Hamiltonian action on a vector <: AbstractDVec
  • starting_address returns an allows_address_type address
  • LOStructure is one of IsDiagonal, IsHermitian, AdjointKnown
  • the AbstractOperator interface is tested
  • the AbstractObservable interface is tested

Example

julia> using Rimu.InterfaceTests
 
 julia> test_hamiltonian_interface(HubbardRealSpace(BoseFS(2,0,3,1)));
 Test Summary:                          | Pass  Total  Time
@@ -66,15 +66,15 @@
 Test Summary:       | Pass  Total  Time
 allows_address_type |    1      1  0.0s
 Test Summary:                                 | Pass  Total  Time
-Hamiltonians-only tests with HubbardRealSpace |    6      6  0.0s

See also test_operator_interface, test_observable_interface.

source
Rimu.InterfaceTests.test_hamiltonian_structureFunction
test_hamiltonian_structure(h::AbstractHamiltonian; sizelim=20)

Test the LOStructure of a small Hamiltonian h by instantiating it as a sparse matrix and checking whether the structure of the matrix is constistent with the result of LOStructure(h) and the eltype is consistent with eltype(h).

This function is intended to be used in automated test for small Hamiltonians where instantiating the matrix is quick. A warning will print if the dimension of the Hamiltonian is larger than 20.

Example

julia> using Rimu.InterfaceTests
+Hamiltonians-only tests with HubbardRealSpace |    6      6  0.0s

See also test_operator_interface, test_observable_interface.

source
Rimu.InterfaceTests.test_hamiltonian_structureFunction
test_hamiltonian_structure(h::AbstractHamiltonian; sizelim=20)

Test the LOStructure of a small Hamiltonian h by instantiating it as a sparse matrix and checking whether the structure of the matrix is constistent with the result of LOStructure(h) and the eltype is consistent with eltype(h).

This function is intended to be used in automated test for small Hamiltonians where instantiating the matrix is quick. A warning will print if the dimension of the Hamiltonian is larger than 20.

Example

julia> using Rimu.InterfaceTests
 
 julia> test_hamiltonian_structure(HubbardRealSpace(BoseFS(2,0,1)));
 Test Summary: | Pass  Total  Time
-structure     |    4      4  0.0s
source
Rimu.InterfaceTests.test_observable_interfaceFunction
test_observable_interface(obs, addr)

This function tests compliance with the AbstractObservable interface for an observable obs at address addr (typically <: AbstractFockAddress) by checking that all required methods are defined.

The following properties are tested:

  • dot(v, obs, v) returns a value of the same type as the eltype of the observable
  • LOStructure is set consistently

Example

julia> using Rimu.InterfaceTests
+structure     |    4      4  0.0s
source
Rimu.InterfaceTests.test_observable_interfaceFunction
test_observable_interface(obs, addr)

This function tests compliance with the AbstractObservable interface for an observable obs at address addr (typically <: AbstractFockAddress) by checking that all required methods are defined.

The following properties are tested:

  • dot(v, obs, v) returns a value of the same type as the eltype of the observable
  • LOStructure is set consistently

Example

julia> using Rimu.InterfaceTests
 
 julia> test_observable_interface(ReducedDensityMatrix(2), FermiFS(1,0,1,1));
 Test Summary:                              | Pass  Total  Time
-Observable interface: ReducedDensityMatrix |    4      4  0.0s

See also AbstractObservable, test_operator_interface, test_hamiltonian_interface.

source
Rimu.InterfaceTests.test_operator_interfaceFunction
test_operator_interface(op, addr; test_spawning=true)

This function tests compliance with the AbstractOperator interface for an operator op at address addr (typically <: AbstractFockAddress) by checking that all required methods are defined.

If test_spawning is true, tests are performed that require offdiagonals to return an Hamiltonians.AbstractOffDiagonals, which is a prerequisite for using the spawn! function. Otherwise, the spawning tests are skipped.

The following properties are tested:

  • diagonal_element returns a value of the same type as the eltype of the operator
  • offdiagonals behaves like an AbstractVector
  • num_offdiagonals returns the correct number of offdiagonals
  • random_offdiagonal returns a tuple with the correct types
  • mul! and dot work as expected
  • dimension returns a consistent value
  • the AbstractObservable interface is tested

Example

julia> using Rimu.InterfaceTests
+Observable interface: ReducedDensityMatrix |    4      4  0.0s

See also AbstractObservable, test_operator_interface, test_hamiltonian_interface.

source
Rimu.InterfaceTests.test_operator_interfaceFunction
test_operator_interface(op, addr; test_spawning=true)

This function tests compliance with the AbstractOperator interface for an operator op at address addr (typically <: AbstractFockAddress) by checking that all required methods are defined.

If test_spawning is true, tests are performed that require offdiagonals to return an Hamiltonians.AbstractOffDiagonals, which is a prerequisite for using the spawn! function. Otherwise, the spawning tests are skipped.

The following properties are tested:

  • diagonal_element returns a value of the same type as the eltype of the operator
  • offdiagonals behaves like an AbstractVector
  • num_offdiagonals returns the correct number of offdiagonals
  • random_offdiagonal returns a tuple with the correct types
  • mul! and dot work as expected
  • dimension returns a consistent value
  • the AbstractObservable interface is tested

Example

julia> using Rimu.InterfaceTests
 
 julia> test_operator_interface(SuperfluidCorrelator(3), BoseFS(1, 2, 3, 1));
 Test Summary:                              | Pass  Total  Time
@@ -82,10 +82,10 @@
 Test Summary:       | Pass  Total  Time
 allows_address_type |    1      1  0.0s
 Test Summary:                            | Pass  Total  Time
-Operator interface: SuperfluidCorrelator |    9      9  0.0s

See also AbstractOperator, test_observable_interface, test_hamiltonian_interface.

source

Utilities for harmonic oscillator models

Useful utilities for harmonic oscillator in Cartesian basis, see HOCartesianContactInteractions and HOCartesianEnergyConservedPerDim.

Utilities for harmonic oscillator models

Useful utilities for harmonic oscillator in Cartesian basis, see HOCartesianContactInteractions and HOCartesianEnergyConservedPerDim.

Rimu.Hamiltonians.get_all_blocksFunction
get_all_blocks(h::Union{HOCartesianContactInteractions,HOCartesianEnergyConservedPerDim};
     target_energy = nothing,
     max_energy = nothing,
     max_blocks = nothing,
     method = :vertices,
-    kwargs...) -> df

Find all distinct blocks of h. Returns a DataFrame with columns

  • block_id: index of block in order found
  • block_E0: noninteracting energy of all elements in the block
  • block_size: number of elements in the block
  • addr: first address that generates the block with e.g. BasisSetRepresentation
  • indices: tuple of mode indices that allow recreation of the generating address addr; in this case use e.g. BoseFS(M; indices .=> 1) This is useful when the DataFrame is loaded from file since Arrow.jl converts custom types to NamedTuples.
  • t_basis: time to generate the basis for each block

Keyword arguments:

  • target_energy: only blocks with this noninteracting energy are found
  • max_energy: only blocks with noninteracting energy less than this are found
  • max_blocks: exit after finding this many blocks
  • method: Choose between :vertices and :comb for method of enumerating tuples of quantum numbers
  • save_to_file=nothing: if set then the DataFrame recording blocks is saved after each new block is found
  • additional kwargs: passed to isapprox for comparing block energies. Useful for anisotropic traps

Note: If h was constructed with option block_by_level = false then the block seeds addr are determined by parity. In this case the blocks are not generated; t_basis will be zero, and block_size will be an estimate. Pass the seed addresses to BasisSetRepresentation with an appropriate filter to generate the blocks.

source
Rimu.Hamiltonians.fock_to_cartFunction
fock_to_cart(addr, S; zero_index = true)

Convert a Fock state address addr to Cartesian harmonic oscillator basis indices $n_x,n_y,\ldots$. These indices are bounded by S which is a tuple of the maximum number of states in each dimension. By default the groundstate in each dimension is indexed by 0, but this can be changed by setting zero_index = false.

source

Underlying integrals for the interaction matrix elements are implemented in the following unexported functions

Rimu.Hamiltonians.four_oscillator_integral_generalFunction
four_oscillator_integral_general(i, j, k, l; max_level = typemax(Int))

Integral of four one-dimensional harmonic oscillator functions,

\[ \mathcal{I}(i,j,k,l) = \int_{-\infty}^\infty dx \, - \phi_i(x) \phi_j(x) \phi_k(x) \phi_l(x)\]

Indices i,j,k,l start at 0 for the groundstate.

This integral has a closed form in terms of the hypergeometric $_{3}F_2$ function, and is non-zero unless $i+j+k+l$ is odd. See e.g. Titchmarsh (1948). This is a generalisation of the closed form in Papenbrock (2002), which is is the special case where $i+j == k+l$, but is numerically unstable for large arguments. Used in HOCartesianContactInteractions and HOCartesianEnergyConservedPerDim.

source
Rimu.Hamiltonians.ho_delta_potentialFunction
ho_delta_potential(S, i, j; [vals])

Returns the matrix element of a delta potential at the centre of a trap, i.e. the product of two harmonic oscillator functions evaluated at the origin,

\[ v_{ij} = \phi_{\mathbf{n}_i}(0) \phi_{\mathbf{n}_j}(0)\]

which is only non-zero for even-parity states. The ith single particle state corresponds to a $D$-tuple of harmonic oscillator indices $\mathbf{n}_i$. S defines the bounds of Cartesian harmonic oscillator indices for each dimension. The optional keyword argument vals allows passing pre-computed values of $\phi_i(0)$ to speed-up the calculation. The values can be calculated with log_abs_oscillator_zero.

See also HOCartesianCentralImpurity.

source

Index

+ kwargs...) -> df

Find all distinct blocks of h. Returns a DataFrame with columns

  • block_id: index of block in order found
  • block_E0: noninteracting energy of all elements in the block
  • block_size: number of elements in the block
  • addr: first address that generates the block with e.g. BasisSetRepresentation
  • indices: tuple of mode indices that allow recreation of the generating address addr; in this case use e.g. BoseFS(M; indices .=> 1) This is useful when the DataFrame is loaded from file since Arrow.jl converts custom types to NamedTuples.
  • t_basis: time to generate the basis for each block

Keyword arguments:

  • target_energy: only blocks with this noninteracting energy are found
  • max_energy: only blocks with noninteracting energy less than this are found
  • max_blocks: exit after finding this many blocks
  • method: Choose between :vertices and :comb for method of enumerating tuples of quantum numbers
  • save_to_file=nothing: if set then the DataFrame recording blocks is saved after each new block is found
  • additional kwargs: passed to isapprox for comparing block energies. Useful for anisotropic traps

Note: If h was constructed with option block_by_level = false then the block seeds addr are determined by parity. In this case the blocks are not generated; t_basis will be zero, and block_size will be an estimate. Pass the seed addresses to BasisSetRepresentation with an appropriate filter to generate the blocks.

source
Rimu.Hamiltonians.fock_to_cartFunction
fock_to_cart(addr, S; zero_index = true)

Convert a Fock state address addr to Cartesian harmonic oscillator basis indices $n_x,n_y,\ldots$. These indices are bounded by S which is a tuple of the maximum number of states in each dimension. By default the groundstate in each dimension is indexed by 0, but this can be changed by setting zero_index = false.

source

Underlying integrals for the interaction matrix elements are implemented in the following unexported functions

Rimu.Hamiltonians.four_oscillator_integral_generalFunction
four_oscillator_integral_general(i, j, k, l; max_level = typemax(Int))

Integral of four one-dimensional harmonic oscillator functions,

\[ \mathcal{I}(i,j,k,l) = \int_{-\infty}^\infty dx \, + \phi_i(x) \phi_j(x) \phi_k(x) \phi_l(x)\]

Indices i,j,k,l start at 0 for the groundstate.

This integral has a closed form in terms of the hypergeometric $_{3}F_2$ function, and is non-zero unless $i+j+k+l$ is odd. See e.g. Titchmarsh (1948). This is a generalisation of the closed form in Papenbrock (2002), which is is the special case where $i+j == k+l$, but is numerically unstable for large arguments. Used in HOCartesianContactInteractions and HOCartesianEnergyConservedPerDim.

source
Rimu.Hamiltonians.ho_delta_potentialFunction
ho_delta_potential(S, i, j; [vals])

Returns the matrix element of a delta potential at the centre of a trap, i.e. the product of two harmonic oscillator functions evaluated at the origin,

\[ v_{ij} = \phi_{\mathbf{n}_i}(0) \phi_{\mathbf{n}_j}(0)\]

which is only non-zero for even-parity states. The ith single particle state corresponds to a $D$-tuple of harmonic oscillator indices $\mathbf{n}_i$. S defines the bounds of Cartesian harmonic oscillator indices for each dimension. The optional keyword argument vals allows passing pre-computed values of $\phi_i(0)$ to speed-up the calculation. The values can be calculated with log_abs_oscillator_zero.

See also HOCartesianCentralImpurity.

source

Index

diff --git a/previews/PR308/dictvectors.html b/previews/PR308/dictvectors.html index 9025116cf..53bcad6a1 100644 --- a/previews/PR308/dictvectors.html +++ b/previews/PR308/dictvectors.html @@ -1,12 +1,12 @@ -Dict vectors · Rimu.jl

Module DictVectors

Rimu.Interfaces.AbstractDVecType
AbstractDVec{K,V}

Abstract data type for vector-like data structures with sparse storage. While conceptually AbstractDVecs represent elements of a vector space over a scalar type V, they are indexed by an arbitrary type K (could be non-integers) similar to dictionaries. They support the interface from VectorInterface.jl and are designed to work well for quantum Monte Carlo with ProjectorMonteCarloProblem and for matrix-free linear algebra with KrylovKit.

Concrete implementations are available as PDVec, DVec, and InitiatorDVec.

AbstractDVecs have a StochasticStyle which selects the spawning algorithm in FCIQMC. Looking up an element that is not stored in the AbstractDVec should return a zero, and setting a value to zero should remove it from the vector. To iterate over an AbstractDVec, use keys, pairs, or values. When possible, use reduction functions such as sum or mapreduce.

Interface

The interface is similar to the AbstractDict interface, but with the changed behaviour as noted above. Implement what would be needed for the AbstractDict interface (pairs, keys, values, setindex!, getindex, delete!, length, empty, empty!) and, in addition:

A default implementation for the VectorInterface.jl interface is provided through the above functions.

See also DictVectors, Interfaces.

source

Concrete implementations

Rimu.DictVectors.DVecType
DVec{K,V,D<:AbstractDict{K,V},S}

Dictionary-based vector-like data structure for use with FCIQMC and KrylovKit. While mostly behaving like a Dict, it supports various linear algebra operations such as norm and dot. It has a StochasticStyle that is used to select an appropriate spawning strategy in the FCIQMC algorithm.

See also: AbstractDVec, InitiatorDVec, PDVec.

Constructors

  • DVec(dict::AbstractDict[; style, capacity]): create a DVec with dict for storage. Note that the data may or may not be copied.

  • DVec(args...[; style, capacity]): args... are passed to the Dict constructor. The Dict is used for storage.

  • DVec{K,V}([; style, capacity]): create an empty DVec{K,V}.

  • DVec(dv::AbstractDVec[; style, capacity]): create a DVec with the same contents as adv. The style is inherited from dv by default.

The default style is selected based on the DVec's valtype (see default_style). If a style is given and the valtype does not match the style's eltype, the values are converted to an appropriate type.

The capacity argument is optional and sets the initial size of the DVec via Base.sizehint!.

Examples

julia> dv = DVec(:a => 1)
+Dict vectors · Rimu.jl

Module DictVectors

Rimu.Interfaces.AbstractDVecType
AbstractDVec{K,V}

Abstract data type for vector-like data structures with sparse storage. While conceptually AbstractDVecs represent elements of a vector space over a scalar type V, they are indexed by an arbitrary type K (could be non-integers) similar to dictionaries. They support the interface from VectorInterface.jl and are designed to work well for quantum Monte Carlo with ProjectorMonteCarloProblem and for matrix-free linear algebra with KrylovKit.

Concrete implementations are available as PDVec, DVec, and InitiatorDVec.

AbstractDVecs have a StochasticStyle which selects the spawning algorithm in FCIQMC. Looking up an element that is not stored in the AbstractDVec should return a zero, and setting a value to zero should remove it from the vector. To iterate over an AbstractDVec, use keys, pairs, or values. When possible, use reduction functions such as sum or mapreduce.

Interface

The interface is similar to the AbstractDict interface, but with the changed behaviour as noted above. Implement what would be needed for the AbstractDict interface (pairs, keys, values, setindex!, getindex, delete!, length, empty, empty!) and, in addition:

A default implementation for the VectorInterface.jl interface is provided through the above functions.

See also DictVectors, Interfaces.

source

Concrete implementations

Rimu.DictVectors.DVecType
DVec{K,V,D<:AbstractDict{K,V},S}

Dictionary-based vector-like data structure for use with FCIQMC and KrylovKit. While mostly behaving like a Dict, it supports various linear algebra operations such as norm and dot. It has a StochasticStyle that is used to select an appropriate spawning strategy in the FCIQMC algorithm.

See also: AbstractDVec, InitiatorDVec, PDVec.

Constructors

  • DVec(dict::AbstractDict[; style, capacity]): create a DVec with dict for storage. Note that the data may or may not be copied.

  • DVec(args...[; style, capacity]): args... are passed to the Dict constructor. The Dict is used for storage.

  • DVec{K,V}([; style, capacity]): create an empty DVec{K,V}.

  • DVec(dv::AbstractDVec[; style, capacity]): create a DVec with the same contents as adv. The style is inherited from dv by default.

The default style is selected based on the DVec's valtype (see default_style). If a style is given and the valtype does not match the style's eltype, the values are converted to an appropriate type.

The capacity argument is optional and sets the initial size of the DVec via Base.sizehint!.

Examples

julia> dv = DVec(:a => 1)
 DVec{Symbol,Int64} with 1 entry, style = IsStochasticInteger{Int64}()
   :a => 1
 
 julia> dv = DVec(:a => 2, :b => 3; style=IsDeterministic())
 DVec{Symbol,Float64} with 2 entries, style = IsDeterministic{Float64}()
   :a => 2.0
-  :b => 3.0
source
Rimu.DictVectors.InitiatorDVecType
InitiatorDVec{K,V} <: AbstractDVec{K,V}

Dictionary-based vector-like data structure for use with ProjectorMonteCarloProblem and KrylovKit.jl. See AbstractDVec. Functionally identical to DVec, but contains InitiatorValues internally in order to facilitate initiator methods. Initiator methods for controlling the Monte Carlo sign problem were first introduced in J. Chem. Phys. 132, 041103 (2010). How the initiators are handled is controlled by specifying an InitiatorRule with the initiator keyword argument (see below).

See also: AbstractDVec, DVec, PDVec.

Constructors

  • InitiatorDVec(dict::AbstractDict[; style, initiator, capacity]): create an InitiatorDVec with dict for storage. Note that the data may or may not be copied.

  • InitiatorDVec(args...[; style, initiator, capacity]): args... are passed to the Dict constructor. The Dict is used for storage.

  • InitiatorDVec{K,V}([; style, initiator, capacity]): create an empty InitiatorDVec{K,V}.

  • InitiatorDVec(dv::AbstractDVec[; style, initiator, capacity]): create an InitiatorDVec with the same contents as dv. The style is inherited from dv by default.

Keyword arguments

  • style: A valid StochasticStyle. The default is selected based on the InitiatorDVec's valtype (see default_style). If a style is given and the valtype does not match the style's eltype, the values are converted to an appropriate type.

  • initiator = Initiator(1): A valid InitiatorRule. See Initiator.

  • capacity: Indicative size as Int. Optional. Sets the initial size of the InitiatorDVec via Base.sizehint!.

source
Rimu.DictVectors.InitiatorDVecType
InitiatorDVec{K,V} <: AbstractDVec{K,V}

Dictionary-based vector-like data structure for use with ProjectorMonteCarloProblem and KrylovKit.jl. See AbstractDVec. Functionally identical to DVec, but contains InitiatorValues internally in order to facilitate initiator methods. Initiator methods for controlling the Monte Carlo sign problem were first introduced in J. Chem. Phys. 132, 041103 (2010). How the initiators are handled is controlled by specifying an InitiatorRule with the initiator keyword argument (see below).

See also: AbstractDVec, DVec, PDVec.

Constructors

  • InitiatorDVec(dict::AbstractDict[; style, initiator, capacity]): create an InitiatorDVec with dict for storage. Note that the data may or may not be copied.

  • InitiatorDVec(args...[; style, initiator, capacity]): args... are passed to the Dict constructor. The Dict is used for storage.

  • InitiatorDVec{K,V}([; style, initiator, capacity]): create an empty InitiatorDVec{K,V}.

  • InitiatorDVec(dv::AbstractDVec[; style, initiator, capacity]): create an InitiatorDVec with the same contents as dv. The style is inherited from dv by default.

Keyword arguments

  • style: A valid StochasticStyle. The default is selected based on the InitiatorDVec's valtype (see default_style). If a style is given and the valtype does not match the style's eltype, the values are converted to an appropriate type.

  • initiator = Initiator(1): A valid InitiatorRule. See Initiator.

  • capacity: Indicative size as Int. Optional. Sets the initial size of the InitiatorDVec via Base.sizehint!.

source
Rimu.DictVectors.PDVecType
PDVec{K,V}(; kwargs...)
 PDVec(iter; kwargs...)
 PDVec(pairs...; kwargs...)

Dictionary-based vector-like data structure for use with FCIQMC and KrylovKit.jl. While mostly behaving like a Dict, it supports various linear algebra operations such as norm and dot, and the interface defined in VectorInterface.

The P in PDVec stands for parallel. PDVecs perform mapreduce, foreach, and various linear algebra operations in a threaded manner. If MPI is available, these operations are automatically distributed as well. As such it is not recommended to iterate over pairs, keys, or values directly unless explicitly performing them on the localpart of the vector.

See also: AbstractDVec, DVec, InitiatorDVec.

Keyword arguments

Extended Help

Segmentation

The vector is split into Threads.nthreads() subdictionaries called segments. Which dictionary a key-value pair is mapped to is determined by the hash of the key. The purpose of this segmentation is to allow parallel processing - functions such as mapreduce, add! or dot (full list below) process each subdictionary on a separate thread.

See also PDWorkingMemory.

Example

julia> add = FermiFS2C((1,1,0,0), (0,0,1,1));
 
@@ -71,17 +71,17 @@
  -3.4311156892322234
   1.1821748602612363
   3.7377753753082823
-  6.996390417443125

Parallel functionality

The following functions are threaded and MPI-compatible:

  • From Base: mapreduce and derivatives (sum, prod, reduce...), all, any,map! (on values only), +, -, *
  • From LinearAlgebra: rmul!, lmul!, mul!, axpy!, axpby!, dot, norm, normalize, normalize!
  • The full interface defined in VectorInterface.jl
source

Interface functions

Rimu.Interfaces.deposit!Function
deposit!(w::InitiatorDVec, add, val, p_add=>p_val)

Add val into w at address add as an AbstractInitiatorValue.

source
deposit!(w::AbstractDVec, add, val, parent::Pair)

Add val into w at address add, taking into account initiator rules if applicable. parent contains the address => value pair from which the pair add => val was created. InitiatorDVec can intercept this and add its own functionality.

source
Rimu.Interfaces.storageFunction
storage(dvec) -> AbstractDict

Return the raw storage associated with dvec as an AbstractDict. Used in MPI communication.

source
OrderedCollections.freezeFunction
freeze(dv)

Create a "frozen" version of dv which can no longer be modified or used in the conventional manner, but supports faster dot products.

source
Rimu.Interfaces.apply_operator!Function
apply_operator!(working_memory, target, source, operator, boost=1, compress=Val(true)) ->
-    stat_names, stats, working_memory, target

Perform a single matrix(/operator)-vector multiplication:

\[v^{(n + 1)} = \hat{T} v^{(n)} ,\]

where $\hat{T}$ is the operator, $v^{(n+1)}$ is the target and $v^{(n)}$ is the source. The working_memory can be used as temporary storage.

The boost argument is passed to apply_column! and increases the number of spawns performed. For the operator to be applied without compressing the vector after, set compress to Val(false).

Whether the operation is performed in a stochastic, semistochastic, or determistic way is controlled by the trait StochasticStyle(target). See StochasticStyle.

Returns the step stats generated by the StochasticStyle, the working memory and the target vector. target and working_memory may be mutated and/or swapped.

source
Rimu.Interfaces.sort_into_targets!Function
sort_into_targets!(target, source, stats) -> target, source, agg_stats

Aggregate coefficients from source to target and from stats to agg_stats according to thread- or MPI-level parallelism.

Returns the new target and source, as the sorting process may involve swapping them.

source
Base.mapreduceFunction
mapreduce(f, op, keys(::PDVec); [init])
+  6.996390417443125

Parallel functionality

The following functions are threaded and MPI-compatible:

  • From Base: mapreduce and derivatives (sum, prod, reduce...), all, any,map! (on values only), +, -, *
  • From LinearAlgebra: rmul!, lmul!, mul!, axpy!, axpby!, dot, norm, normalize, normalize!
  • The full interface defined in VectorInterface.jl
source

Interface functions

Rimu.Interfaces.deposit!Function
deposit!(w::InitiatorDVec, add, val, p_add=>p_val)

Add val into w at address add as an AbstractInitiatorValue.

source
deposit!(w::AbstractDVec, add, val, parent::Pair)

Add val into w at address add, taking into account initiator rules if applicable. parent contains the address => value pair from which the pair add => val was created. InitiatorDVec can intercept this and add its own functionality.

source
Rimu.Interfaces.storageFunction
storage(dvec) -> AbstractDict

Return the raw storage associated with dvec as an AbstractDict. Used in MPI communication.

source
OrderedCollections.freezeFunction
freeze(dv)

Create a "frozen" version of dv which can no longer be modified or used in the conventional manner, but supports faster dot products.

source
Rimu.Interfaces.apply_operator!Function
apply_operator!(working_memory, target, source, operator, boost=1, compress=Val(true)) ->
+    stat_names, stats, working_memory, target

Perform a single matrix(/operator)-vector multiplication:

\[v^{(n + 1)} = \hat{T} v^{(n)} ,\]

where $\hat{T}$ is the operator, $v^{(n+1)}$ is the target and $v^{(n)}$ is the source. The working_memory can be used as temporary storage.

The boost argument is passed to apply_column! and increases the number of spawns performed. For the operator to be applied without compressing the vector after, set compress to Val(false).

Whether the operation is performed in a stochastic, semistochastic, or determistic way is controlled by the trait StochasticStyle(target). See StochasticStyle.

Returns the step stats generated by the StochasticStyle, the working memory and the target vector. target and working_memory may be mutated and/or swapped.

source
Rimu.Interfaces.sort_into_targets!Function
sort_into_targets!(target, source, stats) -> target, source, agg_stats

Aggregate coefficients from source to target and from stats to agg_stats according to thread- or MPI-level parallelism.

Returns the new target and source, as the sorting process may involve swapping them.

source
Base.mapreduceFunction
mapreduce(f, op, keys(::PDVec); [init])
 mapreduce(f, op, values(::PDVec); [init])
-mapreduce(f, op, pairs(::PDVec); [init])

Perform a parallel reduction operation on PDVecs. MPI-compatible. Is used in the definition of various functions from Base such as reduce, sum, prod, etc.

init, if provided, must be a neutral element for op.

source
Rimu.Interfaces.sum_mutating!Function
sum_mutating!(accumulator, [f! = add!], keys(::PDVec); [init])
+mapreduce(f, op, pairs(::PDVec); [init])

Perform a parallel reduction operation on PDVecs. MPI-compatible. Is used in the definition of various functions from Base such as reduce, sum, prod, etc.

init, if provided, must be a neutral element for op.

source
Rimu.Interfaces.sum_mutating!Function
sum_mutating!(accumulator, [f! = add!], keys(::PDVec); [init])
 sum_mutating!(accumulator, [f! = add!], values(::PDVec); [init])
-sum_mutating!(accumulator, [f! = add!], pairs(::PDVec); [init])

Perform a parallel sum on PDVecs for vector-valued results while minimizing allocations. The result of the sum will be added to accumulator and stored in accumulator. MPI-compatible. If f! is provided, it must accept two arguments, the first being the accumulator and the second the element of the iterator. Otherwise,add! is used.

If provided, init must be a neutral element for + and of the same type as accumulator.

See also mapreduce.

source
sum_mutating!(accumulator, [f! = add!], iterator)

Add the sum of elements in iterator to accumulator, storing the result in accumulator. If f! is provided, it must accept two arguments, the first being the accumulator and the second the element of the iterator. Otherwise, add! is used.

See also mapreduce.

source

Supported operations

AbstractDVecs generally support most operations that are defined on Vectors and Dicts. This includes the interface from VectorInterface.jl, and many functions from the LinearAlgebra standard library.

A significant difference between AbstractDVecs, Vectors, and Dicts, is that iteration on them is disabled by default. Iteration must be explicitly performed on keys, values, or pairs, however, it is highly recommended you use mapreduce, reduce, or similar functions when performing reductions, as that will make the operations compatible with MPI.

In addition, Rimu defines the following function.

Rimu.DictVectors.walkernumberFunction
walkernumber(v)

Compute the number of walkers in v. It is used for updating the shift. Overload this function for modifying population control.

In most cases walkernumber(v) is identical to norm(v, 1). For AbstractDVecs with complex coefficients it reports the one norm separately for the real and the imaginary part as a ComplexF64. See Norm1ProjectorPPop.

source

Projectors

Initiator rules

Rimu.DictVectors.InitiatorType
Initiator(threshold = 1.0) <: InitiatorRule

Initiator rule to be passed to PDVec or InitiatorDVec. An initiator is a configuration add with a coefficient with magnitude abs(v[add]) > threshold. The threshold can be passed as a keyword argument. Rules:

  • Initiators can spawn anywhere.
  • Non-initiators can spawn to initiators.

See InitiatorRule.

source
Rimu.DictVectors.SimpleInitiatorType
SimpleInitiator(threshold = 1.0) <: InitiatorRule

Initiator rule to be passed to PDVec or InitiatorDVec. An initiator is a configuration add with a coefficient with magnitude abs(v[add]) > threshold. The threshold can be passed as a keyword argument. Rules:

  • Initiators can spawn anywhere.
  • Non-initiators cannot spawn.

See InitiatorRule.

source
Rimu.DictVectors.CoherentInitiatorType
CoherentInitiator(threshold = 1.0) <: InitiatorRule

Initiator rule to be passed to PDVec or InitiatorDVec. An initiator is a configuration add with a coefficient with magnitude abs(v[add]) > threshold. The threshold can be passed as a keyword argument. Rules:

  • Initiators can spawn anywhere.
  • Non-initiators can spawn to initiators.
  • Multiple non-initiators can spawn to a single non-initiator if their contributions add up to a value greater than the initiator threshold.

See InitiatorRule.

source

PDVec internals

Working memory

Rimu.DictVectors.PDWorkingMemoryType
PDWorkingMemory(t::PDVec)

The working memory that handles threading and MPI distribution for operations that involve operators, such as FCIQMC propagation, operator-vector multiplication and three-way dot products with PDVecs.

The working memory is structured as a two-dimensional array of segments, which themselves are Dicts (see PDVec). The number of rows in this array is equal to the number of segments across all MPI ranks (covering the entire address space), while the number of columns corresponds to the number of segments in the current MPI rank (i.e. column corresponds to the part of the address space that is local to the current rank).

The purpose of this organisation is to allow spawning in parallel without using locks or atomic operations. The spawning is performed by applying the following sequence of operations:

  • perform_spawns!: each segment in the PDVec is multiplied by the operator independently, with the results being stored in a column of the working memory.
  • collect_local!: the rows of the working memory are summed to the first column.
  • synchronize_remote!: the segments corresponding to other MPI ranks are distributed and transferred to the first column.
  • move_and_compress!: the results are stochastically compressed and moved to the result PDVec

When used with three-argument dot products, a full copy of the left-hand side vector is materialized in the first column of the working memory on all ranks.

source

Communicators

Rimu.DictVectors.AllToAllType
AllToAll{K,V}(; mpi_comm, n_segments, report) <: Communicator

Communicator that uses collective communication using MPI.Alltoall[v]!.

Keyword arguments

  • mpi_comm=MPI.COMM_WORLD: the MPI communicator to use.
  • n_segments=Threads.nthreads(): the number of segments per rank to use. Should match the PDVec the communicator is used with.
  • report=false: if set to true, report MPI communication times during a projector Monte Carlo run.

See also: Communicator.

source
Rimu.DictVectors.CommunicatorType
abstract type Communicator

Communicators are used to handle MPI communication when using PDVecs. Currently, three implementations are provided, NotDistributed, AllToAll and PointToPoint. The communicator is picked automatically according to the number of MPI ranks available.

When implementing a communicator, use local_segments and remote_segments.

Interface

Optional interface

See also: PDVec, PDWorkingMemory.

source
Rimu.DictVectors.NestedSegmentedBufferType
NestedSegmentedBuffer{T}(nrows) <: AbstractMatrix{AbstractVector{T}}

Matrix of vectors stored in a single buffer with collective MPI communication support. The number of rows in the matrix is fixed to nrows.

Used in the AllToAll communication strategy, where each column corresponds to an MPI rank and each row corresponds to a segment in the PDVec.

Supported operations

See also: SegmentedBuffer.

source
Rimu.DictVectors.PointToPointType
PointToPoint{K,V}(; mpi_comm, report) <: Communicator

MPI Communicator that uses circular communication using MPI.Isend and MPI.Recv!.

Keyword arguments

  • mpi_comm=MPI.COMM_WORLD: the MPI communicator to use.
  • report=false: if set to true, report MPI communication times during a projector Monte Carlo run.
source
Rimu.DictVectors.SegmentedBufferType
SegmentedBuffer{T}() <: AbstractVector{AbstractVector{T}}

Behaves like a vector of vectors, but is stored in a single buffer. It can be sent/received over MPI keeping its structure intact. Used in the PointToPoint communication strategy.

Supported operations

See also: NestedSegmentedBuffer.

source
Rimu.DictVectors.mpi_recv_any!Method
mpi_recv_any!(buf::SegmentedBuffer, comm::MPI_Comm) -> Int

Find a source that is ready to send a buffer and receive from it. Return the rank ID of the sender.

source
Rimu.DictVectors.replace_collections!Method
replace_collections!(buf::SegmentedBuffer, iters)

Insert collections in iters into a SegmentedBuffer.

julia> using Rimu.DictVectors: SegmentedBuffer
+sum_mutating!(accumulator, [f! = add!], pairs(::PDVec); [init])

Perform a parallel sum on PDVecs for vector-valued results while minimizing allocations. The result of the sum will be added to accumulator and stored in accumulator. MPI-compatible. If f! is provided, it must accept two arguments, the first being the accumulator and the second the element of the iterator. Otherwise,add! is used.

If provided, init must be a neutral element for + and of the same type as accumulator.

See also mapreduce.

source
sum_mutating!(accumulator, [f! = add!], iterator)

Add the sum of elements in iterator to accumulator, storing the result in accumulator. If f! is provided, it must accept two arguments, the first being the accumulator and the second the element of the iterator. Otherwise, add! is used.

See also mapreduce.

source

Supported operations

AbstractDVecs generally support most operations that are defined on Vectors and Dicts. This includes the interface from VectorInterface.jl, and many functions from the LinearAlgebra standard library.

A significant difference between AbstractDVecs, Vectors, and Dicts, is that iteration on them is disabled by default. Iteration must be explicitly performed on keys, values, or pairs, however, it is highly recommended you use mapreduce, reduce, or similar functions when performing reductions, as that will make the operations compatible with MPI.

In addition, Rimu defines the following function.

Rimu.DictVectors.walkernumberFunction
walkernumber(v)

Compute the number of walkers in v. It is used for updating the shift. Overload this function for modifying population control.

In most cases walkernumber(v) is identical to norm(v, 1). For AbstractDVecs with complex coefficients it reports the one norm separately for the real and the imaginary part as a ComplexF64. See Norm1ProjectorPPop.

source

Projectors

Initiator rules

Rimu.DictVectors.InitiatorType
Initiator(threshold = 1.0) <: InitiatorRule

Initiator rule to be passed to PDVec or InitiatorDVec. An initiator is a configuration add with a coefficient with magnitude abs(v[add]) > threshold. The threshold can be passed as a keyword argument. Rules:

  • Initiators can spawn anywhere.
  • Non-initiators can spawn to initiators.

See InitiatorRule.

source
Rimu.DictVectors.SimpleInitiatorType
SimpleInitiator(threshold = 1.0) <: InitiatorRule

Initiator rule to be passed to PDVec or InitiatorDVec. An initiator is a configuration add with a coefficient with magnitude abs(v[add]) > threshold. The threshold can be passed as a keyword argument. Rules:

  • Initiators can spawn anywhere.
  • Non-initiators cannot spawn.

See InitiatorRule.

source
Rimu.DictVectors.CoherentInitiatorType
CoherentInitiator(threshold = 1.0) <: InitiatorRule

Initiator rule to be passed to PDVec or InitiatorDVec. An initiator is a configuration add with a coefficient with magnitude abs(v[add]) > threshold. The threshold can be passed as a keyword argument. Rules:

  • Initiators can spawn anywhere.
  • Non-initiators can spawn to initiators.
  • Multiple non-initiators can spawn to a single non-initiator if their contributions add up to a value greater than the initiator threshold.

See InitiatorRule.

source

PDVec internals

Working memory

Rimu.DictVectors.PDWorkingMemoryType
PDWorkingMemory(t::PDVec)

The working memory that handles threading and MPI distribution for operations that involve operators, such as FCIQMC propagation, operator-vector multiplication and three-way dot products with PDVecs.

The working memory is structured as a two-dimensional array of segments, which themselves are Dicts (see PDVec). The number of rows in this array is equal to the number of segments across all MPI ranks (covering the entire address space), while the number of columns corresponds to the number of segments in the current MPI rank (i.e. column corresponds to the part of the address space that is local to the current rank).

The purpose of this organisation is to allow spawning in parallel without using locks or atomic operations. The spawning is performed by applying the following sequence of operations:

  • perform_spawns!: each segment in the PDVec is multiplied by the operator independently, with the results being stored in a column of the working memory.
  • collect_local!: the rows of the working memory are summed to the first column.
  • synchronize_remote!: the segments corresponding to other MPI ranks are distributed and transferred to the first column.
  • move_and_compress!: the results are stochastically compressed and moved to the result PDVec

When used with three-argument dot products, a full copy of the left-hand side vector is materialized in the first column of the working memory on all ranks.

source

Communicators

Rimu.DictVectors.AllToAllType
AllToAll{K,V}(; mpi_comm, n_segments, report) <: Communicator

Communicator that uses collective communication using MPI.Alltoall[v]!.

Keyword arguments

  • mpi_comm=MPI.COMM_WORLD: the MPI communicator to use.
  • n_segments=Threads.nthreads(): the number of segments per rank to use. Should match the PDVec the communicator is used with.
  • report=false: if set to true, report MPI communication times during a projector Monte Carlo run.

See also: Communicator.

source
Rimu.DictVectors.CommunicatorType
abstract type Communicator

Communicators are used to handle MPI communication when using PDVecs. Currently, three implementations are provided, NotDistributed, AllToAll and PointToPoint. The communicator is picked automatically according to the number of MPI ranks available.

When implementing a communicator, use local_segments and remote_segments.

Interface

Optional interface

See also: PDVec, PDWorkingMemory.

source
Rimu.DictVectors.NestedSegmentedBufferType
NestedSegmentedBuffer{T}(nrows) <: AbstractMatrix{AbstractVector{T}}

Matrix of vectors stored in a single buffer with collective MPI communication support. The number of rows in the matrix is fixed to nrows.

Used in the AllToAll communication strategy, where each column corresponds to an MPI rank and each row corresponds to a segment in the PDVec.

Supported operations

See also: SegmentedBuffer.

source
Rimu.DictVectors.PointToPointType
PointToPoint{K,V}(; mpi_comm, report) <: Communicator

MPI Communicator that uses circular communication using MPI.Isend and MPI.Recv!.

Keyword arguments

  • mpi_comm=MPI.COMM_WORLD: the MPI communicator to use.
  • report=false: if set to true, report MPI communication times during a projector Monte Carlo run.
source
Rimu.DictVectors.SegmentedBufferType
SegmentedBuffer{T}() <: AbstractVector{AbstractVector{T}}

Behaves like a vector of vectors, but is stored in a single buffer. It can be sent/received over MPI keeping its structure intact. Used in the PointToPoint communication strategy.

Supported operations

See also: NestedSegmentedBuffer.

source
Rimu.DictVectors.mpi_recv_any!Method
mpi_recv_any!(buf::SegmentedBuffer, comm::MPI_Comm) -> Int

Find a source that is ready to send a buffer and receive from it. Return the rank ID of the sender.

source
Rimu.DictVectors.replace_collections!Method
replace_collections!(buf::SegmentedBuffer, iters)

Insert collections in iters into a SegmentedBuffer.

julia> using Rimu.DictVectors: SegmentedBuffer
 
 julia> buf = SegmentedBuffer{Int}()
 0-element SegmentedBuffer{Int64}
@@ -95,4 +95,4 @@
 3-element SegmentedBuffer{Int64}:
  [1]
  [2, 3]
- [4]
source
Rimu.DictVectors.target_segmentMethod
target_segment(c::Communicator, k, num_segments) -> target, is_local

This function is used to determine where in the PDVec a key should be stored. If the key is local (stored on the same MPI rank), return its segment index and true. If the key is non-local, return any value and false.

See also: PDVec, Communicator.

source

Index

+ [4]
source
Rimu.DictVectors.target_segmentMethod
target_segment(c::Communicator, k, num_segments) -> target, is_local

This function is used to determine where in the PDVec a key should be stored. If the key is local (stored on the same MPI rank), return its segment index and true. If the key is non-local, return any value and false.

See also: PDVec, Communicator.

source

Index

diff --git a/previews/PR308/documentation.html b/previews/PR308/documentation.html index d13758766..f2a894244 100644 --- a/previews/PR308/documentation.html +++ b/previews/PR308/documentation.html @@ -1,4 +1,4 @@ Documentation generation · Rimu.jl

Documentation generation

We are using Documenter.jl to generate the documentation web site based on markdown files stored in docs/src. Please help keeping the documentation up-to-date by editing the markdown files! For instructions on how to write appropriate documentation please refer to the relevant chapter in the Julia documentation and the Documenter.jl documentation.

Generating the documentation web site

The documentation pages can be generated by running the build script by typing

Rimu$ julia --project=docs docs/make.jl

on the shell prompt from the Rimu/ folder. A complete image of the static documentation web site will be generated in the folder docs/build/. It can be viewed locally by pointing a web browser to file docs/build/index.html, or by deploying it to the GitHub pages web server.

Automatic documentation generation and deployment

Our documentation is hosted on GitHub pages. The documentation web site can be built and deployed automatically with GitHub Actions. This needs to be set up with an appropriate script in the file .github/workflows/docs.yml, where triggers for this to happen can be defined. In the current set up, a new documentation web site is generated and deployed whenever someone pushes to the develop branch on the GitHub server. The updated documentation can then be accessed here.

Previews for pull-requests can be accessed by replacing 101 in the following link with the PR number: https://RimuQMC.github.io/Rimu.jl/previews/PR101/

Example scripts

Examples should be added to the scripts folder, in the form of .jl files suitable for parsing by Literate. The process of generating documentation is automated in the docs/make.jl file and assumes that the following line is at (or near) the top of the script:

# # Example N: Title

where the number N and Title will be extracted automatically.

Tests for the results and output of specific scripts should be added at the end of each example. The code to run the test should be hidden from the final generated document by appending "#hide" to each line of testing code. For example,

using Test                          #hide
 @test isfile("result.out")          #hide
-@test result == expected_result     #hide
+@test result == expected_result #hide diff --git a/previews/PR308/exactdiagonalization.html b/previews/PR308/exactdiagonalization.html index 0d37951c7..213795aa0 100644 --- a/previews/PR308/exactdiagonalization.html +++ b/previews/PR308/exactdiagonalization.html @@ -1,5 +1,5 @@ -Exact Diagonalization · Rimu.jl

Exact Diagonalization

The main functionality of Rimu for exact diagonalization is contained in the module ExactDiagonalization.

Rimu.ExactDiagonalizationModule

The module Rimu.ExactDiagonalization provides a framework for exact diagonalization of quantum many-body systems defined by an AbstractHamiltonian type.

The main usage is through defining an ExactDiagonalizationProblem and solving it with the solve function. The module provides a unified interface for accessing different solver algorithms, which make use of solvers provided by external packages.

Exports

source

ExactDiagonalizationProblem

Rimu.ExactDiagonalization.ExactDiagonalizationProblemType
ExactDiagonalizationProblem(hamiltonian::AbstractHamiltonian, [v0]; kwargs...)

Defines an exact diagonalization problem with an AbstractHamiltonian hamiltonian. Optionally, a starting vector of type AbstractDVec, or a single address or a collection of addresses can be passed as v0.

ExactDiagonalizationProblems can be solved with solve.

Keyword arguments

  • algorithm=LinearAlgebraSolver(): The algorithm to use for solving the problem. The algorithm can also be specified as the second positional argument in the init function.
  • Optional keyword arguments will be passed on to the init and solve functions.

Algorithms

  • LinearAlgebraSolver(): An algorithm for solving the problem using the dense-matrix eigensolver from the LinearAlgebra standard library (eventually using LAPACK). Only suitable for small matrices.
  • KrylovKitSolver(matrix_free=true): An algorithm for finding a few eigenvalues and vectors. With matrix_free=true the problem is solved without instatiating a matrix. This is suitable for large dimensions. With matrix_free=false the problem is solved after instantiating a sparse matrix. This is faster if sufficient memory is available. Requires using KrylovKit.
  • ArpackSolver(): An algorithm for solving the problem after instantiating a sparse matrix and using the Arpack Fortran library. Requires using Arpack.
  • LOBPCGSolver(): An algorithm for solving the problem after instantiating a sparse matrix using the LOBPCG method. Requires using IterativeSolvers.

Keyword arguments for matrix-based algorithms (also accepted by init)

See BasisSetRepresentation for more information.

  • sizelim: The maximum size of the basis set representation. The default is 10^6 for sparse matrices and 10^5 for dense matrices.
  • cutoff: A cutoff value for the basis set representation.
  • filter: A filter function for the basis set representation.
  • max_depth = Inf: Limit the depth when building the matrix.
  • minimum_size = Inf: Stop building the matrix after this size is reached.
  • nnzs = 0: A hint for the number of non-zero elements in the basis set representation. Setting a non-zero value can speed up the computation.
  • col_hint = 0: A hint for the number of columns in the basis set representation.
  • sort = false: Whether to sort the basis set representation.

Keyword arguments for iterative algorithms (also accepted by solve)

  • verbose = false: Whether to print additional information.
  • abstol = nothing: The absolute tolerance for the solver. If nothing, the solver chooses a default value.
  • howmany = 1: The minimum number of eigenvalues to compute.
  • which = :SR: Whether to compute the largest or smallest eigenvalues.
  • maxiters = nothing: The maximum number of iterations for the solver. If nothing, the solver chooses a default value.

Solving an ExactDiagonalizationProblem

The solve function can be called directly on an ExactDiagonalizationProblem to solve it. Alternatively, the init function can be used to initialize a solver, which can then be solved with solve. The solve function returns a result type with the eigenvalues, eigenvectors, and convergence information.

Result type

The result type for the solve function is determined by the algorithm used. It has the following fields:

  • values::Vector: The eigenvalues.
  • vectors::Vector{<:AbstractDVec}: The eigenvectors.
  • success::Bool: A boolean flag indicating whether the solver was successful.
  • info: Convergence information.
  • algorithm: The algorithm used for the computation.
  • problem: The ExactDiagonalizationProblem that was solved.
  • Additional fields may be present depending on the algorithm used.

Iterating the result type will yield the eigenvalues, eigenvectors, and a boolean flag success in that order.

Examples

julia> p = ExactDiagonalizationProblem(HubbardReal1D(BoseFS(1,1,1)))
+Exact Diagonalization · Rimu.jl

Exact Diagonalization

The main functionality of Rimu for exact diagonalization is contained in the module ExactDiagonalization.

Rimu.ExactDiagonalizationModule

The module Rimu.ExactDiagonalization provides a framework for exact diagonalization of quantum many-body systems defined by an AbstractHamiltonian type.

The main usage is through defining an ExactDiagonalizationProblem and solving it with the solve function. The module provides a unified interface for accessing different solver algorithms, which make use of solvers provided by external packages.

Exports

source

ExactDiagonalizationProblem

Rimu.ExactDiagonalization.ExactDiagonalizationProblemType
ExactDiagonalizationProblem(hamiltonian::AbstractHamiltonian, [v0]; kwargs...)

Defines an exact diagonalization problem with an AbstractHamiltonian hamiltonian. Optionally, a starting vector of type AbstractDVec, or a single address or a collection of addresses can be passed as v0.

ExactDiagonalizationProblems can be solved with solve.

Keyword arguments

  • algorithm=LinearAlgebraSolver(): The algorithm to use for solving the problem. The algorithm can also be specified as the second positional argument in the init function.
  • Optional keyword arguments will be passed on to the init and solve functions.

Algorithms

  • LinearAlgebraSolver(): An algorithm for solving the problem using the dense-matrix eigensolver from the LinearAlgebra standard library (eventually using LAPACK). Only suitable for small matrices.
  • KrylovKitSolver(matrix_free=true): An algorithm for finding a few eigenvalues and vectors. With matrix_free=true the problem is solved without instatiating a matrix. This is suitable for large dimensions. With matrix_free=false the problem is solved after instantiating a sparse matrix. This is faster if sufficient memory is available. Requires using KrylovKit.
  • ArpackSolver(): An algorithm for solving the problem after instantiating a sparse matrix and using the Arpack Fortran library. Requires using Arpack.
  • LOBPCGSolver(): An algorithm for solving the problem after instantiating a sparse matrix using the LOBPCG method. Requires using IterativeSolvers.

Keyword arguments for matrix-based algorithms (also accepted by init)

See BasisSetRepresentation for more information.

  • sizelim: The maximum size of the basis set representation. The default is 10^6 for sparse matrices and 10^5 for dense matrices.
  • cutoff: A cutoff value for the basis set representation.
  • filter: A filter function for the basis set representation.
  • max_depth = Inf: Limit the depth when building the matrix.
  • minimum_size = Inf: Stop building the matrix after this size is reached.
  • nnzs = 0: A hint for the number of non-zero elements in the basis set representation. Setting a non-zero value can speed up the computation.
  • col_hint = 0: A hint for the number of columns in the basis set representation.
  • sort = false: Whether to sort the basis set representation.

Keyword arguments for iterative algorithms (also accepted by solve)

  • verbose = false: Whether to print additional information.
  • abstol = nothing: The absolute tolerance for the solver. If nothing, the solver chooses a default value.
  • howmany = 1: The minimum number of eigenvalues to compute.
  • which = :SR: Whether to compute the largest or smallest eigenvalues.
  • maxiters = nothing: The maximum number of iterations for the solver. If nothing, the solver chooses a default value.

Solving an ExactDiagonalizationProblem

The solve function can be called directly on an ExactDiagonalizationProblem to solve it. Alternatively, the init function can be used to initialize a solver, which can then be solved with solve. The solve function returns a result type with the eigenvalues, eigenvectors, and convergence information.

Result type

The result type for the solve function is determined by the algorithm used. It has the following fields:

  • values::Vector: The eigenvalues.
  • vectors::Vector{<:AbstractDVec}: The eigenvectors.
  • success::Bool: A boolean flag indicating whether the solver was successful.
  • info: Convergence information.
  • algorithm: The algorithm used for the computation.
  • problem: The ExactDiagonalizationProblem that was solved.
  • Additional fields may be present depending on the algorithm used.

Iterating the result type will yield the eigenvalues, eigenvectors, and a boolean flag success in that order.

Examples

julia> p = ExactDiagonalizationProblem(HubbardReal1D(BoseFS(1,1,1)))
 ExactDiagonalizationProblem(
   HubbardReal1D(fs"|1 1 1⟩"; u=1.0, t=1.0),
   nothing;
@@ -26,8 +26,8 @@
 julia> values, vectors, success = solve(s);
 
 julia> result.values[1] ≈ values[1]
-true

See also solve(::ExactDiagonalizationProblem), init(::ExactDiagonalizationProblem), KrylovKitSolver, ArpackSolver, LinearAlgebraSolver.

Note

Using the KrylovKitSolver() algorithms requires the KrylovKit.jl package. The package can be loaded with using KrylovKit. Using the ArpackSolver() algorithm requires the Arpack.jl package. The package can be loaded with using Arpack. Using the LOBPCGSolver() algorithm requires the IterativeSolvers.jl package. The package can be loaded with using IterativeSolvers.

source

Solver algorithms

Rimu.ExactDiagonalization.KrylovKitSolverType
KrylovKitSolver(matrix_free::Bool; kwargs...)
-KrylovKitSolver(; matrix_free = false, kwargs...)

Algorithm for solving a large ExactDiagonalizationProblem to find a few eigenvalues and vectors using the KrylovKit.jl package. The Lanczos method is used for hermitian matrices, and the Arnoldi method is used for non-hermitian matrices.

Arguments

  • matrix_free = false: Whether to use a matrix-free algorithm. If false, a sparse matrix will be instantiated. This is typically faster and recommended for small matrices, but requires more memory. If true, the matrix is not instantiated, which is useful for large matrices that would not fit into memory. The calculation will parallelise using threading and MPI if available by making use of PDVec.
  • kwargs: Additional keyword arguments are passed on to the function KrylovKit.eigsolve().

See also ExactDiagonalizationProblem, solve.

Note

Requires the KrylovKit.jl package to be loaded with using KrylovKit.

source
Rimu.ExactDiagonalization.LinearAlgebraSolverType
LinearAlgebraSolver(; kwargs...)

Algorithm for solving an ExactDiagonalizationProblem using the dense-matrix eigensolver from the LinearAlgebra standard library. This is only suitable for small matrices.

The kwargs are passed on to function LinearAlgebra.eigen.

Keyword arguments

  • permute = true: Whether to permute the matrix before diagonalization.
  • scale = true: Whether to scale the matrix before diagonalization.
  • sortby: The sorting order for the eigenvalues.

See also ExactDiagonalizationProblem, solve.

source
Rimu.ExactDiagonalization.ArpackSolverType
ArpackSolver(; kwargs...)

Algorithm for solving an ExactDiagonalizationProblem after instantiating a sparse matrix. It uses the Lanzcos method for hermitian problems, and the Arnoldi method for non-hermitian problems, using the Arpack Fortran library. This is faster than KrylovKitSolver(; matrix_free=true), but it requires more memory and will only be useful if the matrix fits into memory.

The kwargs are passed on to the function Arpack.eigs().

See also ExactDiagonalizationProblem, solve.

Note

Requires the Arpack.jl package to be loaded with using Arpack.

source
Rimu.ExactDiagonalization.LOBPCGSolverType
LOBPCGSolver(; kwargs...)

The Locally Optimal Block Preconditioned Conjugate Gradient Method (LOBPCG). Algorithm for solving an ExactDiagonalizationProblem after instantiating a sparse matrix.

LOBPCG is not suitable for non-hermitian eigenvalue problems.

The kwargs are passed on to the function IterativeSolvers.lobpcg().

See also ExactDiagonalizationProblem, solve.

Note

Requires the IterativeSolvers.jl package to be loaded with using IterativeSolvers.

source

Converting a Hamiltonian in to a matrix

Rimu.ExactDiagonalization.BasisSetRepresentationType
BasisSetRepresentation(
+true

See also solve(::ExactDiagonalizationProblem), init(::ExactDiagonalizationProblem), KrylovKitSolver, ArpackSolver, LinearAlgebraSolver.

Note

Using the KrylovKitSolver() algorithms requires the KrylovKit.jl package. The package can be loaded with using KrylovKit. Using the ArpackSolver() algorithm requires the Arpack.jl package. The package can be loaded with using Arpack. Using the LOBPCGSolver() algorithm requires the IterativeSolvers.jl package. The package can be loaded with using IterativeSolvers.

source

Solver algorithms

Rimu.ExactDiagonalization.KrylovKitSolverType
KrylovKitSolver(matrix_free::Bool; kwargs...)
+KrylovKitSolver(; matrix_free = false, kwargs...)

Algorithm for solving a large ExactDiagonalizationProblem to find a few eigenvalues and vectors using the KrylovKit.jl package. The Lanczos method is used for hermitian matrices, and the Arnoldi method is used for non-hermitian matrices.

Arguments

  • matrix_free = false: Whether to use a matrix-free algorithm. If false, a sparse matrix will be instantiated. This is typically faster and recommended for small matrices, but requires more memory. If true, the matrix is not instantiated, which is useful for large matrices that would not fit into memory. The calculation will parallelise using threading and MPI if available by making use of PDVec.
  • kwargs: Additional keyword arguments are passed on to the function KrylovKit.eigsolve().

See also ExactDiagonalizationProblem, solve.

Note

Requires the KrylovKit.jl package to be loaded with using KrylovKit.

source
Rimu.ExactDiagonalization.LinearAlgebraSolverType
LinearAlgebraSolver(; kwargs...)

Algorithm for solving an ExactDiagonalizationProblem using the dense-matrix eigensolver from the LinearAlgebra standard library. This is only suitable for small matrices.

The kwargs are passed on to function LinearAlgebra.eigen.

Keyword arguments

  • permute = true: Whether to permute the matrix before diagonalization.
  • scale = true: Whether to scale the matrix before diagonalization.
  • sortby: The sorting order for the eigenvalues.

See also ExactDiagonalizationProblem, solve.

source
Rimu.ExactDiagonalization.ArpackSolverType
ArpackSolver(; kwargs...)

Algorithm for solving an ExactDiagonalizationProblem after instantiating a sparse matrix. It uses the Lanzcos method for hermitian problems, and the Arnoldi method for non-hermitian problems, using the Arpack Fortran library. This is faster than KrylovKitSolver(; matrix_free=true), but it requires more memory and will only be useful if the matrix fits into memory.

The kwargs are passed on to the function Arpack.eigs().

See also ExactDiagonalizationProblem, solve.

Note

Requires the Arpack.jl package to be loaded with using Arpack.

source
Rimu.ExactDiagonalization.LOBPCGSolverType
LOBPCGSolver(; kwargs...)

The Locally Optimal Block Preconditioned Conjugate Gradient Method (LOBPCG). Algorithm for solving an ExactDiagonalizationProblem after instantiating a sparse matrix.

LOBPCG is not suitable for non-hermitian eigenvalue problems.

The kwargs are passed on to the function IterativeSolvers.lobpcg().

See also ExactDiagonalizationProblem, solve.

Note

Requires the IterativeSolvers.jl package to be loaded with using IterativeSolvers.

source

Converting a Hamiltonian in to a matrix

Rimu.ExactDiagonalization.BasisSetRepresentationType
BasisSetRepresentation(
     hamiltonian::AbstractHamiltonian, addr=starting_address(hamiltonian);
     sizelim=10^7, cutoff, filter, max_depth, minimum_size, sort=false, kwargs...
 )
@@ -61,15 +61,15 @@
 DVec{BoseFS{1, 3, BitString{3, 1, UInt8}},Float64} with 3 entries, style = IsDeterministic{Float64}()
   fs"|0 0 1⟩" => 0.57735
   fs"|0 1 0⟩" => 0.57735
-  fs"|1 0 0⟩" => 0.57735

Has methods for dimension, sparse, Matrix, starting_address.

Part of the AbstractHamiltonian interface. See also build_basis.

source
Rimu.ExactDiagonalization.build_basisFunction
build_basis(
     ham, address=starting_address(ham);
     cutoff, filter, sizelim, sort=false, kwargs...
 ) -> basis
 build_basis(ham, addresses::AbstractVector; kwargs...)

Get all basis element of a linear operator ham that are reachable (via non-zero matrix elements) from the address address, returned as a vector. Instead of a single address, a vector of addresses can be passed. Does not return the matrix, for that purpose use BasisSetRepresentation.

Providing an energy cutoff will skip addresses with diagonal elements greater than cutoff. Alternatively, an arbitrary filter function can be used instead. Addresses passed as arguments are not filtered.

Providing a max_depth will limit the size of the basis by only visiting addresses that are connected to the starting_address through max_depth hops through the Hamiltonian. Similarly, providing minimum_size will stop the bulding process after the basis reaches a length of at least minimum_size.

A maximum basis size sizelim can be set which will throw an error if the expected dimension of ham is larger than sizelim. This may be useful when memory may be a concern. These options are disabled by default.

Warning
The order the basis is returned in is arbitrary and non-deterministic. Use
-`sort=true` if the ordering matters.
source
build_basis(addr::AbstractFockAddress)
-build_basis(::Type{<:AbstractFockAddress}) -> basis

Return all possible Fock states of a given type as a vector. This method is much faster than build_basis(::AbstractHamiltonian, ...), but does not take matrix blocking into account. This version of build_basis accepts no additional arguments.

All address types except OccupationNumberFS are supported.

Returns a sorted vector of length equal to the dimension of addr.

See also AbstractFockAddress.

source
Base.MatrixType
Matrix(
+`sort=true` if the ordering matters.
source
build_basis(addr::AbstractFockAddress)
+build_basis(::Type{<:AbstractFockAddress}) -> basis

Return all possible Fock states of a given type as a vector. This method is much faster than build_basis(::AbstractHamiltonian, ...), but does not take matrix blocking into account. This version of build_basis accepts no additional arguments.

All address types except OccupationNumberFS are supported.

Returns a sorted vector of length equal to the dimension of addr.

See also AbstractFockAddress.

source

Deprecated

+Matrix(bsr::BasisSetRepresentation)

Return a dense matrix representation of hamiltonian or bsr. kwargs are passed to BasisSetRepresentation.

See BasisSetRepresentation.

source
SparseArrays.sparseFunction
sparse(hamiltonian::AbstractHamiltonian, addr=starting_address(hamiltonian); kwargs...)
+sparse(bsr::BasisSetRepresentation)

Return a sparse matrix representation of hamiltonian or bsr. kwargs are passed to BasisSetRepresentation.

See BasisSetRepresentation.

source

Deprecated

Rimu.ExactDiagonalization.BasisSetRepFunction
BasisSetRep(args...; kwargs...)

BasisSetRep is deprecated. Use BasisSetRepresentation instead.

source
diff --git a/previews/PR308/generated/BHM-example-mpi.html b/previews/PR308/generated/BHM-example-mpi.html index 7435e72c7..2cc1b0e2f 100644 --- a/previews/PR308/generated/BHM-example-mpi.html +++ b/previews/PR308/generated/BHM-example-mpi.html @@ -14,4 +14,4 @@

Finally, we can run the computation.

simulation = solve(problem);
 
 @mpi_root println("Simulation success = ", simulation.success)
Simulation success = true
-

Once the calculation is done, the results are available in the arrow file on disk.

In a typical workflow, the simulation results would be loaded from disk and analysed in the REPL or with a separate script. The arrow file can be loaded into a DataFrame with metadata using the load_df function.


This page was generated using Literate.jl.

+

Once the calculation is done, the results are available in the arrow file on disk.

In a typical workflow, the simulation results would be loaded from disk and analysed in the REPL or with a separate script. The arrow file can be loaded into a DataFrame with metadata using the load_df function.


This page was generated using Literate.jl.

diff --git a/previews/PR308/generated/BHM-example.html b/previews/PR308/generated/BHM-example.html index 65eaa5c4c..8c70f21e0 100644 --- a/previews/PR308/generated/BHM-example.html +++ b/previews/PR308/generated/BHM-example.html @@ -18,60 +18,60 @@ plot!(df.step, df.norm, label="norm", color=1) - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + +

After an initial equilibriation period, the norm fluctuates around the target number of walkers.

Now, let's look at using the shift to estimate the ground state energy of H. The mean of the shift is a useful estimator of the energy. Calculating the error bars is a bit more involved as autocorrelations have to be removed from the time series. This can be done with the function shift_estimator, which performs a blocking analysis on the shift column of the dataframe.

se = shift_estimator(df; skip=steps_equilibrate)
BlockingResult{Float64}
-  mean = -4.029 ± 0.026
-  with uncertainty of ± 0.002331601728257115
+  mean = -4.041 ± 0.025
+  with uncertainty of ± 0.002249521709283463
   from 62 blocks after 5 transformations (k = 6).
 

Here, se contains the calculated mean and standard errors of the shift, as well as some additional information related to the blocking analysis.

Computing the error of the projected energy is a bit more complicated, as it's a ratio of fluctuating variables contained in the hproj and vproj columns in the dataframe. Thankfully, the complications are handled by the function projected_energy.

pe = projected_energy(df; skip=steps_equilibrate)
RatioBlockingResult{Float64,MonteCarloMeasurements.Particles{Float64, 2000}}
-  ratio = -4.01374 ± (0.00182987, 0.00200136) (MC)
-  95% confidence interval: [-4.01757, -4.01008] (MC)
-  linear error propagation: -4.01384 ± 0.00189423
-  |δ_y| = |0.00172589| (≤ 0.1 for normal approx)
-  Blocking successful with 31 blocks after 6 transformations (k = 7).
-

The result is a ratio distribution. We extract its median and the edges of the 95% confidence interval.

v = val_and_errs(pe; p=0.95)
(val = -4.0137380929613204, val_l = 0.003831426778932112, val_u = 0.0036566501605630464)

Let's visualise these estimators together with the time series of the shift.

plot(df.step, df.shift, ylabel="energy", xlabel="step", label="shift", margin = 1Plots.cm)
+  ratio = -4.01331 ± (0.00328573, 0.00353296) (MC)
+  95% confidence interval: [-4.02063, -4.00652] (MC)
+  linear error propagation: -4.01353 ± 0.00354394
+  |δ_y| = |0.00322799| (≤ 0.1 for normal approx)
+  Blocking successful with 15 blocks after 7 transformations (k = 8).
+

The result is a ratio distribution. We extract its median and the edges of the 95% confidence interval.

v = val_and_errs(pe; p=0.95)
(val = -4.013309070980869, val_l = 0.007319929452815899, val_u = 0.006792034209384568)

Let's visualise these estimators together with the time series of the shift.

plot(df.step, df.shift, ylabel="energy", xlabel="step", label="shift", margin = 1Plots.cm)
 
 plot!(x->se.mean, df.step[steps_equilibrate+1:end], ribbon=se.err, label="shift mean")
 plot!(
@@ -81,89 +81,89 @@
 lens!([steps_equilibrate, last_step], [-5.1, -2.9]; inset=(1, bbox(0.2, 0.25, 0.6, 0.4)))
- + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + +

In this case the projected energy and the shift are close to each other and the error bars are hard to see.

The problem was just a toy example, as the dimension of the Hamiltonian is rather small:

dimension(H)
462

In this case, it's easy (and more efficient) to calculate the exact ground state energy using standard linear algebra. Read more about Rimu's capabilities for exact diagonalization in the example "Exact diagonalization".

edp = ExactDiagonalizationProblem(H)
 exact_energy = solve(edp).values[1]
-4.021502406906473

We finish by comparing our FCIQMC results with the exact computation.

println(
@@ -176,8 +176,8 @@
 )
 
 
Energy from 2000 steps with 1000 walkers:
-Shift: -4.029305674616693 ± 0.025753382836897584
-Projected Energy: -4.0137380929613204 ± (0.003831426778932112, 0.0036566501605630464)
+Shift: -4.041259061220064 ± 0.02484677939503602
+Projected Energy: -4.013309070980869 ± (0.007319929452815899, 0.006792034209384568)
 Exact Energy: -4.021502406906473
 
-

This page was generated using Literate.jl.

+

This page was generated using Literate.jl.

diff --git a/previews/PR308/generated/G2-example.html b/previews/PR308/generated/G2-example.html index 5ff0aa978..5bbe85f3a 100644 --- a/previews/PR308/generated/G2-example.html +++ b/previews/PR308/generated/G2-example.html @@ -25,19 +25,19 @@ r = rayleigh_replica_estimator(df; op_name = "Op$(d+1)", skip=steps_equilibrate) println(" G2($d) = $(r.f) ± $(r.σ_f)") end
Two-body correlator from 3 replicas:
-   G2(0) = 0.21588758691561244 ± 0.0017906745443117286
-   G2(1) = 0.9162852152091748 ± 0.0011106368247895651
-   G2(2) = 0.9820537989355586 ± 0.0006230997601880472
-   G2(3) = 0.9874343847949214 ± 0.0009189444068620799
-   G2(4) = 0.9820537989355586 ± 0.0006230997601880472
-   G2(5) = 0.9162852152091748 ± 0.0011106368247895651
+   G2(0) = 0.20880526675490996 ± 0.001650235029310676
+   G2(1) = 0.9187078655187123 ± 0.0007600488432629197
+   G2(2) = 0.9821782165945223 ± 0.0006972126484492098
+   G2(3) = 0.9894225690186212 ± 0.0009186561663562719
+   G2(4) = 0.9821782165945223 ± 0.0006972126484492098
+   G2(5) = 0.9187078655187123 ± 0.0007600488432629197
 

As expected, the onsite correlation at $d=0$ is low since this is a Mott insulating state with unit filling fraction, and is close to $1.0$ for all other values of the displacement $d$.

Since we ran multiple independent replicas, we also have multiple estimates of the shift energy.

println("Shift energy from $n_replicas replicas:")
 for i in 1:n_replicas
     se = shift_estimator(df; shift="shift_$i", skip=steps_equilibrate)
     println("   Replica $i: $(se.mean) ± $(se.err)")
 end
 
Shift energy from 3 replicas:
-   Replica 1: -4.016337436606625 ± 0.11880763464913646
-   Replica 2: -4.044163449484755 ± 0.13015222463254772
-   Replica 3: -4.06405078692469 ± 0.1267785087026866
-

This page was generated using Literate.jl.

+ Replica 1: -4.0481027033902715 ± 0.14022744896804235 + Replica 2: -3.999175246993472 ± 0.1440589169512744 + Replica 3: -4.004366054970122 ± 0.13757576512903064 +

This page was generated using Literate.jl.

diff --git a/previews/PR308/generated/HO-example.html b/previews/PR308/generated/HO-example.html index ea71a8b74..6c3ca7cf3 100644 --- a/previews/PR308/generated/HO-example.html +++ b/previews/PR308/generated/HO-example.html @@ -5,7 +5,7 @@ M = 4;

Use a tuple S to define the range of harmonic oscillator states in a Cartesian basis, in this isotropic case $n_x,n_y=0,1,\ldots,M-1$.

S = (M, M);

In Rimu the $N$-particle states are still stored as Fock states.

P = prod(S)
 addr = BoseFS(P, M => N)
BoseFS{2,16}(0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)

Here, the numbering of the modes folds in the two spatial dimensions. Use the utility function fock_to_cart to convert a Fock address to human-readable Cartesian quantum numbers for inspection.

fock_to_cart(addr, S)
2-element StaticArraysCore.SVector{2, Tuple{Int64, Int64}} with indices SOneTo(2):
  (3, 0)
- (3, 0)

The output shows that all $N$ particles are in single-particle state $n_x=M-1, n_y=0$.

The harmonic oscillator Hamiltonian HOCartesianContactInteractions handles contact interactions with first-order perturbation theory, so the matrix representation will block according to the non-interacting energy of the basis states. The first task is to find all blocks of basis states with the same energy. The strength of the interaction is not relevant at this point, just that it is non-zero. Use an arbitrary N-particle starting address to build the Hamiltonian.

H = HOCartesianContactInteractions(BoseFS(P, 1 => N); S);

Then, use the utility function get_all_blocks to find all blocks. The blocks are found by looping over all possible states with N particles in Cartesian states defined by S. Note that this will only work for total energy up to the maximum accessible by a single particle. The $N$-particle groundstate energy for a 2D harmonic oscillator is $E_0 = N \hbar \omega$ and the maximum single-particle energy is $E = (E_0 + M - 1) \hbar \omega$.

block_df = get_all_blocks(H; max_energy = N + M - 1)
7×6 DataFrame
Rowblock_idblock_E0block_sizeaddrindicest_basis
Int64Float64Int64BoseFS…Tuple…Float64
112.01fs"|2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0⟩"(1, 1)1.12114
223.01fs"|1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0⟩"(2, 1)3.4755e-5
334.04fs"|0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0⟩"(2, 2)2.1049e-5
445.05fs"|0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0⟩"(3, 2)1.5679e-5
553.01fs"|1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0⟩"(5, 1)3.557e-6
664.02fs"|0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0⟩"(5, 2)7.003e-6
775.05fs"|0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0⟩"(5, 3)1.4186e-5

This outputs a list of blocks in H indexed by the noninteracting energy of all states in the block, and a single address that can be used to rebuild the block for further analysis.

addr1 = block_df[7,:addr]
+ (3, 0)

The output shows that all $N$ particles are in single-particle state $n_x=M-1, n_y=0$.

The harmonic oscillator Hamiltonian HOCartesianContactInteractions handles contact interactions with first-order perturbation theory, so the matrix representation will block according to the non-interacting energy of the basis states. The first task is to find all blocks of basis states with the same energy. The strength of the interaction is not relevant at this point, just that it is non-zero. Use an arbitrary N-particle starting address to build the Hamiltonian.

H = HOCartesianContactInteractions(BoseFS(P, 1 => N); S);

Then, use the utility function get_all_blocks to find all blocks. The blocks are found by looping over all possible states with N particles in Cartesian states defined by S. Note that this will only work for total energy up to the maximum accessible by a single particle. The $N$-particle groundstate energy for a 2D harmonic oscillator is $E_0 = N \hbar \omega$ and the maximum single-particle energy is $E = (E_0 + M - 1) \hbar \omega$.

block_df = get_all_blocks(H; max_energy = N + M - 1)
7×6 DataFrame
Rowblock_idblock_E0block_sizeaddrindicest_basis
Int64Float64Int64BoseFS…Tuple…Float64
112.01fs"|2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0⟩"(1, 1)1.13502
223.01fs"|1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0⟩"(2, 1)3.4244e-5
334.04fs"|0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0⟩"(2, 2)3.0928e-5
445.05fs"|0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0⟩"(3, 2)1.5028e-5
553.01fs"|1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0⟩"(5, 1)3.657e-6
664.02fs"|0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0⟩"(5, 2)6.612e-6
775.05fs"|0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0⟩"(5, 3)1.3896e-5

This outputs a list of blocks in H indexed by the noninteracting energy of all states in the block, and a single address that can be used to rebuild the block for further analysis.

addr1 = block_df[7,:addr]
 E = block_df[7,:block_E0]
5.0

First, notice that all basis states have the same energy, defined by the block.

basis1 = build_basis(H, addr1)
 map(b -> Hamiltonians.noninteracting_energy(H, b), basis1)
5-element Vector{Float64}:
  5.0
@@ -59,4 +59,4 @@
   1.0625181290352691e-17
   0.15915494309189532
   0.15915494309189535
-  0.15915494309189543

Two eigenstates in this block are unaffected by the interaction and three have a non-zero energy shift.

The default strength of the interaction is g = 1.0. Other interactions strengths can be obtained by using keyword argument g in HOCartesianContactInteractions or by rescaling ΔE since the interactions are handled with first-order perturbation theory.

Rimu also contains HOCartesianEnergyConservedPerDim which is a similar Hamiltonian but with the stricter condition that the contact interaction only connects states that have the same total energy in each dimension, rather than conserving the overall total energy. Both Hamiltonians can handle anisotropic systems by passing a tuple S whose elements are not all the same. This will alter which states are connected by the interaction, but assumes that the harmonic trapping frequencies in each dimension are commensurate.


This page was generated using Literate.jl.

+ 0.15915494309189543

Two eigenstates in this block are unaffected by the interaction and three have a non-zero energy shift.

The default strength of the interaction is g = 1.0. Other interactions strengths can be obtained by using keyword argument g in HOCartesianContactInteractions or by rescaling ΔE since the interactions are handled with first-order perturbation theory.

Rimu also contains HOCartesianEnergyConservedPerDim which is a similar Hamiltonian but with the stricter condition that the contact interaction only connects states that have the same total energy in each dimension, rather than conserving the overall total energy. Both Hamiltonians can handle anisotropic systems by passing a tuple S whose elements are not all the same. This will alter which states are connected by the interaction, but assumes that the harmonic trapping frequencies in each dimension are commensurate.


This page was generated using Literate.jl.

diff --git a/previews/PR308/generated/exact-example.html b/previews/PR308/generated/exact-example.html index 3680c6171..cb33d7552 100644 --- a/previews/PR308/generated/exact-example.html +++ b/previews/PR308/generated/exact-example.html @@ -102,18 +102,18 @@ vals_kk, vecs_kk = eigsolve(sparse_matrix, num_eigvals, :SR) vals_kk
14-element Vector{Float64}:
- -6.979863998321633
- -3.3631242916133512
- -0.7590191922770817
-  0.13584182219620367
-  0.1578999869460933
-  0.8767114411781343
-  1.530592997097334
-  1.583573261186734
+ -6.979863998321601
+ -3.3631242916133672
+ -0.7590191922770995
+  0.1358418221962161
+  0.15789998694608265
+  0.8767114411781378
+  1.5305929970973278
+  1.583573261186741
   3.0728703303258706
-  3.125672653951841
-  4.862107221562171
-  6.2606948503805935
+  3.1256726539518347
+  4.862107221562172
+  6.260694850380597
   6.402671211183112
   9.093371706203957

Both solvers use variants of the Lanczos algorithm for Hermitian matrices and the Arnoldi algorithm for non-Hermitian ones. These may in some cases miss degenerate eigenpairs.

If diagonalization takes too long, you can reduce the tolerance by setting the tol keyword argument to eigs or eigsolve. Using drastically lower tolerances than the default can still produce good results in practice. This, however, should be checked on a case-by-case basis.

The matrix-free method

KrylovKit's eigsolve function is implemented in a way that does not require the linear operator and vector to be Julia arrays. Rimu leverages this functionality, which allows diagonalising Hamiltonians without ever needing to construct the matrix - all matrix elements are generated on the fly.

While this method is by far the slowest of the ones discussed, it also uses drastically less memory. This allows us to diagonalise much larger Hamiltonians.

To use this method, you first need a starting vector. It's best to use PDVec here as it leverages threading during the diagonalization.

dvec = PDVec(add => 1.0)
1-element PDVec: style = IsDeterministic{Float64}()
   fs"|0 0 4 0 0⟩" => 1.0

Then, pass that vector and the Hamiltonian to eigsolve.

vals_mf, vecs_mf = eigsolve(ham, dvec, num_eigvals, :SR; issymmetric=true)
@@ -162,4 +162,4 @@
  0.03307039977204201
  3.9204869225657397
  0.033070399772041965
- 0.006686138945087815

This page was generated using Literate.jl.

+ 0.006686138945087815

This page was generated using Literate.jl.

diff --git a/previews/PR308/hamiltonians.html b/previews/PR308/hamiltonians.html index a21f44ed4..414a685c4 100644 --- a/previews/PR308/hamiltonians.html +++ b/previews/PR308/hamiltonians.html @@ -1,27 +1,27 @@ -Hamiltonians · Rimu.jl

Module Hamiltonians

This module contains definitions of Hamiltonians, in particular specific physical models of interest. These are organised by means of an interface around the abstract type AbstractHamiltonian, in the spirit of the AbstractArray interface as discussed in the Julia Documentation.

The Hamiltonians can be used for projector quantum Monte Carlo with ProjectorMonteCarloProblem or for exact diagonalization with ExactDiagonalizationProblem, see Exact Diagonalization.

Rimu.HamiltoniansModule
source

Here is a list of fully implemented model Hamiltonians. There are several variants of the Hubbard model in real and momentum space, as well as some other models.

Real space Hubbard models

Rimu.Hamiltonians.HubbardReal1DType
HubbardReal1D(address; u=1.0, t=1.0)

Implements a one-dimensional Bose Hubbard chain in real space.

\[\hat{H} = -t \sum_{\langle i,j\rangle} a_i^† a_j + \frac{u}{2}\sum_i n_i (n_i-1)\]

Arguments

  • address: the starting address, defines number of particles and sites.
  • u: the interaction parameter.
  • t: the hopping strength.

See also

source
Rimu.Hamiltonians.HubbardReal1DEPType
HubbardReal1DEP(address; u=1.0, t=1.0, v_ho=1.0)

Implements a one-dimensional Bose Hubbard chain in real space with external potential.

\[\hat{H} = -t \sum_{\langle i,j\rangle} a_i^† a_j + \sum_i ϵ_i n_i -+ \frac{u}{2}\sum_i n_i (n_i-1)\]

Arguments

  • address: the starting address, defines number of particles and sites.
  • u: the interaction parameter.
  • t: the hopping strength.
  • v_ho: strength of the external harmonic oscillator potential $ϵ_i = v_{ho} i^2$.

The first index is i=0 and the maximum of the potential occurs in the centre of the lattice.

See also

source
Rimu.Hamiltonians.HubbardRealSpaceType
HubbardRealSpace(address; geometry=PeriodicBoundaries(M,), t=ones(C), u=ones(C, C), v=zeros(C, D))

Hubbard model in real space. Supports single or multi-component Fock state addresses (with C components) and various (rectangular) lattice geometries in D dimensions.

\[ \hat{H} = -\sum_{\langle i,j\rangle,σ} t_σ a^†_{iσ} a_{jσ} + +Hamiltonians · Rimu.jl

Module Hamiltonians

This module contains definitions of Hamiltonians, in particular specific physical models of interest. These are organised by means of an interface around the abstract type AbstractHamiltonian, in the spirit of the AbstractArray interface as discussed in the Julia Documentation.

The Hamiltonians can be used for projector quantum Monte Carlo with ProjectorMonteCarloProblem or for exact diagonalization with ExactDiagonalizationProblem, see Exact Diagonalization.

Rimu.HamiltoniansModule
source

Here is a list of fully implemented model Hamiltonians. There are several variants of the Hubbard model in real and momentum space, as well as some other models.

Real space Hubbard models

Rimu.Hamiltonians.HubbardReal1DType
HubbardReal1D(address; u=1.0, t=1.0)

Implements a one-dimensional Bose Hubbard chain in real space.

\[\hat{H} = -t \sum_{\langle i,j\rangle} a_i^† a_j + \frac{u}{2}\sum_i n_i (n_i-1)\]

Arguments

  • address: the starting address, defines number of particles and sites.
  • u: the interaction parameter.
  • t: the hopping strength.

See also

source
Rimu.Hamiltonians.HubbardReal1DEPType
HubbardReal1DEP(address; u=1.0, t=1.0, v_ho=1.0)

Implements a one-dimensional Bose Hubbard chain in real space with external potential.

\[\hat{H} = -t \sum_{\langle i,j\rangle} a_i^† a_j + \sum_i ϵ_i n_i ++ \frac{u}{2}\sum_i n_i (n_i-1)\]

Arguments

  • address: the starting address, defines number of particles and sites.
  • u: the interaction parameter.
  • t: the hopping strength.
  • v_ho: strength of the external harmonic oscillator potential $ϵ_i = v_{ho} i^2$.

The first index is i=0 and the maximum of the potential occurs in the centre of the lattice.

See also

source
Rimu.Hamiltonians.HubbardRealSpaceType
HubbardRealSpace(address; geometry=PeriodicBoundaries(M,), t=ones(C), u=ones(C, C), v=zeros(C, D))

Hubbard model in real space. Supports single or multi-component Fock state addresses (with C components) and various (rectangular) lattice geometries in D dimensions.

\[ \hat{H} = -\sum_{\langle i,j\rangle,σ} t_σ a^†_{iσ} a_{jσ} + \frac{1}{2}\sum_{i,σ} u_{σσ} n_{iσ} (n_{iσ} - 1) + - \sum_{i,σ≠τ}u_{στ} n_{iσ} n_{iτ}\]

If v is nonzero then this calculates $\hat{H} + \hat{V}$ by adding the harmonic trapping potential

\[ \hat{V} = \sum_{i,σ,d} v_{σd} x_{di}^2 n_{iσ}\]

where $x_{di}$ is the distance of site $i$ from the centre of the trap along dimension $d$.

Address types

  • BoseFS: Single-component Bose-Hubbard model.
  • FermiFS: Single-component Fermi-Hubbard model.
  • CompositeFS: For multi-component models.

Note that a single component of fermions cannot interact with itself. A warning is produced if addressis incompatible with the interaction parameters u.

Geometries

Implemented CubicGrids for keyword geometry

Default is geometry=PeriodicBoundaries(M,), i.e. a one-dimensional lattice with the number of sites M inferred from the number of modes in address.

Other parameters

  • t: the hopping strengths. Must be a vector of length C. The i-th element of the vector corresponds to the hopping strength of the i-th component.
  • u: the on-site interaction parameters. Must be a symmetric matrix. u[i, j] corresponds to the interaction between the i-th and j-th component. u[i, i] corresponds to the interaction of a component with itself. Note that u[i,i] must be zero for fermionic components.
  • v: the trap potential strengths. Must be a matrix of size C × D. v[i,j] is the strength of the trap for component i in the jth dimension.
source
Rimu.Hamiltonians.ExtendedHubbardReal1DType
ExtendedHubbardReal1D(address; u=1.0, v=1.0, t=1.0, boundary_condition=:periodic)

Implements the extended Hubbard model on a one-dimensional chain in real space. This Hamiltonian can be either real or complex, depending on the choice of boundary_condition.

\[\hat{H} = -t \sum_{\langle i,j\rangle} a_i^† a_j + \frac{u}{2}\sum_i n_i (n_i-1) + -v \sum_{\langle i,j\rangle} n_i n_j\]

Arguments

  • address: the starting address.
  • u: on-site interaction parameter
  • v: the next-neighbor interaction
  • t: the hopping strength
  • boundary_condition The following values are supported:
    • :periodic: usual period boundary condition realising a ring geometry.
    • :hard_wall: hopping over the boundary is not allowed.
    • :twisted: like :periodic but hopping over the boundary incurs an additional factor of -1.
    • θ <: Number: like :periodic and :twisted but hopping over the boundary incurs a factor $\exp(iθ)$ for a hop to the right and $\exp(−iθ)$ for a hop to the left. With this choice the Hamiltonian will have a complex eltype whereas otherwise the eltype is determined by the type of the parameters t, u, and v.

See also HubbardRealSpace.

source

Momentum space Hubbard models

Rimu.Hamiltonians.HubbardMom1DType
HubbardMom1D(address; u=1.0, t=1.0, dispersion=hubbard_dispersion)

Implements a one-dimensional Bose Hubbard chain in momentum space.

\[\hat{H} = \sum_{k} ϵ_k n_k + \frac{u}{M}\sum_{kpqr} a^†_{r} a^†_{q} a_p a_k δ_{r+q,p+k}\]

Arguments

  • address: the starting address, defines number of particles and sites.
  • u: the interaction parameter.
  • t: the hopping strength.
  • dispersion: defines $ϵ_k =$dispersion(t, k)

See also

source
Rimu.Hamiltonians.HubbardMom1DEPType
HubbardMom1DEP(address; u=1.0, t=1.0, v_ho=1.0, dispersion=hubbard_dispersion)

Implements a one-dimensional Bose Hubbard chain in momentum space with harmonic external potential.

\[Ĥ = \sum_{k} ϵ_k n_k + \frac{u}{M}\sum_{kpqr} a^†_{r} a^†_{q} a_p a_k δ_{r+q,p+k} + \sum_{i,σ≠τ}u_{στ} n_{iσ} n_{iτ}\]

If v is nonzero then this calculates $\hat{H} + \hat{V}$ by adding the harmonic trapping potential

\[ \hat{V} = \sum_{i,σ,d} v_{σd} x_{di}^2 n_{iσ}\]

where $x_{di}$ is the distance of site $i$ from the centre of the trap along dimension $d$.

Address types

  • BoseFS: Single-component Bose-Hubbard model.
  • FermiFS: Single-component Fermi-Hubbard model.
  • CompositeFS: For multi-component models.

Note that a single component of fermions cannot interact with itself. A warning is produced if addressis incompatible with the interaction parameters u.

Geometries

Implemented CubicGrids for keyword geometry

Default is geometry=PeriodicBoundaries(M,), i.e. a one-dimensional lattice with the number of sites M inferred from the number of modes in address.

Other parameters

  • t: the hopping strengths. Must be a vector of length C. The i-th element of the vector corresponds to the hopping strength of the i-th component.
  • u: the on-site interaction parameters. Must be a symmetric matrix. u[i, j] corresponds to the interaction between the i-th and j-th component. u[i, i] corresponds to the interaction of a component with itself. Note that u[i,i] must be zero for fermionic components.
  • v: the trap potential strengths. Must be a matrix of size C × D. v[i,j] is the strength of the trap for component i in the jth dimension.
source
Rimu.Hamiltonians.ExtendedHubbardReal1DType
ExtendedHubbardReal1D(address; u=1.0, v=1.0, t=1.0, boundary_condition=:periodic)

Implements the extended Hubbard model on a one-dimensional chain in real space. This Hamiltonian can be either real or complex, depending on the choice of boundary_condition.

\[\hat{H} = -t \sum_{\langle i,j\rangle} a_i^† a_j + \frac{u}{2}\sum_i n_i (n_i-1) + +v \sum_{\langle i,j\rangle} n_i n_j\]

Arguments

  • address: the starting address.
  • u: on-site interaction parameter
  • v: the next-neighbor interaction
  • t: the hopping strength
  • boundary_condition The following values are supported:
    • :periodic: usual period boundary condition realising a ring geometry.
    • :hard_wall: hopping over the boundary is not allowed.
    • :twisted: like :periodic but hopping over the boundary incurs an additional factor of -1.
    • θ <: Number: like :periodic and :twisted but hopping over the boundary incurs a factor $\exp(iθ)$ for a hop to the right and $\exp(−iθ)$ for a hop to the left. With this choice the Hamiltonian will have a complex eltype whereas otherwise the eltype is determined by the type of the parameters t, u, and v.

See also HubbardRealSpace.

source

Momentum space Hubbard models

Rimu.Hamiltonians.HubbardMom1DType
HubbardMom1D(address; u=1.0, t=1.0, dispersion=hubbard_dispersion)

Implements a one-dimensional Bose Hubbard chain in momentum space.

\[\hat{H} = \sum_{k} ϵ_k n_k + \frac{u}{M}\sum_{kpqr} a^†_{r} a^†_{q} a_p a_k δ_{r+q,p+k}\]

Arguments

  • address: the starting address, defines number of particles and sites.
  • u: the interaction parameter.
  • t: the hopping strength.
  • dispersion: defines $ϵ_k =$dispersion(t, k)

See also

source
Rimu.Hamiltonians.HubbardMom1DEPType
HubbardMom1DEP(address; u=1.0, t=1.0, v_ho=1.0, dispersion=hubbard_dispersion)

Implements a one-dimensional Bose Hubbard chain in momentum space with harmonic external potential.

\[Ĥ = \sum_{k} ϵ_k n_k + \frac{u}{M}\sum_{kpqr} a^†_{r} a^†_{q} a_p a_k δ_{r+q,p+k} + V̂_\mathrm{ho} ,\]

where

\[\begin{aligned} V̂_\mathrm{ho} & = \frac{1}{M} \sum_{p,q} \mathrm{DFT}[V_{ext}]_{p-q} \, a^†_{p} a_q ,\\ V_\mathrm{ext}(x) &= v_\mathrm{ho} \,x^2 , -\end{aligned}\]

is an external harmonic potential in momentum space, $\mathrm{DFT}[…]_k$ is a discrete Fourier transform performed by fft()[k%M + 1], and M == num_modes(address).

Arguments

  • address: the starting address, defines number of particles and sites.
  • u: the interaction parameter.
  • t: the hopping strength.
  • dispersion: defines $ϵ_k =$dispersion(t, k)
  • v_ho: strength of the external harmonic oscillator potential $v_\mathrm{ho}$.

See also HubbardMom1D, HubbardReal1DEP, Transcorrelated1D, Hamiltonians.

source
Rimu.Hamiltonians.ExtendedHubbardMom1DType
ExtendedHubbardMom1D(
+\end{aligned}\]

is an external harmonic potential in momentum space, $\mathrm{DFT}[…]_k$ is a discrete Fourier transform performed by fft()[k%M + 1], and M == num_modes(address).

Arguments

  • address: the starting address, defines number of particles and sites.
  • u: the interaction parameter.
  • t: the hopping strength.
  • dispersion: defines $ϵ_k =$dispersion(t, k)
  • v_ho: strength of the external harmonic oscillator potential $v_\mathrm{ho}$.

See also HubbardMom1D, HubbardReal1DEP, Transcorrelated1D, Hamiltonians.

source
Rimu.Hamiltonians.ExtendedHubbardMom1DType
ExtendedHubbardMom1D(
     address; 
     u=1.0, t=1.0, v=1.0, dispersion=hubbard_dispersion, boundary_condition = 0.0
-)

Implements a one-dimensional extended Hubbard chain, also known as the $t - V$ model, in momentum space.

\[\hat{H} = \sum_{k} ϵ_k n_k + \frac{1}{2M} \sum_{kpqr} (u + 2v \cos(q-p)) a^†_{r} a^†_{q} a_p a_k δ_{r+q,p+k}\]

Arguments

  • address: the starting address, defines number of particles and sites.

  • u: the interaction parameter.

  • t: the hopping strength.

  • boundary_condition: θ <: Number: hopping over the boundary incurs a factor $\exp(iθ)$ for a hop to the right and $\exp(−iθ)$ for a hop to the left.

  • dispersion: defines $ϵ_k =$dispersion(t, k + θ)

See also

source

Harmonic oscillator models

Rimu.Hamiltonians.HOCartesianContactInteractionsType
HOCartesianContactInteractions(addr; S, η, g = 1.0, interaction_only = false, block_by_level = true)

Implements a bosonic harmonic oscillator in Cartesian basis with contact interactions

\[\hat{H} = \sum_{i} \epsilon_\mathbf{i} n_\mathbf{i} + \frac{g}{2}\sum_\mathbf{ijkl} +)

Implements a one-dimensional extended Hubbard chain, also known as the $t - V$ model, in momentum space.

\[\hat{H} = \sum_{k} ϵ_k n_k + \frac{1}{2M} \sum_{kpqr} (u + 2v \cos(q-p)) a^†_{r} a^†_{q} a_p a_k δ_{r+q,p+k}\]

Arguments

  • address: the starting address, defines number of particles and sites.

  • u: the interaction parameter.

  • t: the hopping strength.

  • boundary_condition: θ <: Number: hopping over the boundary incurs a factor $\exp(iθ)$ for a hop to the right and $\exp(−iθ)$ for a hop to the left.

  • dispersion: defines $ϵ_k =$dispersion(t, k + θ)

See also

source

Harmonic oscillator models

Rimu.Hamiltonians.HOCartesianContactInteractionsType
HOCartesianContactInteractions(addr; S, η, g = 1.0, interaction_only = false, block_by_level = true)

Implements a bosonic harmonic oscillator in Cartesian basis with contact interactions

\[\hat{H} = \sum_{i} \epsilon_\mathbf{i} n_\mathbf{i} + \frac{g}{2}\sum_\mathbf{ijkl} V_\mathbf{ijkl} a^†_\mathbf{i} a^†_\mathbf{j} a_\mathbf{k} a_\mathbf{l}.\]

For a $D$-dimensional harmonic oscillator indices $\mathbf{i}, \mathbf{j}, \ldots$ are $D$-tuples. The energy scale is defined by the first dimension i.e. $\hbar \omega_x$ so that single particle energies are

\[ \frac{\epsilon_\mathbf{i}}{\hbar \omega_x} = (i_x + 1/2) + \eta_y (i_y+1/2) + \ldots.\]

The factors $\eta_y, \ldots$ allow for anisotropic trapping geometries and are assumed to be greater than 1 so that $\omega_x$ is the smallest trapping frequency.

By default the offdiagonal elements due to the interactions are consistent with first-order degenerate perturbation theory

\[ V_{\mathbf{ijkl}} = \delta_{\epsilon_\mathbf{i} + \epsilon_\mathbf{j}} ^{\epsilon_\mathbf{k} + \epsilon_\mathbf{l}} - \prod_{d \in x, y,\ldots} \mathcal{I}(i_d,j_d,k_d,l_d),\]

where the $\delta$ function indicates that the total noninteracting energy is conserved meaning all states with the same noninteracting energy are connected by this interaction and the Hamiltonian blocks according to noninteracting energy levels. Setting block_by_level = false will disable this restriction and allow coupling between basis states of any noninteracting energy level, leading to many more offdiagonals and fewer but larger blocks (the blocks are still distinguished by parity of basis states). Alternatively, see HOCartesianEnergyConservedPerDim for a model with the stronger restriction that conserves energy separately per spatial dimension. The integral $\mathcal{I}(a,b,c,d)$ is of four one dimensional harmonic oscillator basis functions, implemented in four_oscillator_integral_general.

Arguments

  • addr: the starting address, defines number of particles and total number of modes.
  • S: Tuple of the number of levels in each dimension, including the groundstate. The allowed couplings between states is defined by the aspect ratio of S .- 1. Defaults to a 1D spectrum with number of levels matching modes of addr. Will be sorted to make the first dimension the largest.
  • η: Define a custom aspect ratio for the trapping potential strengths, instead of deriving from S .- 1. This will only affect the single particle energy scale and not the interactions. The values are always scaled relative to the first dimension, which sets the energy scale of the system, $\hbar\omega_x$.
  • g: the (isotropic) bare interaction parameter. The value of g is assumed to be in trap units.
  • interaction_only: if set to true then the noninteracting single-particle terms are ignored. Useful if only energy shifts due to interactions are required.
  • block_by_level: if set to false will allow the interactions to couple all states without comparing their noninteracting energy.
Warning

num_offdiagonals is a bad estimate for this Hamiltonian. Take care when building a matrix or using QMC methods. Use get_all_blocks first then pass option col_hint = block_size to BasisSetRep to safely build the matrix.

source
Rimu.Hamiltonians.HOCartesianEnergyConservedPerDimType
HOCartesianEnergyConservedPerDim(addr; S, η, g = 1.0, interaction_only = false)

Implements a bosonic harmonic oscillator in Cartesian basis with contact interactions

\[\hat{H} = \sum_{i} ϵ_i n_i + \frac{g}{2}\sum_{ijkl} V_{ijkl} a^†_i a^†_j a_k a_l,\]

with the additional restriction that the interactions only couple states with the same energy in each dimension separately. See HOCartesianContactInteractions for a model that conserves total energy.

For a $D$-dimensional harmonic oscillator indices $\mathbf{i}, \mathbf{j}, \ldots$ are $D$-tuples. The energy scale is defined by the first dimension i.e. $\hbar \omega_x$ so that single particle energies are

\[ \frac{\epsilon_\mathbf{i}}{\hbar \omega_x} = (i_x + 1/2) + \eta_y (i_y+1/2) + \ldots.\]

The factors $\eta_y, \ldots$ allow for anisotropic trapping geometries and are assumed to be greater than 1 so that $\omega_x$ is the smallest trapping frequency.

Matrix elements $V_{\mathbf{ijkl}}$ are for a contact interaction calculated in this basis using first-order degenerate perturbation theory.

\[ V_{\mathbf{ijkl}} = \prod_{d \in x, y,\ldots} \mathcal{I}(i_d,j_d,k_d,l_d) - \delta_{i_d + j_d}^{k_d + l_d},\]

where the $\delta$-function indicates that the noninteracting energy is conserved along each dimension. The integral $\mathcal{I}(a,b,c,d)$ is of four one dimensional harmonic oscillator basis functions, see four_oscillator_integral_general, with the additional restriction that energy is conserved in each dimension.

Arguments

  • addr: the starting address, defines number of particles and total number of modes.
  • S: Tuple of the number of levels in each dimension, including the groundstate. Defaults to a 1D spectrum with number of levels matching modes of addr. Will be sorted to make the first dimension the largest.
  • η: Define a custom aspect ratio for the trapping potential strengths, instead of deriving from S .- 1. The values are always scaled relative to the first dimension, which sets the energy scale of the system, $\hbar\omega_x$.
  • g: the (isotropic) interparticle interaction parameter. The value of g is assumed to be in trap units.
  • interaction_only: if set to true then the noninteracting single-particle terms are ignored. Useful if only energy shifts due to interactions are required.
source
Rimu.Hamiltonians.HOCartesianCentralImpurityType
HOCartesianCentralImpurity(addr; kwargs...)

Hamiltonian of non-interacting particles in an arbitrary harmonic trap with a delta-function potential at the centre, with strength g,

\[\hat{H}_\mathrm{rel} = \sum_\mathbf{i} ϵ_\mathbf{i} n_\mathbf{i} + \prod_{d \in x, y,\ldots} \mathcal{I}(i_d,j_d,k_d,l_d),\]

where the $\delta$ function indicates that the total noninteracting energy is conserved meaning all states with the same noninteracting energy are connected by this interaction and the Hamiltonian blocks according to noninteracting energy levels. Setting block_by_level = false will disable this restriction and allow coupling between basis states of any noninteracting energy level, leading to many more offdiagonals and fewer but larger blocks (the blocks are still distinguished by parity of basis states). Alternatively, see HOCartesianEnergyConservedPerDim for a model with the stronger restriction that conserves energy separately per spatial dimension. The integral $\mathcal{I}(a,b,c,d)$ is of four one dimensional harmonic oscillator basis functions, implemented in four_oscillator_integral_general.

Arguments

  • addr: the starting address, defines number of particles and total number of modes.
  • S: Tuple of the number of levels in each dimension, including the groundstate. The allowed couplings between states is defined by the aspect ratio of S .- 1. Defaults to a 1D spectrum with number of levels matching modes of addr. Will be sorted to make the first dimension the largest.
  • η: Define a custom aspect ratio for the trapping potential strengths, instead of deriving from S .- 1. This will only affect the single particle energy scale and not the interactions. The values are always scaled relative to the first dimension, which sets the energy scale of the system, $\hbar\omega_x$.
  • g: the (isotropic) bare interaction parameter. The value of g is assumed to be in trap units.
  • interaction_only: if set to true then the noninteracting single-particle terms are ignored. Useful if only energy shifts due to interactions are required.
  • block_by_level: if set to false will allow the interactions to couple all states without comparing their noninteracting energy.
Warning

num_offdiagonals is a bad estimate for this Hamiltonian. Take care when building a matrix or using QMC methods. Use get_all_blocks first then pass option col_hint = block_size to BasisSetRep to safely build the matrix.

source
Rimu.Hamiltonians.HOCartesianEnergyConservedPerDimType
HOCartesianEnergyConservedPerDim(addr; S, η, g = 1.0, interaction_only = false)

Implements a bosonic harmonic oscillator in Cartesian basis with contact interactions

\[\hat{H} = \sum_{i} ϵ_i n_i + \frac{g}{2}\sum_{ijkl} V_{ijkl} a^†_i a^†_j a_k a_l,\]

with the additional restriction that the interactions only couple states with the same energy in each dimension separately. See HOCartesianContactInteractions for a model that conserves total energy.

For a $D$-dimensional harmonic oscillator indices $\mathbf{i}, \mathbf{j}, \ldots$ are $D$-tuples. The energy scale is defined by the first dimension i.e. $\hbar \omega_x$ so that single particle energies are

\[ \frac{\epsilon_\mathbf{i}}{\hbar \omega_x} = (i_x + 1/2) + \eta_y (i_y+1/2) + \ldots.\]

The factors $\eta_y, \ldots$ allow for anisotropic trapping geometries and are assumed to be greater than 1 so that $\omega_x$ is the smallest trapping frequency.

Matrix elements $V_{\mathbf{ijkl}}$ are for a contact interaction calculated in this basis using first-order degenerate perturbation theory.

\[ V_{\mathbf{ijkl}} = \prod_{d \in x, y,\ldots} \mathcal{I}(i_d,j_d,k_d,l_d) + \delta_{i_d + j_d}^{k_d + l_d},\]

where the $\delta$-function indicates that the noninteracting energy is conserved along each dimension. The integral $\mathcal{I}(a,b,c,d)$ is of four one dimensional harmonic oscillator basis functions, see four_oscillator_integral_general, with the additional restriction that energy is conserved in each dimension.

Arguments

  • addr: the starting address, defines number of particles and total number of modes.
  • S: Tuple of the number of levels in each dimension, including the groundstate. Defaults to a 1D spectrum with number of levels matching modes of addr. Will be sorted to make the first dimension the largest.
  • η: Define a custom aspect ratio for the trapping potential strengths, instead of deriving from S .- 1. The values are always scaled relative to the first dimension, which sets the energy scale of the system, $\hbar\omega_x$.
  • g: the (isotropic) interparticle interaction parameter. The value of g is assumed to be in trap units.
  • interaction_only: if set to true then the noninteracting single-particle terms are ignored. Useful if only energy shifts due to interactions are required.
source
Rimu.Hamiltonians.HOCartesianCentralImpurityType
HOCartesianCentralImpurity(addr; kwargs...)

Hamiltonian of non-interacting particles in an arbitrary harmonic trap with a delta-function potential at the centre, with strength g,

\[\hat{H}_\mathrm{rel} = \sum_\mathbf{i} ϵ_\mathbf{i} n_\mathbf{i} + g\sum_\mathbf{ij} V_\mathbf{ij} a^†_\mathbf{i} a_\mathbf{j}.\]

For a $D$-dimensional harmonic oscillator indices $\mathbf{i}, \mathbf{j}, \ldots$ are $D$-tuples. The energy scale is defined by the first dimension i.e. $\hbar \omega_x$ so that single particle energies are

\[ \frac{\epsilon_\mathbf{i}}{\hbar \omega_x} = (i_x + 1/2) + \eta_y (i_y+1/2) + \ldots.\]

The factors $\eta_y, \ldots$ allow for anisotropic trapping geometries and are assumed to be greater than 1 so that $\omega_x$ is the smallest trapping frequency.

Matrix elements $V_{\mathbf{ij}}$ are for a delta function potential calculated in this basis

\[ V_{\mathbf{ij}} = \prod_{d \in x, y,\ldots} \psi_{i_d}(0) \psi_{j_d}(0).\]

Only even parity states feel this impurity, so all $i_d$ are even. Note that the matrix representation of this Hamiltonian for a single particle is completely dense in the even-parity subspace.

Arguments

  • addr: the starting address, defines number of particles and total number of modes.
  • max_nx = num_modes(addr) - 1: the maximum harmonic oscillator index number in the $x$-dimension. Must be even. Index number for the harmonic oscillator groundstate is 0.
  • ηs = (): a tuple of aspect ratios for the remaining dimensions (η_y, ...). Should be empty for a 1D trap or contain values greater than 1.0. The maximum index in other dimensions will be the largest even number less than M/η_y.
  • S = nothing: Instead of max_nx, manually set the number of levels in each dimension, including the groundstate. Must be a Tuple of Ints.
  • g = 1.0: the strength of the delta impurity in ($x$-dimension) trap units.
  • impurity_only=false: if set to true then the trap energy terms are ignored. Useful if only energy shifts due to the impurity are required.
Warning
Due to use of `SpecialFunctions` with large arguments the matrix representation of
 this Hamiltonian may not be strictly symmetric, but is approximately symmetric within
-machine precision.

See also HOCartesianContactInteractions andHOCartesianEnergyConservedPerDim.

source

Other model Hamiltonians

See also HOCartesianContactInteractions andHOCartesianEnergyConservedPerDim.

source

Other model Hamiltonians

Rimu.Hamiltonians.MatrixHamiltonianType
MatrixHamiltonian(
     mat::AbstractMatrix{T};
     starting_address::Int = starting_address(mat)
-) <: AbstractHamiltonian{T}

Wrap an abstract matrix mat as an AbstractHamiltonian object. Works with stochastic methods of ProjectorMonteCarloProblem() and DVec. Optionally, a valid index can be provided as the starting_address.

Specialised methods are implemented for sparse matrices of type AbstractSparseMatrixCSC. One based indexing is required for the matrix mat.

source
Rimu.Hamiltonians.Transcorrelated1DType
Transcorrelated1D(address; t=1.0, v=1.0, v_ho=0.0, cutoff=1, three_body_term=true)

Implements a transcorrelated Hamiltonian for contact interactions in one dimensional momentum space from Jeszenski et al. (2018). Currently limited to two component fermionic addresses.

\[\begin{aligned} +) <: AbstractHamiltonian{T}

Wrap an abstract matrix mat as an AbstractHamiltonian object. Works with stochastic methods of ProjectorMonteCarloProblem() and DVec. Optionally, a valid index can be provided as the starting_address.

Specialised methods are implemented for sparse matrices of type AbstractSparseMatrixCSC. One based indexing is required for the matrix mat.

source
Rimu.Hamiltonians.Transcorrelated1DType
Transcorrelated1D(address; t=1.0, v=1.0, v_ho=0.0, cutoff=1, three_body_term=true)

Implements a transcorrelated Hamiltonian for contact interactions in one dimensional momentum space from Jeszenski et al. (2018). Currently limited to two component fermionic addresses.

\[\begin{aligned} \tilde{H} &= t \sum_{kσ}k^2 n_{k,σ} \\ &\quad + \sum_{pqkσσ'} T_{pqk} a^†_{p-k,σ} a^†_{q+k,σ'} a_{q,σ'} a_{p,σ} \\ @@ -38,7 +38,7 @@ - (p - q)k\tilde{u}(k)\right] + \frac{2v^2}{t}W(k)\\ W(k) &= \frac{1}{M^2}\sum_{q} (k - q)q\, \tilde{u}(q)\,\tilde{u}(k - q) \\ Q_{kl} &= -\frac{v^2}{t M^2}k \tilde{u}(k)\,l\tilde{u}(l), -\end{aligned}\]

Arguments

  • address: The starting address, defines number of particles and sites.
  • v: The interaction parameter.
  • t: The kinetic energy prefactor.
  • v_ho: Strength of the external harmonic oscillator potential $V̂_\mathrm{ho}$. See HubbardMom1DEP.
  • cutoff controls $k_c$ in equations above. Note: skipping generating off-diagonal elements below the cutoff is not implemented - zero-valued elements are returned instead.
  • three_body_term: If set to false, generating three body excitations is skipped. Note: when disabling three body terms, cutoff should be set to a higher value for best results.

See also

source
Rimu.Hamiltonians.FroehlichPolaronType
FroehlichPolaron(address::OccupationNumberFS{M}; kwargs...) <: AbstractHamiltonian

The Froehlich polaron Hamiltonian for a 1D lattice with M momentum modes is given by

\[H = (p̂_f - p)^2/m + ωN̂ - v Σₖ(âₖ^† + â₋ₖ)\]

where $p$ is the total momentum, $p̂_f = Σ_k k âₖ^† âₖ$ is the momentum operator for the bosons, and $k$ part of the momentum lattice with separation $2π/l$. $N̂$ is the number operator for the bosons.

Keyword Arguments

  • p=0.0: the total momentum $p$.
  • v=1.0: the coupling strength $v$.
  • mass=1.0: the particle mass $m$.
  • omega=1.0: the oscillation frequency of the phonons $ω$.
  • l=1.0: the box size in real space $l$. Provides scale parameter of the momentum lattice.
  • momentum_cutoff=nothing: the maximum boson momentum allowed for an address.
  • mode_cutoff: the maximum number of bosons in each momentum mode. Defaults to the maximum value supported by the address type OccupationNumberFS.

Examples

julia> fs = OccupationNumberFS(0,0,0)
+\end{aligned}\]

Arguments

  • address: The starting address, defines number of particles and sites.
  • v: The interaction parameter.
  • t: The kinetic energy prefactor.
  • v_ho: Strength of the external harmonic oscillator potential $V̂_\mathrm{ho}$. See HubbardMom1DEP.
  • cutoff controls $k_c$ in equations above. Note: skipping generating off-diagonal elements below the cutoff is not implemented - zero-valued elements are returned instead.
  • three_body_term: If set to false, generating three body excitations is skipped. Note: when disabling three body terms, cutoff should be set to a higher value for best results.

See also

source
Rimu.Hamiltonians.FroehlichPolaronType
FroehlichPolaron(address::OccupationNumberFS{M}; kwargs...) <: AbstractHamiltonian

The Froehlich polaron Hamiltonian for a 1D lattice with M momentum modes is given by

\[H = (p̂_f - p)^2/m + ωN̂ - v Σₖ(âₖ^† + â₋ₖ)\]

where $p$ is the total momentum, $p̂_f = Σ_k k âₖ^† âₖ$ is the momentum operator for the bosons, and $k$ part of the momentum lattice with separation $2π/l$. $N̂$ is the number operator for the bosons.

Keyword Arguments

  • p=0.0: the total momentum $p$.
  • v=1.0: the coupling strength $v$.
  • mass=1.0: the particle mass $m$.
  • omega=1.0: the oscillation frequency of the phonons $ω$.
  • l=1.0: the box size in real space $l$. Provides scale parameter of the momentum lattice.
  • momentum_cutoff=nothing: the maximum boson momentum allowed for an address.
  • mode_cutoff: the maximum number of bosons in each momentum mode. Defaults to the maximum value supported by the address type OccupationNumberFS.

Examples

julia> fs = OccupationNumberFS(0,0,0)
 OccupationNumberFS{3, UInt8}(0, 0, 0)
 
 julia> ham = FroehlichPolaron(fs; v=0.5)
@@ -48,7 +48,7 @@
 16777216
 
 julia> dimension(FroehlichPolaron(fs; v=0.5, mode_cutoff=5))
-216

See also OccupationNumberFS, dimension, AbstractHamiltonian.

source

Convenience functions

Convenience functions

Rimu.Hamiltonians.momentumFunction
momentum(ham::AbstractHamiltonian)

Momentum as a linear operator in Fock space. Pass a Hamiltonian ham in order to convey information about the Fock basis. Returns an AbstractHamiltonian that represents the momentum operator.

Note: momentum is currently only defined on HubbardMom1D.

Example

julia> add = BoseFS((1, 0, 2, 1, 2, 1, 1, 3));
 
 
 julia> ham = HubbardMom1D(add; u = 2.0, t = 1.0);
@@ -64,7 +64,7 @@
 
 
 julia> rayleigh_quotient(mom, v) # momentum expectation value for state vector `v`
--1.5707963267948966

Part of the AbstractHamiltonian interface.

source

Hamiltonian wrappers

The following Hamiltonians are constructed from an existing Hamiltonian instance and change its behaviour:

Rimu.Hamiltonians.GutzwillerSamplingType
GutzwillerSampling(::AbstractHamiltonian; g)

Wrapper over any AbstractHamiltonian that implements Gutzwiller sampling. In this importance sampling scheme the Hamiltonian is modified as follows

\[\tilde{H}_{ij} = H_{ij} e^{-g(H_{ii} - H_{jj})} .\]

This way off-diagonal spawns to higher-energy configurations are discouraged and spawns to lower-energy configurations encouraged for positive g.

Constructor

  • GutzwillerSampling(::AbstractHamiltonian, g)
  • GutzwillerSampling(::AbstractHamiltonian; g)

After construction, we can access the underlying Hamiltonian with G.hamiltonian and the g parameter with G.g.

Example

julia> H = HubbardMom1D(BoseFS(1,1,1); u=6.0, t=1.0)
+-1.5707963267948966

Part of the AbstractHamiltonian interface.

source

Hamiltonian wrappers

The following Hamiltonians are constructed from an existing Hamiltonian instance and change its behaviour:

Rimu.Hamiltonians.GutzwillerSamplingType
GutzwillerSampling(::AbstractHamiltonian; g)

Wrapper over any AbstractHamiltonian that implements Gutzwiller sampling. In this importance sampling scheme the Hamiltonian is modified as follows

\[\tilde{H}_{ij} = H_{ij} e^{-g(H_{ii} - H_{jj})} .\]

This way off-diagonal spawns to higher-energy configurations are discouraged and spawns to lower-energy configurations encouraged for positive g.

Constructor

  • GutzwillerSampling(::AbstractHamiltonian, g)
  • GutzwillerSampling(::AbstractHamiltonian; g)

After construction, we can access the underlying Hamiltonian with G.hamiltonian and the g parameter with G.g.

Example

julia> H = HubbardMom1D(BoseFS(1,1,1); u=6.0, t=1.0)
 HubbardMom1D(fs"|1 1 1⟩"; u=6.0, t=1.0)
 
 julia> G = GutzwillerSampling(H, g=0.3)
@@ -74,7 +74,7 @@
 (BoseFS{3,3}(1, 0, 2), 2.0)
 
 julia> get_offdiagonal(G, BoseFS(2, 1, 0), 1)
-(BoseFS{3,3}(1, 0, 2), 0.8131393194811987)

Observables

To calculate observables, pass the transformed Hamiltonian G to AllOverlaps with keyword argument transform=G.

source
Rimu.Hamiltonians.GuidingVectorSamplingType
GuidingVectorSampling

Wrapper over any AbstractHamiltonian that implements guided vector a.k.a. guided wave function sampling. In this importance sampling scheme the Hamiltonian is modified as follows.

\[\tilde{H}_{ij} = v_i H_{ij} v_j^{-1}\]

and where v is the guiding vector. v_i and v_j are also thresholded to avoid dividing by zero (see below).

Constructors

  • GuidingVectorSampling(::AbstractHamiltonian, vector, eps)
  • GuidingVectorSampling(::AbstractHamiltonian; vector, eps)

eps is a thresholding parameter used to avoid dividing by zero; all values below eps are set to eps. It is recommended that eps is in the same value range as the guiding vector. The default value is set to eps=norm(v, Inf) * 1e-2

After construction, we can access the underlying hamiltonian with G.hamiltonian, the eps parameter with G.eps, and the guiding vector with G.vector.

Example

julia> H = HubbardReal1D(BoseFS(1,1,1); u=6.0, t=1.0);
+(BoseFS{3,3}(1, 0, 2), 0.8131393194811987)

Observables

To calculate observables, pass the transformed Hamiltonian G to AllOverlaps with keyword argument transform=G.

source
Rimu.Hamiltonians.GuidingVectorSamplingType
GuidingVectorSampling

Wrapper over any AbstractHamiltonian that implements guided vector a.k.a. guided wave function sampling. In this importance sampling scheme the Hamiltonian is modified as follows.

\[\tilde{H}_{ij} = v_i H_{ij} v_j^{-1}\]

and where v is the guiding vector. v_i and v_j are also thresholded to avoid dividing by zero (see below).

Constructors

  • GuidingVectorSampling(::AbstractHamiltonian, vector, eps)
  • GuidingVectorSampling(::AbstractHamiltonian; vector, eps)

eps is a thresholding parameter used to avoid dividing by zero; all values below eps are set to eps. It is recommended that eps is in the same value range as the guiding vector. The default value is set to eps=norm(v, Inf) * 1e-2

After construction, we can access the underlying hamiltonian with G.hamiltonian, the eps parameter with G.eps, and the guiding vector with G.vector.

Example

julia> H = HubbardReal1D(BoseFS(1,1,1); u=6.0, t=1.0);
 
 julia> v = DVec(starting_address(H) => 10; capacity=1);
 
@@ -84,7 +84,7 @@
 (BoseFS{3,3}(2, 0, 1), -1.4142135623730951)
 
 julia> get_offdiagonal(G, starting_address(G), 4)
-(BoseFS{3,3}(2, 0, 1), -0.014142135623730952)

Observables

To calculate observables, pass the transformed Hamiltonian G to AllOverlaps with keyword argument transform=G.

source
Rimu.Hamiltonians.ParitySymmetryType
ParitySymmetry(ham::AbstractHamiltonian{T}; even=true) <: AbstractHamiltonian{T}

Impose even or odd parity on all states and the Hamiltonian ham as controlled by the keyword argument even. Parity symmetry of the Hamiltonian is assumed. For some Hamiltonians, ParitySymmetry reduces the size of the Hilbert space by half.

ParitySymmetry performs a unitary transformation, leaving the eigenvalues unchanged and preserving the LOStructure. This is achieved by changing the basis set to states with defined parity. Effectively, a non-even address $|α⟩$ is replaced by $\frac{1}{√2}(|α⟩ ± |ᾱ⟩)$ for even and odd parity, respectively, where ᾱ == reverse(α).

Notes

  • This modifier currently only works on starting_addresss with an odd number of modes.
  • For odd parity, the starting_address of the underlying Hamiltonian cannot be symmetric.
  • If parity is not a symmetry of the Hamiltonian ham then the result is undefined.
  • ParitySymmetry works by modifying the offdiagonals iterator.
julia> ham = HubbardReal1D(BoseFS(0,2,1))
+(BoseFS{3,3}(2, 0, 1), -0.014142135623730952)

Observables

To calculate observables, pass the transformed Hamiltonian G to AllOverlaps with keyword argument transform=G.

source
Rimu.Hamiltonians.ParitySymmetryType
ParitySymmetry(ham::AbstractHamiltonian{T}; even=true) <: AbstractHamiltonian{T}

Impose even or odd parity on all states and the Hamiltonian ham as controlled by the keyword argument even. Parity symmetry of the Hamiltonian is assumed. For some Hamiltonians, ParitySymmetry reduces the size of the Hilbert space by half.

ParitySymmetry performs a unitary transformation, leaving the eigenvalues unchanged and preserving the LOStructure. This is achieved by changing the basis set to states with defined parity. Effectively, a non-even address $|α⟩$ is replaced by $\frac{1}{√2}(|α⟩ ± |ᾱ⟩)$ for even and odd parity, respectively, where ᾱ == reverse(α).

Notes

  • This modifier currently only works on starting_addresss with an odd number of modes.
  • For odd parity, the starting_address of the underlying Hamiltonian cannot be symmetric.
  • If parity is not a symmetry of the Hamiltonian ham then the result is undefined.
  • ParitySymmetry works by modifying the offdiagonals iterator.
julia> ham = HubbardReal1D(BoseFS(0,2,1))
 HubbardReal1D(fs"|0 2 1⟩"; u=1.0, t=1.0)
 
 julia> size(Matrix(ham))
@@ -97,7 +97,7 @@
 (4, 4)
 
 julia> eigvals(Matrix(ham))[1] ≈ eigvals(Matrix(ParitySymmetry(ham)))[1]
-true

See also TimeReversalSymmetry.

source
Rimu.Hamiltonians.TimeReversalSymmetryType
TimeReversalSymmetry(ham::AbstractHamiltonian{T}; even=true) <: AbstractHamiltonian{T}

Impose even or odd time reversal on all states and the Hamiltonian ham as controlled by the keyword argument even. If time reversal is a symmetry of the Hamiltonian it will block (reducing Hilbert space dimension) preserving the eigenvalues and LOStructure.

Notes

  • This modifier only works two component starting_addresses.
  • For odd time reversal symmetry, the starting_address of the underlying Hamiltonian must not be symmetric.
  • If time reversal is not a symmetry of the Hamiltonian ham then the result is undefined.
  • TimeReversalSymmetry works by modifying the offdiagonals iterator.
julia> ham = HubbardMom1D(FermiFS2C((1,0,1),(0,1,1)));
+true

See also TimeReversalSymmetry.

source
Rimu.Hamiltonians.TimeReversalSymmetryType
TimeReversalSymmetry(ham::AbstractHamiltonian{T}; even=true) <: AbstractHamiltonian{T}

Impose even or odd time reversal on all states and the Hamiltonian ham as controlled by the keyword argument even. If time reversal is a symmetry of the Hamiltonian it will block (reducing Hilbert space dimension) preserving the eigenvalues and LOStructure.

Notes

  • This modifier only works two component starting_addresses.
  • For odd time reversal symmetry, the starting_address of the underlying Hamiltonian must not be symmetric.
  • If time reversal is not a symmetry of the Hamiltonian ham then the result is undefined.
  • TimeReversalSymmetry works by modifying the offdiagonals iterator.
julia> ham = HubbardMom1D(FermiFS2C((1,0,1),(0,1,1)));
 
 julia> size(Matrix(ham))
 (3, 3)
@@ -109,12 +109,12 @@
 (1, 1)
 
 julia> eigvals(Matrix(TimeReversalSymmetry(ham)))[1] ≈ eigvals(Matrix(ham))[1]
-true

See also ParitySymmetry.

source
Rimu.Hamiltonians.StoquasticType
Stoquastic(ham <: AbstractHamiltonian) <: AbstractHamiltonian

A wrapper for an AbstractHamiltonian that replaces all off-diagonal matrix elements v by -abs(v), thus making the new Hamiltonian stoquastic.

A stoquastic Hamiltonian does not have a Monte Carlo sign problem. For a hermitian ham the smallest eigenvalue of Stoquastic(ham) is ≤ the smallest eigenvalue of ham.

source

Observables

Rimu.jl offers two other supertypes for operators that are less restrictive than AbstractHamiltonian. AbstractObservable and AbstractOperators both can represent a physical observable. Their expectation values can be sampled during a ProjectorMonteCarloProblem simulation by passing them into a suitable ReplicaStrategy, e.g. AllOverlaps. Some observables are also AbstractHamiltonians. The full type hierarchy is

AbstractHamiltonian{T} <: AbstractOperator{T} <: AbstractObservable{T}
Rimu.Hamiltonians.ParticleNumberOperatorType
ParticleNumberOperator() <: AbstractOperator{Float64}

The number operator in Fock space. This operator is diagonal in the Fock basis and returns the number of particles in the Fock state. It works with any address type that is a subtype of AbstractFockAddress.

julia> p = ExactDiagonalizationProblem(FroehlichPolaron(fs"|0 0⟩{}"; mode_cutoff=5, v=3));
+true

See also ParitySymmetry.

source
Rimu.Hamiltonians.StoquasticType
Stoquastic(ham <: AbstractHamiltonian) <: AbstractHamiltonian

A wrapper for an AbstractHamiltonian that replaces all off-diagonal matrix elements v by -abs(v), thus making the new Hamiltonian stoquastic.

A stoquastic Hamiltonian does not have a Monte Carlo sign problem. For a hermitian ham the smallest eigenvalue of Stoquastic(ham) is ≤ the smallest eigenvalue of ham.

source

Observables

Rimu.jl offers two other supertypes for operators that are less restrictive than AbstractHamiltonian. AbstractObservable and AbstractOperators both can represent a physical observable. Their expectation values can be sampled during a ProjectorMonteCarloProblem simulation by passing them into a suitable ReplicaStrategy, e.g. AllOverlaps. Some observables are also AbstractHamiltonians. The full type hierarchy is

AbstractHamiltonian{T} <: AbstractOperator{T} <: AbstractObservable{T}
Rimu.Hamiltonians.ParticleNumberOperatorType
ParticleNumberOperator() <: AbstractOperator{Float64}

The number operator in Fock space. This operator is diagonal in the Fock basis and returns the number of particles in the Fock state. It works with any address type that is a subtype of AbstractFockAddress.

julia> p = ExactDiagonalizationProblem(FroehlichPolaron(fs"|0 0⟩{}"; mode_cutoff=5, v=3));
 
 julia> gs = solve(p).vectors[1]; # normalised ground state vector
 
 julia> dot(gs, ParticleNumberOperator(), gs) # particle number expectation value
-2.8823297252925917

See also AbstractHamiltonian.

source
Rimu.Hamiltonians.G2RealCorrelatorType
G2RealCorrelator(d::Int) <: AbstractOperator{Float64}

Two-body operator for density-density correlation between sites separated by d with 0 ≤ d < M.

\[ \hat{G}^{(2)}(d) = \frac{1}{M} \sum_i^M \hat{n}_i (\hat{n}_{i+d} - \delta_{0d}).\]

Assumes a one-dimensional lattice with periodic boundary conditions where

\[ \hat{G}^{(2)}(-M/2 \leq d < 0) = \hat{G}^{(2)}(|d|),\]

\[ \hat{G}^{(2)}(M/2 < d < M) = \hat{G}^{(2)}(M - d),\]

and normalisation

\[ \sum_{d=0}^{M-1} \langle \hat{G}^{(2)}(d) \rangle = \frac{N (N-1)}{M}.\]

For multicomponent basis, calculates correlations between all particles equally, equivalent to stacking all components into a single Fock state.

Arguments

  • d::Integer: distance between sites.

See also

source
Rimu.Hamiltonians.G2RealSpaceType
G2RealSpace(geometry::CubicGrid, σ=1, τ=1; sum_components=false) <: AbstractOperator{SArray}

Two-body operator for density-density correlation for all Displacements $d⃗$ in the specified geometry.

\[ \hat{G}^{(2)}_{σ,τ}(d⃗) = \frac{1}{M} ∑_{i⃗} n̂_{σ,i⃗} (n̂_{τ,i⃗+d⃗} - δ_{0⃗,d⃗}δ_{σ,τ}).\]

For multicomponent addresses, σ and τ control the components involved. Alternatively, sum_components can be set to true, which treats all particles as belonging to the same component.

Examples

julia> geom = CubicGrid(2, 2);
+2.8823297252925917

See also AbstractHamiltonian.

source
Rimu.Hamiltonians.G2RealCorrelatorType
G2RealCorrelator(d::Int) <: AbstractOperator{Float64}

Two-body operator for density-density correlation between sites separated by d with 0 ≤ d < M.

\[ \hat{G}^{(2)}(d) = \frac{1}{M} \sum_i^M \hat{n}_i (\hat{n}_{i+d} - \delta_{0d}).\]

Assumes a one-dimensional lattice with periodic boundary conditions where

\[ \hat{G}^{(2)}(-M/2 \leq d < 0) = \hat{G}^{(2)}(|d|),\]

\[ \hat{G}^{(2)}(M/2 < d < M) = \hat{G}^{(2)}(M - d),\]

and normalisation

\[ \sum_{d=0}^{M-1} \langle \hat{G}^{(2)}(d) \rangle = \frac{N (N-1)}{M}.\]

For multicomponent basis, calculates correlations between all particles equally, equivalent to stacking all components into a single Fock state.

Arguments

  • d::Integer: distance between sites.

See also

source
Rimu.Hamiltonians.G2RealSpaceType
G2RealSpace(geometry::CubicGrid, σ=1, τ=1; sum_components=false) <: AbstractOperator{SArray}

Two-body operator for density-density correlation for all Displacements $d⃗$ in the specified geometry.

\[ \hat{G}^{(2)}_{σ,τ}(d⃗) = \frac{1}{M} ∑_{i⃗} n̂_{σ,i⃗} (n̂_{τ,i⃗+d⃗} - δ_{0⃗,d⃗}δ_{σ,τ}).\]

For multicomponent addresses, σ and τ control the components involved. Alternatively, sum_components can be set to true, which treats all particles as belonging to the same component.

Examples

julia> geom = CubicGrid(2, 2);
 
 julia> g2 = G2RealSpace(geom)
 G2RealSpace(CubicGrid((2, 2), (true, true)), 1,1)
@@ -143,8 +143,8 @@
 julia> diagonal_element(g2_sum, fs"|⇅⋅↓↑⟩")
 2×2 StaticArraysCore.SMatrix{2, 2, Float64, 4} with indices SOneTo(2)×SOneTo(2):
  0.5  1.0
- 0.5  1.0

See also

source
Rimu.Hamiltonians.G2MomCorrelatorType
G2MomCorrelator(d::Int) <: AbstractOperator{ComplexF64}

Two-body correlation operator representing the density-density correlation at distance d. It returns a Complex value.

Correlation within a single component:

\[\hat{G}^{(2)}(d) = \frac{1}{M}\sum_{spqr=1}^M e^{-id(p-q)2π/M} a^†_{s} a^†_{p} a_q a_r δ_{s+p,q+r}\]

The diagonal element, where (p-q)=0, is

\[\frac{1}{M}\sum_{k,p=1}^M a^†_{k} b^†_{p} b_p a_k .\]

Arguments

  • d::Integer: the distance between two particles.

See also

source
Rimu.Hamiltonians.SuperfluidCorrelatorType
SuperfluidCorrelator(d::Int) <: AbstractOperator{Float64}

Operator for extracting superfluid correlation between sites separated by a distance d with 0 ≤ d < M:

\[ \hat{C}_{\text{SF}}(d) = \frac{1}{M} \sum_{i}^{M} a_{i}^{\dagger} a_{i + d}\]

Assumes a one-dimensional lattice with $M$ sites and periodic boundary conditions. $M$ is also the number of modes in the Fock state address.

Usage

Superfluid correlations can be extracted from a Monte Carlo calculation by wrapping SuperfluidCorrelator with AllOverlaps and passing into ProjectorMonteCarloProblem with the replica keyword argument. For an example with a similar use of G2RealCorrelator see G2 Correlator Example.

See also HubbardReal1D, G2RealCorrelator, AbstractOperator, and AllOverlaps.

source
Rimu.Hamiltonians.StringCorrelatorType
StringCorrelator(d::Int; address=nothing, type=nothing) <: AbstractOperator{T}

Operator for extracting string correlation between lattice sites on a one-dimensional Hubbard lattice separated by a distance d with 0 ≤ d < M

\[ Ĉ_{\text{string}}(d) = \frac{1}{M} \sum_{j}^{M} δ n̂_j - (e^{i π \sum_{j ≤ k < j + d} δ n̂_k}) δ n̂_{j+d}\]

Here, $δ n̂_j = n̂_j - n̄$ is the boson number deviation from the mean filling number and $n̄ = N/M$ is the mean filling number of lattice sites with $N$ particles and $M$ lattice sites (or modes).

Assumes a one-dimensional lattice with periodic boundary conditions. For usage see SuperfluidCorrelator and AllOverlaps.

The default element type T is ComplexF64. This can be overridden with the type keyword argument. If an address is provided, then T is calculated from the address type. It is set to ComplexF64 for non-integer filling numbers, and to Float64 for integer filling numbers or if d==0.

See also HubbardReal1D, G2RealCorrelator, SuperfluidCorrelator, AbstractOperator, and AllOverlaps.

source
Rimu.Hamiltonians.ReducedDensityMatrixType
ReducedDensityMatrix{T=Float64}(p) <: AbstractObservable{Hermitian{T, Matrix{T}}}

A matrix-valued operator that can be used to calculate the p-particle reduced density matrix. The matrix elements are defined as:

\[\hat{ρ}^{(p)}_{j_1,...,j_1,k_1,...,k_p} = \prod_{i=1}^{p} â^†_{j_i} \prod_{l=p}^{1} â_{k_{l}}\]

The integer indices j_i and k_i represent single particle modes. For efficiency they are chosen to be distinct and ordered:

\[j_1 < j_2 < \ldots < j_{p} \quad \land \quad k_1 < k_2 < \ldots < k_{p}\]

ReducedDensityMatrix can be used to construct the single-particle reduced density matrix (with p == 1) for fermionic and bosonic Fock spaces with address types <: SingleComponentFockAddress. For higher order reduced density matrices with p > 1 only fermionic Fock addresses (FermiFS) are supported due to the ordering of indices.

ReducedDensityMatrix can be used with dot or AllOverlaps to calculate the whole matrix in one go.

Examples

julia> dvec_b = PDVec(BoseFS(1,1) => 0.5, BoseFS(2,0) => 0.5)
+ 0.5  1.0

See also

source
Rimu.Hamiltonians.G2MomCorrelatorType
G2MomCorrelator(d::Int) <: AbstractOperator{ComplexF64}

Two-body correlation operator representing the density-density correlation at distance d. It returns a Complex value.

Correlation within a single component:

\[\hat{G}^{(2)}(d) = \frac{1}{M}\sum_{spqr=1}^M e^{-id(p-q)2π/M} a^†_{s} a^†_{p} a_q a_r δ_{s+p,q+r}\]

The diagonal element, where (p-q)=0, is

\[\frac{1}{M}\sum_{k,p=1}^M a^†_{k} b^†_{p} b_p a_k .\]

Arguments

  • d::Integer: the distance between two particles.

See also

source
Rimu.Hamiltonians.SuperfluidCorrelatorType
SuperfluidCorrelator(d::Int) <: AbstractOperator{Float64}

Operator for extracting superfluid correlation between sites separated by a distance d with 0 ≤ d < M:

\[ \hat{C}_{\text{SF}}(d) = \frac{1}{M} \sum_{i}^{M} a_{i}^{\dagger} a_{i + d}\]

Assumes a one-dimensional lattice with $M$ sites and periodic boundary conditions. $M$ is also the number of modes in the Fock state address.

Usage

Superfluid correlations can be extracted from a Monte Carlo calculation by wrapping SuperfluidCorrelator with AllOverlaps and passing into ProjectorMonteCarloProblem with the replica keyword argument. For an example with a similar use of G2RealCorrelator see G2 Correlator Example.

See also HubbardReal1D, G2RealCorrelator, AbstractOperator, and AllOverlaps.

source
Rimu.Hamiltonians.StringCorrelatorType
StringCorrelator(d::Int; address=nothing, type=nothing) <: AbstractOperator{T}

Operator for extracting string correlation between lattice sites on a one-dimensional Hubbard lattice separated by a distance d with 0 ≤ d < M

\[ Ĉ_{\text{string}}(d) = \frac{1}{M} \sum_{j}^{M} δ n̂_j + (e^{i π \sum_{j ≤ k < j + d} δ n̂_k}) δ n̂_{j+d}\]

Here, $δ n̂_j = n̂_j - n̄$ is the boson number deviation from the mean filling number and $n̄ = N/M$ is the mean filling number of lattice sites with $N$ particles and $M$ lattice sites (or modes).

Assumes a one-dimensional lattice with periodic boundary conditions. For usage see SuperfluidCorrelator and AllOverlaps.

The default element type T is ComplexF64. This can be overridden with the type keyword argument. If an address is provided, then T is calculated from the address type. It is set to ComplexF64 for non-integer filling numbers, and to Float64 for integer filling numbers or if d==0.

See also HubbardReal1D, G2RealCorrelator, SuperfluidCorrelator, AbstractOperator, and AllOverlaps.

source
Rimu.Hamiltonians.ReducedDensityMatrixType
ReducedDensityMatrix{T=Float64}(p) <: AbstractObservable{Hermitian{T, Matrix{T}}}

A matrix-valued operator that can be used to calculate the p-particle reduced density matrix. The matrix elements are defined as:

\[\hat{ρ}^{(p)}_{j_1,...,j_1,k_1,...,k_p} = \prod_{i=1}^{p} â^†_{j_i} \prod_{l=p}^{1} â_{k_{l}}\]

The integer indices j_i and k_i represent single particle modes. For efficiency they are chosen to be distinct and ordered:

\[j_1 < j_2 < \ldots < j_{p} \quad \land \quad k_1 < k_2 < \ldots < k_{p}\]

ReducedDensityMatrix can be used to construct the single-particle reduced density matrix (with p == 1) for fermionic and bosonic Fock spaces with address types <: SingleComponentFockAddress. For higher order reduced density matrices with p > 1 only fermionic Fock addresses (FermiFS) are supported due to the ordering of indices.

ReducedDensityMatrix can be used with dot or AllOverlaps to calculate the whole matrix in one go.

Examples

julia> dvec_b = PDVec(BoseFS(1,1) => 0.5, BoseFS(2,0) => 0.5)
 2-element PDVec: style = IsDeterministic{Float64}()
   fs"|2 0⟩" => 0.5
   fs"|1 1⟩" => 0.5
@@ -175,7 +175,7 @@
  0.25  0.0  0.25  0.0  0.0  0.0
  0.0   0.0  0.0   0.0  0.0  0.0
  0.0   0.0  0.0   0.0  0.0  0.0
- 0.0   0.0  0.0   0.0  0.0  0.0

See also single_particle_density, SingleParticleDensity, SingleParticleExcitation, TwoParticleExcitation.

source
Rimu.Hamiltonians.MomentumType
Momentum(component=0; fold=true) <: AbstractHamiltonian

The momentum operator $P̂$.

The component argument controls which component of the address is taken into consideration. A value of 0 sums the contributions of all components. If fold is true, the momentum is folded into the Brillouin zone.

julia> address = BoseFS((1, 0, 2, 1, 2, 1, 1, 3))
+ 0.0   0.0  0.0   0.0  0.0  0.0

See also single_particle_density, SingleParticleDensity, SingleParticleExcitation, TwoParticleExcitation.

source
Rimu.Hamiltonians.MomentumType
Momentum(component=0; fold=true) <: AbstractHamiltonian

The momentum operator $P̂$.

The component argument controls which component of the address is taken into consideration. A value of 0 sums the contributions of all components. If fold is true, the momentum is folded into the Brillouin zone.

julia> address = BoseFS((1, 0, 2, 1, 2, 1, 1, 3))
 BoseFS{11,8}(1, 0, 2, 1, 2, 1, 1, 3)
 
 julia> v = DVec(address => 10);
@@ -184,7 +184,7 @@
 -2.0
 
 julia> rayleigh_quotient(Momentum(fold=false), DVec(address => 1))
-14.0
source
Rimu.Hamiltonians.AxialAngularMomentumHOType
AxialAngularMomentumHO(S; z_dim = 3, addr = BoseFS(prod(S))) <: AbstractHamiltonian

Angular momentum operator for application to Cartesian harmonic oscillator basis, see HOCartesianContactInteractions or HOCartesianEnergyConservedPerDim. Represents the projection of angular momentum onto z-axis:

\[\hat{L}_z = i \hbar \sum_{j=1}^N \left( b_x b_y^\dag - b_y b_x^\dag \right),\]

where $b_x^\dag$ and $b_x$ are raising and lowering (ladder) operators for a harmonic oscillator in the $x$ dimension, and simlarly for $y$.

This is implemented for an $N$ particle Fock space with creation and annihilation operators as

\[\frac{1}{\hbar} \hat{L}_z = i \sum_{n_x=1}^{M_x} \sum_{n_y=1}^{M_y} +14.0

source
Rimu.Hamiltonians.AxialAngularMomentumHOType
AxialAngularMomentumHO(S; z_dim = 3, addr = BoseFS(prod(S))) <: AbstractHamiltonian

Angular momentum operator for application to Cartesian harmonic oscillator basis, see HOCartesianContactInteractions or HOCartesianEnergyConservedPerDim. Represents the projection of angular momentum onto z-axis:

\[\hat{L}_z = i \hbar \sum_{j=1}^N \left( b_x b_y^\dag - b_y b_x^\dag \right),\]

where $b_x^\dag$ and $b_x$ are raising and lowering (ladder) operators for a harmonic oscillator in the $x$ dimension, and simlarly for $y$.

This is implemented for an $N$ particle Fock space with creation and annihilation operators as

\[\frac{1}{\hbar} \hat{L}_z = i \sum_{n_x=1}^{M_x} \sum_{n_y=1}^{M_y} \left( a_{n_x-1,n_y+1}^\dag - a_{n_x+1,n_y-1}^\dag \right) a_{n_x, n_y}.\]

in units of $\hbar$.

Argument S is a tuple defining the range of Cartesian modes in each dimension and their mapping to Fock space modes in a SingleComponentFockAddress. If S indicates a 3D system the z dimension can be changed by setting z_dim; S should be be isotropic in the remaining x-y plane, i.e. must have S[x_dim] == S[y_dim]. The starting address addr only needs to satisfy num_modes(addr) == prod(S).

Example

Calculate the overlap of two Fock addresses interpreted as harmonic oscillator states in a 2D Cartesian basis

julia> S = (2,2)
 (2, 2)
 
@@ -200,7 +200,7 @@
   fs"|0 0 1 0⟩" => 1.0
 
 julia> dot(w, Lz, v)
-0.0 + 1.0im
source

Geometry

Lattices in higher dimensions are defined here and can be passed with the keyword argument geometry to HubbardRealSpace and G2RealSpace.

Rimu.Hamiltonians.CubicGridType
CubicGrid(dims::NTuple{D,Int}, fold::NTuple{D,Bool})

Represents a D-dimensional grid. Used to define a cubic lattice and boundary conditions for some AbstractHamiltonians, e.g. with the keyword argument geometry when constructing a HubbardRealSpace. The type instance can be used to convert between cartesian vector indices (tuples or SVectors) and linear indices (integers). When indexed with vectors, it folds them back into the grid if the out-of-bounds dimension is periodic and 0 otherwise (see example below).

  • dims controls the size of the grid in each dimension.
  • fold controls whether the boundaries in each dimension are periodic (or folded in the case of momentum space).
julia> geo = CubicGrid((2,3), (true,false))
+0.0 + 1.0im
source

Geometry

Lattices in higher dimensions are defined here and can be passed with the keyword argument geometry to HubbardRealSpace and G2RealSpace.

Rimu.Hamiltonians.CubicGridType
CubicGrid(dims::NTuple{D,Int}, fold::NTuple{D,Bool})

Represents a D-dimensional grid. Used to define a cubic lattice and boundary conditions for some AbstractHamiltonians, e.g. with the keyword argument geometry when constructing a HubbardRealSpace. The type instance can be used to convert between cartesian vector indices (tuples or SVectors) and linear indices (integers). When indexed with vectors, it folds them back into the grid if the out-of-bounds dimension is periodic and 0 otherwise (see example below).

  • dims controls the size of the grid in each dimension.
  • fold controls whether the boundaries in each dimension are periodic (or folded in the case of momentum space).
julia> geo = CubicGrid((2,3), (true,false))
 CubicGrid{2}((2, 3), (true, false))
 
 julia> geo[1]
@@ -222,7 +222,7 @@
 5
 
 julia> geo[(3,4)] # returns 0 if out of bounds
-0

See also PeriodicBoundaries, HardwallBoundaries and LadderBoundaries for special-case constructors. See also HubbardRealSpace and G2RealSpace.

source
Rimu.Hamiltonians.DirectionsType
Directions(D) <: AbstractVector{SVector{D,Int}}
 Directions(geometry::CubicGrid) <: AbstractVector{SVector{D,Int}}

Iterate over axis-aligned direction vectors in D dimensions.

julia> Directions(3)
 6-element Directions{3}:
  [1, 0, 0]
@@ -231,7 +231,7 @@
  [-1, 0, 0]
  [0, -1, 0]
  [0, 0, -1]
-

See also CubicGrid.

source
Rimu.Hamiltonians.DisplacementsType
Displacements(geometry::CubicGrid) <: AbstractVector{SVector{D,Int}}

Return all valid offset vectors in a CubicGrid. If center=true the (0,0) displacement is placed at the centre of the array.

julia> geometry = CubicGrid((3,4));
+

See also CubicGrid.

source
Rimu.Hamiltonians.DisplacementsType
Displacements(geometry::CubicGrid) <: AbstractVector{SVector{D,Int}}

Return all valid offset vectors in a CubicGrid. If center=true the (0,0) displacement is placed at the centre of the array.

julia> geometry = CubicGrid((3,4));
 
 julia> reshape(Displacements(geometry), (3,4))
 3×4 reshape(::Displacements{2, CubicGrid{2, (3, 4), (true, true)}}, 3, 4) with eltype StaticArraysCore.SVector{2, Int64}:
@@ -244,7 +244,7 @@
  [-1, -1]  [-1, 0]  [-1, 1]  [-1, 2]
  [0, -1]   [0, 0]   [0, 1]   [0, 2]
  [1, -1]   [1, 0]   [1, 1]   [1, 2]
-
source
Rimu.Hamiltonians.LadderBoundariesFunction
LadderBoundaries(dims...) -> CubicGrid
-LadderBoundaries(dims) -> CubicGrid

Return a CubicGrid where the first dimension is dimensions non-periodic and the rest are periodic. Equivalent to CubicGrid(dims, (true, false, ...)).

source

Index

+source
Rimu.Hamiltonians.LadderBoundariesFunction
LadderBoundaries(dims...) -> CubicGrid
+LadderBoundaries(dims) -> CubicGrid

Return a CubicGrid where the first dimension is dimensions non-periodic and the rest are periodic. Equivalent to CubicGrid(dims, (true, false, ...)).

source

Index

diff --git a/previews/PR308/index.html b/previews/PR308/index.html index 201b3fda8..13e91d869 100644 --- a/previews/PR308/index.html +++ b/previews/PR308/index.html @@ -1,2 +1,2 @@ -Guide · Rimu.jl

Rimu.jl Package Guide

Random Integrators for many-body quantum systems

The grand aim is to develop a toolbox for many-body quantum systems that can be represented by a Hamiltonian in second quantisation language. Currently supported features include:

Interacting with quantum many-body models

  • Full configuration interaction quantum Monte Carlo (FCIQMC), a flavour of projector quantum Monte Carlo for stochastically solving the time-independent Schrödinger equation. See References.
  • Matrix-free exact diagonalisation of quantum Hamiltonians (with external package KrylovKit.jl).
  • Sparse matrix representation of quantum Hamiltonians for exact diagonalisation with sparse linear algebra package of your choice (fastest for small systems).

Representing quantum many-body models

  • A composable and efficient type system for representing single- and multi-component Fock states of bosons, fermions, and mixtures thereof, to be used as a basis for representing Hamiltonians.
  • An interface for defining many-body Hamiltonians.
  • Pre-defined models include:
    • Hubbard model in real space for bosons and fermions and mixtures in 1, 2, and 3 spatial dimensions.
    • Hubbard and related lattice models in momentum space for bosons and fermions in one spatial dimension.
    • Transcorrelated Hamiltonian for contact interactions in one dimension for fermions, as described in Jeszenski et al. arXiv:1806.11268.

Statistical analysis of Monte Carlo data

  • Blocking analysis following Flyvberg & Peterson JCP (1989), and automated with hypothesis testing by Jonsson

PRE (2018).

  • Unbiased estimators for the ground state energy by re-reweighting following Nightingale & Blöte PRB (1986) and Umrigar et al. JCP (1993).

The code supports parallelisation with MPI (harnessing MPI.jl) as well as native Julia threading (experimental). In the future, we may add tools to solve the time-dependent Schrödinger equation and Master equations for open system time evolution.

Concept: Joachim Brand and Elke Pahl.

Contributors: Joachim Brand, Elke Pahl, Mingrui Yang, Matija Čufar, Chris Bradly.

Discussions, help, and additional contributions are acknowledged by Ali Alavi, Didier Adrien, Chris Scott (NeSI), Alexander Pletzer (NeSI).

Installation

Installing Rimu for usage

Rimu is a registered package and can be installed with the package manager. Hit the ] key at the Julia REPL to get into Pkg mode and type

pkg> add Rimu

Alternatively, use

julia> using Pkg; Pkg.add(name="Rimu")

in order to install Rimu from a script.

Installing Rimu for development

In order to be able to edit the source code, push changes, change and make new git branches, etc., clone the git repository with git clone to a convenient location, e.g. ~/mygitpackagefolder/. Then hit the ] key at the Julia REPL to get into Pkg mode and type

pkg> develop ~/mygitpackagefolder/rimu.jl

where the file path has to be adjusted to the location of the cloned git repository.

Usage

The package is now installed and can be imported with

julia> using Rimu

When planning to edit the code of the package it is advisable to use the Revise package by issuing

julia> using Revise

before using Rimu. This will track any changes made to the source code of Rimu and the changed package will be available after saving the source code (hopefully, and most of the time, without restarting the Julia REPL).

Rimu offers a number of tools for representing Hamiltonians (see Hamiltonians) and state vectors / wave functions (see DictVectors) as well as algorithms to find the ground state, e.g. ProjectorMonteCarloProblem, ExactDiagonalizationProblem.

Scripts

Rimu is written as a Julia package to be imported with using Rimu as described above. It supplies useful functions and types. Performing actual calculations and analysing the results is done with scripts. The folder scripts/ contains a collections of scripts that are either examples for use of the Rimu package or useful scripts for data analysis. In particular:

  • scripts/BHM-example.jl is an example script that runs fciqmc on the 1D Bose-Hubbard model. A data frame with results is written to the file fciqmcdata.arrow.
  • scripts/BHM-example-mpi.jl demonstrates basic usage of Rimu with MPI.

MPI

The Rimu package can run in parallel on different processes or node and distribute work by making use of MPI, or "message passing interface". For example, running

> julia scripts/BHM-example.jl

will run on one processor with the main computation (i.e. after package loading and compilation) completing in 2.69 seconds.

Running

> mpirun -np 4 julia scripts/BHM-example-mpi.jl

on the same hardware makes use of 4 cores and the main part completes in 1.04 seconds, a speedup factor of 2.6. This seems reasonable, given that extra work needs to be done for communicating between different processes.

Using MPI parallelism with Rimu is easy. Enabling MPI enabled automatically if PDVec is used to store a vector. In that case, data will be stored in a distributed fashion among the MPI ranks and only communicated between ranks when necessary.

Compatibility

We recommend using Rimu with the latest Julia release version. Rimu requires at least julia v1.9.

References

The code implements the FCIQMC algorithm originally described in

  • "Fermion Monte Carlo without fixed nodes: A game of life, death, and annihilation in Slater determinant space", G. H. Booth, A. J. W. Thom, A. Alavi, J. Chem. Phys. 131, 054106 (2009).
  • "Communications: Survival of the fittest: accelerating convergence in full configuration-interaction quantum Monte Carlo.", D. Cleland, G. H. Booth, A. Alavi, J. Chem. Phys. 132, 041103 (2010).

Scientific papers describing additional features implemented in Rimu:

  • "Improved walker population control for full configuration interaction quantum Monte Carlo", M. Yang, E. Pahl, J. Brand, J. Chem. Phys. 153, 170143 (2020); arXiv:2008.01927.
  • "Stochastic differential equation approach to understanding the population control bias in full configuration interaction quantum Monte Carlo", J. Brand, M. Yang, E. Pahl, arXiv:2103.07800 (2021).

Papers discussing results obtained with Rimu:

  • "Polaron-Depleton Transition in the Yrast Excitations of a One-Dimensional Bose Gas with a Mobile Impurity", M. Yang, M. Čufar, E. Pahl, J. Brand, Condens. Matter 7, 15 (2022).
  • "Magnetic impurity in a one-dimensional few-fermion system", L. Rammelmüller, D. Huber, M. Čufar, J. Brand, A. Volosniev, arXiv:2204.01606 (2022).
+Guide · Rimu.jl

Rimu.jl Package Guide

Random Integrators for many-body quantum systems

The grand aim is to develop a toolbox for many-body quantum systems that can be represented by a Hamiltonian in second quantisation language. Currently supported features include:

Interacting with quantum many-body models

  • Full configuration interaction quantum Monte Carlo (FCIQMC), a flavour of projector quantum Monte Carlo for stochastically solving the time-independent Schrödinger equation. See References.
  • Matrix-free exact diagonalisation of quantum Hamiltonians (with external package KrylovKit.jl).
  • Sparse matrix representation of quantum Hamiltonians for exact diagonalisation with sparse linear algebra package of your choice (fastest for small systems).

Representing quantum many-body models

  • A composable and efficient type system for representing single- and multi-component Fock states of bosons, fermions, and mixtures thereof, to be used as a basis for representing Hamiltonians.
  • An interface for defining many-body Hamiltonians.
  • Pre-defined models include:
    • Hubbard model in real space for bosons and fermions and mixtures in 1, 2, and 3 spatial dimensions.
    • Hubbard and related lattice models in momentum space for bosons and fermions in one spatial dimension.
    • Transcorrelated Hamiltonian for contact interactions in one dimension for fermions, as described in Jeszenski et al. arXiv:1806.11268.

Statistical analysis of Monte Carlo data

  • Blocking analysis following Flyvberg & Peterson JCP (1989), and automated with hypothesis testing by Jonsson

PRE (2018).

  • Unbiased estimators for the ground state energy by re-reweighting following Nightingale & Blöte PRB (1986) and Umrigar et al. JCP (1993).

The code supports parallelisation with MPI (harnessing MPI.jl) as well as native Julia threading (experimental). In the future, we may add tools to solve the time-dependent Schrödinger equation and Master equations for open system time evolution.

Concept: Joachim Brand and Elke Pahl.

Contributors: Joachim Brand, Elke Pahl, Mingrui Yang, Matija Čufar, Chris Bradly.

Discussions, help, and additional contributions are acknowledged by Ali Alavi, Didier Adrien, Chris Scott (NeSI), Alexander Pletzer (NeSI).

Installation

Installing Rimu for usage

Rimu is a registered package and can be installed with the package manager. Hit the ] key at the Julia REPL to get into Pkg mode and type

pkg> add Rimu

Alternatively, use

julia> using Pkg; Pkg.add(name="Rimu")

in order to install Rimu from a script.

Installing Rimu for development

In order to be able to edit the source code, push changes, change and make new git branches, etc., clone the git repository with git clone to a convenient location, e.g. ~/mygitpackagefolder/. Then hit the ] key at the Julia REPL to get into Pkg mode and type

pkg> develop ~/mygitpackagefolder/rimu.jl

where the file path has to be adjusted to the location of the cloned git repository.

Usage

The package is now installed and can be imported with

julia> using Rimu

When planning to edit the code of the package it is advisable to use the Revise package by issuing

julia> using Revise

before using Rimu. This will track any changes made to the source code of Rimu and the changed package will be available after saving the source code (hopefully, and most of the time, without restarting the Julia REPL).

Rimu offers a number of tools for representing Hamiltonians (see Hamiltonians) and state vectors / wave functions (see DictVectors) as well as algorithms to find the ground state, e.g. ProjectorMonteCarloProblem, ExactDiagonalizationProblem.

Scripts

Rimu is written as a Julia package to be imported with using Rimu as described above. It supplies useful functions and types. Performing actual calculations and analysing the results is done with scripts. The folder scripts/ contains a collections of scripts that are either examples for use of the Rimu package or useful scripts for data analysis. In particular:

  • scripts/BHM-example.jl is an example script that runs fciqmc on the 1D Bose-Hubbard model. A data frame with results is written to the file fciqmcdata.arrow.
  • scripts/BHM-example-mpi.jl demonstrates basic usage of Rimu with MPI.

MPI

The Rimu package can run in parallel on different processes or node and distribute work by making use of MPI, or "message passing interface". For example, running

> julia scripts/BHM-example.jl

will run on one processor with the main computation (i.e. after package loading and compilation) completing in 2.69 seconds.

Running

> mpirun -np 4 julia scripts/BHM-example-mpi.jl

on the same hardware makes use of 4 cores and the main part completes in 1.04 seconds, a speedup factor of 2.6. This seems reasonable, given that extra work needs to be done for communicating between different processes.

Using MPI parallelism with Rimu is easy. Enabling MPI enabled automatically if PDVec is used to store a vector. In that case, data will be stored in a distributed fashion among the MPI ranks and only communicated between ranks when necessary.

Compatibility

We recommend using Rimu with the latest Julia release version. Rimu requires at least julia v1.9.

References

The code implements the FCIQMC algorithm originally described in

  • "Fermion Monte Carlo without fixed nodes: A game of life, death, and annihilation in Slater determinant space", G. H. Booth, A. J. W. Thom, A. Alavi, J. Chem. Phys. 131, 054106 (2009).
  • "Communications: Survival of the fittest: accelerating convergence in full configuration-interaction quantum Monte Carlo.", D. Cleland, G. H. Booth, A. Alavi, J. Chem. Phys. 132, 041103 (2010).

Scientific papers describing additional features implemented in Rimu:

  • "Improved walker population control for full configuration interaction quantum Monte Carlo", M. Yang, E. Pahl, J. Brand, J. Chem. Phys. 153, 170143 (2020); arXiv:2008.01927.
  • "Stochastic differential equation approach to understanding the population control bias in full configuration interaction quantum Monte Carlo", J. Brand, M. Yang, E. Pahl, arXiv:2103.07800 (2021).

Papers discussing results obtained with Rimu:

  • "Polaron-Depleton Transition in the Yrast Excitations of a One-Dimensional Bose Gas with a Mobile Impurity", M. Yang, M. Čufar, E. Pahl, J. Brand, Condens. Matter 7, 15 (2022).
  • "Magnetic impurity in a one-dimensional few-fermion system", L. Rammelmüller, D. Huber, M. Čufar, J. Brand, A. Volosniev, arXiv:2204.01606 (2022).
diff --git a/previews/PR308/interfaces.html b/previews/PR308/interfaces.html index 2599c6e53..51f13a644 100644 --- a/previews/PR308/interfaces.html +++ b/previews/PR308/interfaces.html @@ -1,2 +1,2 @@ -Interfaces · Rimu.jl

Module Interfaces

Rimu.InterfacesModule
module Interfaces

This module contains interfaces that can be used to extend and modify the algorithms and behaviours of Rimu.

Interfaces

Follow the links for the definitions of the interfaces!

Additional exports

Interface functions forAbstractHamiltonians:

working with AbstractDVecs and StochasticStyle

Functions Rimu.jl uses to do FCIQMC:

source
+Interfaces · Rimu.jl

Module Interfaces

Rimu.InterfacesModule
module Interfaces

This module contains interfaces that can be used to extend and modify the algorithms and behaviours of Rimu.

Interfaces

Follow the links for the definitions of the interfaces!

Additional exports

Interface functions forAbstractHamiltonians:

working with AbstractDVecs and StochasticStyle

Functions Rimu.jl uses to do FCIQMC:

source
diff --git a/previews/PR308/mpi.html b/previews/PR308/mpi.html index 288f0278b..084c3d71c 100644 --- a/previews/PR308/mpi.html +++ b/previews/PR308/mpi.html @@ -13,4 +13,4 @@ @mpi_root println("vector length is $len")

Threaded operations and reductions

When using functions that take anonymous functions, such as map(!), sum, or mapreduce, it is important that the anonymous functions passed to them do not perform any MPI-reducing operations (length, norm, sum, etc.). These anonymous functions are executed on multiple threads and initiating MPI communication from multiple threads may cause issues.

As an example, suppose we want to scale a vector by its length by using map!. The correct way to write this code is as

len = length(pdvec)
 map!(values(pdvec)) do x
 	x / len
-end

Similar to the previous example, len is calculated first and not within the body of map!. In this specific case, an even better option is to use the scale! function from VectorInterface.jl:

scale!(pdvec, 1 / length(pdvec))
+end

Similar to the previous example, len is calculated first and not within the body of map!. In this specific case, an even better option is to use the scale! function from VectorInterface.jl:

scale!(pdvec, 1 / length(pdvec))
diff --git a/previews/PR308/projectormontecarlo.html b/previews/PR308/projectormontecarlo.html index 7733d14b2..8e1072917 100644 --- a/previews/PR308/projectormontecarlo.html +++ b/previews/PR308/projectormontecarlo.html @@ -9,4 +9,4 @@ true julia> size(DataFrame(simulation)) -(100, 9)

Further keyword arguments:

  • starting_step = 1: Starting step of the simulation.
  • wall_time = Inf: Maximum time allowed for the simulation.
  • simulation_plan = SimulationPlan(; starting_step, last_step, wall_time): Defines the duration of the simulation. Takes precedence over last_step and wall_time.
  • ζ = 0.08: Damping parameter for the shift update.
  • ξ = ζ^2/4: Forcing parameter for the shift update.
  • shift_strategy = DoubleLogUpdate(; target_walkers, ζ, ξ): How to update the shift, see ShiftStrategy.
  • time_step_strategy = ConstantTimeStep(): Adjust time step or not, see TimeStepStrategy.
  • algorithm = FCIQMC(; shift_strategy, time_step_strategy): The algorithm to use. Currenlty only FCIQMC is implemented.
  • shift: Initial shift value or collection of shift values. Determined by default from the Hamiltonian and the starting vectors.
  • initial_shift_parameters: Initial shift parameters or collection of initial shift parameters. Overrides shift if provided.
  • max_length = 2 * target_walkers + 100: Maximum length of the vectors.
  • display_name = "PMCSimulation": Name displayed in progress bar (via ProgressLogging).
  • metadata: User-supplied metadata to be added to the report. Must be an iterable of pairs or a NamedTuple, e.g. metadata = ("key1" => "value1", "key2" => "value2"). All metadata is converted to strings.
  • random_seed = true: Provide and store a seed for the random number generator. If set to true, a new random seed is generated from RandomDevice(). If set to number, this number is used as the seed. This seed is used by solve (and init) to re-seed the default random number generator (consistently on each MPI rank) such that solveing the same ProjectorMonteCarloProblem twice will yield identical results. If set to false, no seed is used and consecutive random numbers are used.
  • minimum_size = 2*num_spectral_states(spectral_strategy): The minimum size of the basis used to construct starting vectors for simulations of spectral states, if start_at is not provided.

See also init, solve.

source
CommonSolve.initFunction
init(p::ExactDiagonalizationProblem, [algorithm]; kwargs...)

Initialize a solver for an ExactDiagonalizationProblem p with an optional algorithm. Returns a solver instance that can be solved with solve.

For a description of the keyword arguments, see the documentation for ExactDiagonalizationProblem.

source
init(problem::ProjectorMonteCarloProblem; copy_vectors=true)::PMCSimulation

Initialise a Rimu.PMCSimulation.

See also ProjectorMonteCarloProblem, solve!, solve, step!, Rimu.PMCSimulation.

source
CommonSolve.solve!Function
solve!(sm::PMCSimulation; kwargs...)::PMCSimulation

Solve a Rimu.PMCSimulation until the last step is completed or the wall time limit is reached.

To continue a previously completed simulation, set a new last_step or wall_time using the keyword arguments. Optionally, changes can be made to the replica_strategy, the post_step_strategy, or the reporting_strategy.

Optional keyword arguments:

  • last_step = nothing: Set the last step to a new value and continue the simulation.
  • wall_time = nothing: Set the allowed wall time to a new value and continue the simulation.
  • reset_time = false: Reset the elapsed_time counter and continue the simulation.
  • empty_report = false: Empty the report before continuing the simulation.
  • replica_strategy = nothing: Change the replica strategy. Requires the number of replicas to match the number of replicas in the simulation sm. Implies empty_report = true.
  • post_step_strategy = nothing: Change the post-step strategy. Implies empty_report = true.
  • reporting_strategy = nothing: Change the reporting strategy. Implies empty_report = true.
  • metadata = nothing: Add metadata to the report.

See also ProjectorMonteCarloProblem, init, solve, step!, Rimu.PMCSimulation.

source

After solve or solve! have been called the returned PMCSimulation contains the results of the projector Monte Carlo calculation.

PMCSimulation and report as a DataFrame

Rimu.PMCSimulationType
PMCSimulation

Holds the state and the results of a projector quantum Monte Carlo (PMC) simulation. Is returned by init(::ProjectorMonteCarloProblem) and solved with solve!(::PMCSimulation).

Obtain the results of a simulation sm as a DataFrame with DataFrame(sm).

Fields

  • problem::ProjectorMonteCarloProblem: The problem that was solved
  • state::Rimu.ReplicaState: The current state of the simulation
  • report::Rimu.Report: The report of the simulation
  • modified::Bool: Whether the simulation has been modified
  • aborted::Bool: Whether the simulation has been aborted
  • success::Bool: Whether the simulation has been completed successfully
  • message::String: A message about the simulation status
  • elapsed_time::Float64: The time elapsed during the simulation

See also state_vectors, ProjectorMonteCarloProblem, init, solve!.

source

The DataFrame returned from DataFrame(::PMCSimulation) contains the time series data from the projector Monte Carlo simulation that is of primary interest for analysis. Depending on the reporting_strategy and other options passed as keyword arguments to ProjectorMonteCarloProblem it can have different numbers of rows and columns. The rows correspond to the reported time steps (Monte Carlo steps). There is at least one column with the name :step. Further columns are usually present with additional data reported from the simulation.

For the default option algorithm = FCIQMC(; shift_strategy, time_step_strategy) with a single replica (n_replicas = 1) and single spectral state, the fields :shift, :norm, :len will be present as well as others depending on the style argument and the post_step_strategy.

If multiple replicas or spectral states are requested, then the relevant field names in the DataFrame will have a suffix identifying the respective replica simulation, e.g. the shifts will be reported as shift_1, shift_2, ...

Many tools for analysing the time series data obtained from a ProjectorMonteCarloProblem are contained in the Module StatsTools.

+(100, 9)

Further keyword arguments:

  • starting_step = 1: Starting step of the simulation.
  • wall_time = Inf: Maximum time allowed for the simulation.
  • simulation_plan = SimulationPlan(; starting_step, last_step, wall_time): Defines the duration of the simulation. Takes precedence over last_step and wall_time.
  • ζ = 0.08: Damping parameter for the shift update.
  • ξ = ζ^2/4: Forcing parameter for the shift update.
  • shift_strategy = DoubleLogUpdate(; target_walkers, ζ, ξ): How to update the shift, see ShiftStrategy.
  • time_step_strategy = ConstantTimeStep(): Adjust time step or not, see TimeStepStrategy.
  • algorithm = FCIQMC(; shift_strategy, time_step_strategy): The algorithm to use. Currenlty only FCIQMC is implemented.
  • shift: Initial shift value or collection of shift values. Determined by default from the Hamiltonian and the starting vectors.
  • initial_shift_parameters: Initial shift parameters or collection of initial shift parameters. Overrides shift if provided.
  • max_length = 2 * target_walkers + 100: Maximum length of the vectors.
  • display_name = "PMCSimulation": Name displayed in progress bar (via ProgressLogging).
  • metadata: User-supplied metadata to be added to the report. Must be an iterable of pairs or a NamedTuple, e.g. metadata = ("key1" => "value1", "key2" => "value2"). All metadata is converted to strings.
  • random_seed = true: Provide and store a seed for the random number generator. If set to true, a new random seed is generated from RandomDevice(). If set to number, this number is used as the seed. This seed is used by solve (and init) to re-seed the default random number generator (consistently on each MPI rank) such that solveing the same ProjectorMonteCarloProblem twice will yield identical results. If set to false, no seed is used and consecutive random numbers are used.
  • minimum_size = 2*num_spectral_states(spectral_strategy): The minimum size of the basis used to construct starting vectors for simulations of spectral states, if start_at is not provided.

See also init, solve.

source
CommonSolve.initFunction
init(p::ExactDiagonalizationProblem, [algorithm]; kwargs...)

Initialize a solver for an ExactDiagonalizationProblem p with an optional algorithm. Returns a solver instance that can be solved with solve.

For a description of the keyword arguments, see the documentation for ExactDiagonalizationProblem.

source
init(problem::ProjectorMonteCarloProblem; copy_vectors=true)::PMCSimulation

Initialise a Rimu.PMCSimulation.

See also ProjectorMonteCarloProblem, solve!, solve, step!, Rimu.PMCSimulation.

source
CommonSolve.solve!Function
solve!(sm::PMCSimulation; kwargs...)::PMCSimulation

Solve a Rimu.PMCSimulation until the last step is completed or the wall time limit is reached.

To continue a previously completed simulation, set a new last_step or wall_time using the keyword arguments. Optionally, changes can be made to the replica_strategy, the post_step_strategy, or the reporting_strategy.

Optional keyword arguments:

  • last_step = nothing: Set the last step to a new value and continue the simulation.
  • wall_time = nothing: Set the allowed wall time to a new value and continue the simulation.
  • reset_time = false: Reset the elapsed_time counter and continue the simulation.
  • empty_report = false: Empty the report before continuing the simulation.
  • replica_strategy = nothing: Change the replica strategy. Requires the number of replicas to match the number of replicas in the simulation sm. Implies empty_report = true.
  • post_step_strategy = nothing: Change the post-step strategy. Implies empty_report = true.
  • reporting_strategy = nothing: Change the reporting strategy. Implies empty_report = true.
  • metadata = nothing: Add metadata to the report.

See also ProjectorMonteCarloProblem, init, solve, step!, Rimu.PMCSimulation.

source

After solve or solve! have been called the returned PMCSimulation contains the results of the projector Monte Carlo calculation.

PMCSimulation and report as a DataFrame

Rimu.PMCSimulationType
PMCSimulation

Holds the state and the results of a projector quantum Monte Carlo (PMC) simulation. Is returned by init(::ProjectorMonteCarloProblem) and solved with solve!(::PMCSimulation).

Obtain the results of a simulation sm as a DataFrame with DataFrame(sm).

Fields

  • problem::ProjectorMonteCarloProblem: The problem that was solved
  • state::Rimu.ReplicaState: The current state of the simulation
  • report::Rimu.Report: The report of the simulation
  • modified::Bool: Whether the simulation has been modified
  • aborted::Bool: Whether the simulation has been aborted
  • success::Bool: Whether the simulation has been completed successfully
  • message::String: A message about the simulation status
  • elapsed_time::Float64: The time elapsed during the simulation

See also state_vectors, ProjectorMonteCarloProblem, init, solve!.

source

The DataFrame returned from DataFrame(::PMCSimulation) contains the time series data from the projector Monte Carlo simulation that is of primary interest for analysis. Depending on the reporting_strategy and other options passed as keyword arguments to ProjectorMonteCarloProblem it can have different numbers of rows and columns. The rows correspond to the reported time steps (Monte Carlo steps). There is at least one column with the name :step. Further columns are usually present with additional data reported from the simulation.

For the default option algorithm = FCIQMC(; shift_strategy, time_step_strategy) with a single replica (n_replicas = 1) and single spectral state, the fields :shift, :norm, :len will be present as well as others depending on the style argument and the post_step_strategy.

If multiple replicas or spectral states are requested, then the relevant field names in the DataFrame will have a suffix identifying the respective replica simulation, e.g. the shifts will be reported as shift_1, shift_2, ...

Many tools for analysing the time series data obtained from a ProjectorMonteCarloProblem are contained in the Module StatsTools.

diff --git a/previews/PR308/rimuio.html b/previews/PR308/rimuio.html index cd6419623..232aabf17 100644 --- a/previews/PR308/rimuio.html +++ b/previews/PR308/rimuio.html @@ -1,4 +1,4 @@ -I/O · Rimu.jl

Module RimuIO

Rimu.RimuIO.DVecAsTableType
struct DVecAsTable

Wrapper over the storage of a DVec that allows us to treat a DVec as a table from Tables.jl. Constructed with Tables.table(::DVec).

source
Rimu.RimuIO.load_dfMethod
load_df(filename; propagate_metadata = true, add_filename = true) -> DataFrame

Load Arrow file into DataFrame. Optionally propagate metadata to DataFrame and add the file name as metadata.

See also RimuIO.save_df.

source
Rimu.RimuIO.load_stateMethod
load_state(filename; kwargs...) -> PDVec, NamedTuple
+I/O · Rimu.jl

Module RimuIO

Rimu.RimuIO.DVecAsTableType
struct DVecAsTable

Wrapper over the storage of a DVec that allows us to treat a DVec as a table from Tables.jl. Constructed with Tables.table(::DVec).

source
Rimu.RimuIO.load_dfMethod
load_df(filename; propagate_metadata = true, add_filename = true) -> DataFrame

Load Arrow file into DataFrame. Optionally propagate metadata to DataFrame and add the file name as metadata.

See also RimuIO.save_df.

source
Rimu.RimuIO.load_stateMethod
load_state(filename; kwargs...) -> PDVec, NamedTuple
 load_state(PDVec, filename; kwargs...) -> PDVec, NamedTuple
-load_state(DVec, filename; kwargs...) -> DVec, NamedTuple

Load the state saved in the Arrow file filename. kwargs are passed to the constructor of PDVec/DVec. Any metadata stored in the file is be parsed as a number (if possible) and returned alongside the vector in a NamedTuple.

See also save_state.

source
Rimu.RimuIO.save_dfMethod
save_df(filename, df::DataFrame; kwargs...)

Save dataframe in Arrow format.

Keyword arguments are passed on to Arrow.write. Compression is enabled by default for large DataFrames (over 10,000 rows).

Table-level metadata of the DataFrame is saved as Arrow metadata (with String value) unless overwritten with the keyword argument metadata.

See also RimuIO.load_df.

source
Rimu.RimuIO.save_stateMethod
save_state(filename, vector; io, kwargs...)

Save PDVec or DVec vector to an arrow file filename.

io determines the output stream to write progress to. Defaults to stderr when MPI is enabled and devnull otherwise.

All other kwargs are saved as strings to the arrow file and will be parsed back when the state is loaded.

See also load_state.

source

Index

+load_state(DVec, filename; kwargs...) -> DVec, NamedTuple

Load the state saved in the Arrow file filename. kwargs are passed to the constructor of PDVec/DVec. Any metadata stored in the file is be parsed as a number (if possible) and returned alongside the vector in a NamedTuple.

See also save_state.

source
Rimu.RimuIO.save_dfMethod
save_df(filename, df::DataFrame; kwargs...)

Save dataframe in Arrow format.

Keyword arguments are passed on to Arrow.write. Compression is enabled by default for large DataFrames (over 10,000 rows).

Table-level metadata of the DataFrame is saved as Arrow metadata (with String value) unless overwritten with the keyword argument metadata.

See also RimuIO.load_df.

source
Rimu.RimuIO.save_stateMethod
save_state(filename, vector; io, kwargs...)

Save PDVec or DVec vector to an arrow file filename.

io determines the output stream to write progress to. Defaults to stderr when MPI is enabled and devnull otherwise.

All other kwargs are saved as strings to the arrow file and will be parsed back when the state is loaded.

See also load_state.

source

Index

diff --git a/previews/PR308/search_index.js b/previews/PR308/search_index.js index 501a5ea18..fde7373e8 100644 --- a/previews/PR308/search_index.js +++ b/previews/PR308/search_index.js @@ -1,3 +1,3 @@ var documenterSearchIndex = {"docs": -[{"location":"mpi.html#Working-with-MPI","page":"Using MPI","title":"Working with MPI","text":"","category":"section"},{"location":"mpi.html","page":"Using MPI","title":"Using MPI","text":"If you are using PDVecs to store your vectors, working with MPI should be fairly straightforward. Generally, PDVec will work with MPI automatically, as long as MPI is set up correctly and a few common pitfalls are avoided.","category":"page"},{"location":"mpi.html#Configuring-MPI","page":"Using MPI","title":"Configuring MPI","text":"","category":"section"},{"location":"mpi.html","page":"Using MPI","title":"Using MPI","text":"When running on a cluster, ensure that MPI.jl is using the system binary. See the MPI.jl documentation for more information.","category":"page"},{"location":"mpi.html","page":"Using MPI","title":"Using MPI","text":"It is always a good idea to start your script with a quick test that ensures the MPI is set up correctly. One way to do this is to open with","category":"page"},{"location":"mpi.html","page":"Using MPI","title":"Using MPI","text":"mpi_allprintln(\"hello\")","category":"page"},{"location":"mpi.html","page":"Using MPI","title":"Using MPI","text":"which should print something like","category":"page"},{"location":"mpi.html","page":"Using MPI","title":"Using MPI","text":"[ rank 0: hello\n[ rank 1: hello\n[ rank 2: hello\n[ rank 3: hello","category":"page"},{"location":"mpi.html","page":"Using MPI","title":"Using MPI","text":"If it prints rank 0 several times, the code will run, but ranks will not communicate.","category":"page"},{"location":"mpi.html#Using-Slurm","page":"Using MPI","title":"Using Slurm","text":"","category":"section"},{"location":"mpi.html","page":"Using MPI","title":"Using MPI","text":"When using PDVec, the recommended setup is to use threads to parallelise the computation within a node, and to only use MPI for inter-node communication. In a slurm script, this is done as follows:","category":"page"},{"location":"mpi.html","page":"Using MPI","title":"Using MPI","text":"...\n#SBATCH --ntasks-per-node=1\n#SBATCH --nodes=4 # replace 4 with the desired number of nodes\n#SBATCH --cpus-per-task=28 # replace 28 with the number of cores available in a node\n#SBATCH --hint=nomultithread # don't use hyperthreading\n...\n\nsrun julia --project -tauto script.jl","category":"page"},{"location":"mpi.html","page":"Using MPI","title":"Using MPI","text":"On some clusters, additional settings must be used with srun, for example the CTCP cluster requires the following.","category":"page"},{"location":"mpi.html","page":"Using MPI","title":"Using MPI","text":"srun mpi=pmi2 julia --project -tauto script.jl","category":"page"},{"location":"mpi.html#Common-pitfalls-with-reducing-functions","page":"Using MPI","title":"Common pitfalls with reducing functions","text":"","category":"section"},{"location":"mpi.html#Using-@mpi_root","page":"Using MPI","title":"Using @mpi_root","text":"","category":"section"},{"location":"mpi.html","page":"Using MPI","title":"Using MPI","text":"Take care to not use reducing functions (such as length, sum, norm, ...) inside @mpi_root blocks. Doing so will only initiate the distributed reduction on one rank only, which will cause the code to go out of sync and freeze. As an example, to report the current length of a vector, calculate the length before the @mpi_root block:","category":"page"},{"location":"mpi.html","page":"Using MPI","title":"Using MPI","text":"len = length(pdvec)\n@mpi_root println(\"vector length is $len\")","category":"page"},{"location":"mpi.html#Threaded-operations-and-reductions","page":"Using MPI","title":"Threaded operations and reductions","text":"","category":"section"},{"location":"mpi.html","page":"Using MPI","title":"Using MPI","text":"When using functions that take anonymous functions, such as map(!), sum, or mapreduce, it is important that the anonymous functions passed to them do not perform any MPI-reducing operations (length, norm, sum, etc.). These anonymous functions are executed on multiple threads and initiating MPI communication from multiple threads may cause issues.","category":"page"},{"location":"mpi.html","page":"Using MPI","title":"Using MPI","text":"As an example, suppose we want to scale a vector by its length by using map!. The correct way to write this code is as","category":"page"},{"location":"mpi.html","page":"Using MPI","title":"Using MPI","text":"len = length(pdvec)\nmap!(values(pdvec)) do x\n\tx / len\nend","category":"page"},{"location":"mpi.html","page":"Using MPI","title":"Using MPI","text":"Similar to the previous example, len is calculated first and not within the body of map!. In this specific case, an even better option is to use the scale! function from VectorInterface.jl:","category":"page"},{"location":"mpi.html","page":"Using MPI","title":"Using MPI","text":"scale!(pdvec, 1 / length(pdvec))","category":"page"},{"location":"projectormontecarlo.html#Projector-Monte-Carlo-/-FCIQMC","page":"Projector Monte Carlo","title":"Projector Monte Carlo / FCIQMC","text":"","category":"section"},{"location":"projectormontecarlo.html","page":"Projector Monte Carlo","title":"Projector Monte Carlo","text":"The purpose of Projector Monte Carlo is to stochastically sample the ground state, i.e. the eigenvector corresponding to the lowest eigenvalue of a quantum Hamiltonian, or more generally, a very large matrix. Rimu implements a flavor of Projector Monte Carlo called Full Configuration Interaction Quantum Monte Carlo (FCIQMC).","category":"page"},{"location":"projectormontecarlo.html#ProjectorMonteCarloProblem","page":"Projector Monte Carlo","title":"ProjectorMonteCarloProblem","text":"","category":"section"},{"location":"projectormontecarlo.html","page":"Projector Monte Carlo","title":"Projector Monte Carlo","text":"To run a projector Monte Carlo simulation you set up a problem with ProjectorMonteCarloProblem and solve it with solve. Alternatively you can init it with to obtain a PMCSimulation struct, step! through time steps, and solve! it to completion. ","category":"page"},{"location":"projectormontecarlo.html","page":"Projector Monte Carlo","title":"Projector Monte Carlo","text":"ProjectorMonteCarloProblem\ninit\nsolve\nsolve!\nstep!","category":"page"},{"location":"projectormontecarlo.html#Rimu.ProjectorMonteCarloProblem-projectormontecarlo","page":"Projector Monte Carlo","title":"Rimu.ProjectorMonteCarloProblem","text":"ProjectorMonteCarloProblem(hamiltonian::AbstractHamiltonian; kwargs...)\n\nDefines a problem to be solved by projector quantum Monte Carlo (QMC) methods, such as the the FCIQMC algorithm.\n\nCommon keyword arguments and defaults:\n\ntime_step = 0.01: Initial time step size.\nlast_step = 100: Controls the number of steps.\ntarget_walkers = 1_000: Target for the 1-norm of the coefficient vector.\nstart_at = starting_address(hamiltonian): Define the initial state vector(s). An r s matrix of state vectors can be passed where r is the number of replicas and s the number of spectral states. See also default_starting_vector.\nstyle = IsDynamicSemistochastic(): The StochasticStyle of the simulation.\ninitiator = false: Whether to use initiators. Can be true, false, or a valid InitiatorRule.\nthreading: Default is to use multithreading and/or MPI if available. Set to true to force PDVec for the starting vector, false for serial computation; may be overridden by start_at.\nreporting_strategy = ReportDFAndInfo(): How and when to report results, see ReportingStrategy.\npost_step_strategy = (): Extract observables (e.g. ProjectedEnergy), see PostStepStrategy.\nn_replicas = 1: Number of synchronised independent simulations.\nreplica_strategy = NoStats(n_replicas): Which results to report from replica simulations, see ReplicaStrategy.\nn_spectral = 1: Number of targeted spectral states. Set n_spectral > 1 to find excited states.\nspectral_strategy = GramSchmidt(n_spectral): The SpectralStrategy used for orthogonalizing spectral states.\n\nExample\n\njulia> hamiltonian = HubbardReal1D(BoseFS(1,2,3));\n\njulia> problem = ProjectorMonteCarloProblem(hamiltonian; target_walkers = 500, last_step = 100);\n\njulia> simulation = solve(problem);\n\njulia> simulation.success[]\ntrue\n\njulia> size(DataFrame(simulation))\n(100, 9)\n\nFurther keyword arguments:\n\nstarting_step = 1: Starting step of the simulation.\nwall_time = Inf: Maximum time allowed for the simulation.\nsimulation_plan = SimulationPlan(; starting_step, last_step, wall_time): Defines the duration of the simulation. Takes precedence over last_step and wall_time.\nζ = 0.08: Damping parameter for the shift update.\nξ = ζ^2/4: Forcing parameter for the shift update.\nshift_strategy = DoubleLogUpdate(; target_walkers, ζ, ξ): How to update the shift, see ShiftStrategy.\ntime_step_strategy = ConstantTimeStep(): Adjust time step or not, see TimeStepStrategy.\nalgorithm = FCIQMC(; shift_strategy, time_step_strategy): The algorithm to use. Currenlty only FCIQMC is implemented.\nshift: Initial shift value or collection of shift values. Determined by default from the Hamiltonian and the starting vectors.\ninitial_shift_parameters: Initial shift parameters or collection of initial shift parameters. Overrides shift if provided.\nmax_length = 2 * target_walkers + 100: Maximum length of the vectors.\ndisplay_name = \"PMCSimulation\": Name displayed in progress bar (via ProgressLogging).\nmetadata: User-supplied metadata to be added to the report. Must be an iterable of pairs or a NamedTuple, e.g. metadata = (\"key1\" => \"value1\", \"key2\" => \"value2\"). All metadata is converted to strings.\nrandom_seed = true: Provide and store a seed for the random number generator. If set to true, a new random seed is generated from RandomDevice(). If set to number, this number is used as the seed. This seed is used by solve (and init) to re-seed the default random number generator (consistently on each MPI rank) such that solveing the same ProjectorMonteCarloProblem twice will yield identical results. If set to false, no seed is used and consecutive random numbers are used.\nminimum_size = 2*num_spectral_states(spectral_strategy): The minimum size of the basis used to construct starting vectors for simulations of spectral states, if start_at is not provided.\n\nSee also init, solve.\n\n\n\n\n\n","category":"type"},{"location":"projectormontecarlo.html#CommonSolve.init-projectormontecarlo","page":"Projector Monte Carlo","title":"CommonSolve.init","text":"init(p::ExactDiagonalizationProblem, [algorithm]; kwargs...)\n\nInitialize a solver for an ExactDiagonalizationProblem p with an optional algorithm. Returns a solver instance that can be solved with solve.\n\nFor a description of the keyword arguments, see the documentation for ExactDiagonalizationProblem.\n\n\n\n\n\ninit(problem::ProjectorMonteCarloProblem; copy_vectors=true)::PMCSimulation\n\nInitialise a Rimu.PMCSimulation.\n\nSee also ProjectorMonteCarloProblem, solve!, solve, step!, Rimu.PMCSimulation.\n\n\n\n\n\n","category":"function"},{"location":"projectormontecarlo.html#CommonSolve.solve-projectormontecarlo","page":"Projector Monte Carlo","title":"CommonSolve.solve","text":"solve(::ProjectorMonteCarloProblem)::PMCSimulation\n\nInitialize and solve a ProjectorMonteCarloProblem until the last step is completed or the wall time limit is reached.\n\nSee also init, solve!, step!, Rimu.PMCSimulation, and solve(::ExactDiagonalizationProblem).\n\n\n\n\n\n","category":"function"},{"location":"projectormontecarlo.html#CommonSolve.solve!-projectormontecarlo","page":"Projector Monte Carlo","title":"CommonSolve.solve!","text":"solve!(sm::PMCSimulation; kwargs...)::PMCSimulation\n\nSolve a Rimu.PMCSimulation until the last step is completed or the wall time limit is reached.\n\nTo continue a previously completed simulation, set a new last_step or wall_time using the keyword arguments. Optionally, changes can be made to the replica_strategy, the post_step_strategy, or the reporting_strategy.\n\nOptional keyword arguments:\n\nlast_step = nothing: Set the last step to a new value and continue the simulation.\nwall_time = nothing: Set the allowed wall time to a new value and continue the simulation.\nreset_time = false: Reset the elapsed_time counter and continue the simulation.\nempty_report = false: Empty the report before continuing the simulation.\nreplica_strategy = nothing: Change the replica strategy. Requires the number of replicas to match the number of replicas in the simulation sm. Implies empty_report = true.\npost_step_strategy = nothing: Change the post-step strategy. Implies empty_report = true.\nreporting_strategy = nothing: Change the reporting strategy. Implies empty_report = true.\nmetadata = nothing: Add metadata to the report.\n\nSee also ProjectorMonteCarloProblem, init, solve, step!, Rimu.PMCSimulation.\n\n\n\n\n\n","category":"function"},{"location":"projectormontecarlo.html#CommonSolve.step!-projectormontecarlo","page":"Projector Monte Carlo","title":"CommonSolve.step!","text":"step!(sm::PMCSimulation)::PMCSimulation\n\nAdvance the simulation by one step.\n\nCalling solve! will advance the simulation until the last step or the wall time is exceeded. When completing the simulation without calling solve!, the simulation report needs to be finalised by calling Rimu.finalize_report!.\n\nSee also ProjectorMonteCarloProblem, init, solve!, solve, Rimu.PMCSimulation.\n\n\n\n\n\n","category":"function"},{"location":"projectormontecarlo.html","page":"Projector Monte Carlo","title":"Projector Monte Carlo","text":"After solve or solve! have been called the returned PMCSimulation contains the results of the projector Monte Carlo calculation.","category":"page"},{"location":"projectormontecarlo.html#PMCSimulation-and-report-as-a-DataFrame","page":"Projector Monte Carlo","title":"PMCSimulation and report as a DataFrame","text":"","category":"section"},{"location":"projectormontecarlo.html","page":"Projector Monte Carlo","title":"Projector Monte Carlo","text":"Rimu.PMCSimulation","category":"page"},{"location":"projectormontecarlo.html#Rimu.PMCSimulation-projectormontecarlo","page":"Projector Monte Carlo","title":"Rimu.PMCSimulation","text":"PMCSimulation\n\nHolds the state and the results of a projector quantum Monte Carlo (PMC) simulation. Is returned by init(::ProjectorMonteCarloProblem) and solved with solve!(::PMCSimulation).\n\nObtain the results of a simulation sm as a DataFrame with DataFrame(sm).\n\nFields\n\nproblem::ProjectorMonteCarloProblem: The problem that was solved\nstate::Rimu.ReplicaState: The current state of the simulation\nreport::Rimu.Report: The report of the simulation\nmodified::Bool: Whether the simulation has been modified\naborted::Bool: Whether the simulation has been aborted\nsuccess::Bool: Whether the simulation has been completed successfully\nmessage::String: A message about the simulation status\nelapsed_time::Float64: The time elapsed during the simulation\n\nSee also state_vectors, ProjectorMonteCarloProblem, init, solve!.\n\n\n\n\n\n","category":"type"},{"location":"projectormontecarlo.html","page":"Projector Monte Carlo","title":"Projector Monte Carlo","text":"The DataFrame returned from DataFrame(::PMCSimulation) contains the time series data from the projector Monte Carlo simulation that is of primary interest for analysis. Depending on the reporting_strategy and other options passed as keyword arguments to ProjectorMonteCarloProblem it can have different numbers of rows and columns. The rows correspond to the reported time steps (Monte Carlo steps). There is at least one column with the name :step. Further columns are usually present with additional data reported from the simulation.","category":"page"},{"location":"projectormontecarlo.html","page":"Projector Monte Carlo","title":"Projector Monte Carlo","text":"For the default option algorithm = FCIQMC(; shift_strategy, time_step_strategy) with a single replica (n_replicas = 1) and single spectral state, the fields :shift, :norm, :len will be present as well as others depending on the style argument and the post_step_strategy.","category":"page"},{"location":"projectormontecarlo.html","page":"Projector Monte Carlo","title":"Projector Monte Carlo","text":"If multiple replicas or spectral states are requested, then the relevant field names in the DataFrame will have a suffix identifying the respective replica simulation, e.g. the shifts will be reported as shift_1, shift_2, ... ","category":"page"},{"location":"projectormontecarlo.html","page":"Projector Monte Carlo","title":"Projector Monte Carlo","text":"Many tools for analysing the time series data obtained from a ProjectorMonteCarloProblem are contained in the Module StatsTools.","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"EditURL = \"../../../scripts/G2-example.jl\"","category":"page"},{"location":"generated/G2-example.html#Example-3:-Calculating-observables","page":"Calculating observables","title":"Example 3: Calculating observables","text":"","category":"section"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"This is an example calculation of the two-body correlation function G_2.","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"A runnable script for this example is located here. Run it with julia G2-example.jl.","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"First, we load the reqired packages. Rimu for FCIQMC calculation, and DataFrames for maniplating the output.","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"using Rimu\nusing Random\nusing DataFrames","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"We use the same Hamiltonian as the first example, a Bose-Hubbard model with 6 particles in 6 sites, with strong interactions (we expect a Mott insulating state).","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"m = n = 6\ninitial_address = near_uniform(BoseFS{n,m})\nH = HubbardReal1D(initial_address; u = 6.0, t = 1.0)","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"HubbardReal1D(fs\"|1 1 1 1 1 1⟩\"; u=6.0, t=1.0)","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"Now, we define the operators for the observables we wish to calculate.","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"dvals = 0:m-1\nG2list = ((G2RealCorrelator(d) for d in dvals)...,)","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"(G2RealCorrelator(0), G2RealCorrelator(1), G2RealCorrelator(2), G2RealCorrelator(3), G2RealCorrelator(4), G2RealCorrelator(5))","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"This is a tuple of G2RealCorrelators, subtypes of AbstractHamiltonian. It calculates the density-density correlation function on a lattice","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":" hatG^(2)(d) = frac1M sum_i^M hatn_i (hatn_i+d - delta_0d)","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"with normalisation","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":" sum_d=0^M-1 langle hatG^(2)(d) rangle = fracN (N-1)M","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"Observables that are defined by expectation values are calculated using the \"replica trick\". Thereby several independent copies or \"replicas\" of the state vector are propagated simultaneously. The reason is to have two (or more) stochastically independent copies of the state vector available such that we can calculate bias-free overlaps. We enable this by defining a ReplicaStrategy. Each replica has its own state and FCIQMC is effectively performed independently on each one. For calculating observables, we use AllOverlaps for the ReplicaStrategy. At each timestep, after the FCIQMC step is performed on, this strategy calculates the overlaps of every operator with the wavefunctions from each pair of replicas.","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"To obtain an unbiased result, at least two replicas should be used. One can also use more than two to improve the statistics. This is particularly helpful when the walker number is low.","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"n_replicas = 3\nreplica_strategy = AllOverlaps(n_replicas; operator=G2list)","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"AllOverlaps{3, 6, Tuple{G2RealCorrelator{0}, G2RealCorrelator{1}, G2RealCorrelator{2}, G2RealCorrelator{3}, G2RealCorrelator{4}, G2RealCorrelator{5}}, true}((G2RealCorrelator(0), G2RealCorrelator(1), G2RealCorrelator(2), G2RealCorrelator(3), G2RealCorrelator(4), G2RealCorrelator(5)))","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"Other FCIQMC parameters and strategies can be set in the same way as before.","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"steps_equilibrate = 1_000\nsteps_measure = 5_000\ntarget_walkers = 100;\ntime_step = 0.001\n","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"Now, we run FCIQMC. Note that passing an initial vector is optional - if we only pass the style, a vector with the appropriate style is created automatically.","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"problem = ProjectorMonteCarloProblem(H;\n style=IsDynamicSemistochastic(),\n time_step,\n last_step = steps_equilibrate + steps_measure,\n target_walkers,\n replica_strategy,\n)\nresult = solve(problem)\ndf = DataFrame(result);","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"The output DataFrame has FCIQMC statistics for each replica (e.g. shift, norm),","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"println(filter(startswith(\"shift_\"), names(df)))","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"[\"shift_1\", \"shift_2\", \"shift_3\"]\n","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"as well as vector-vector overlaps (e.g. c1_dot_c2),","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"println(filter(contains(\"dot\"), names(df)))","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"[\"c1_dot_c2\", \"c1_dot_c3\", \"c2_dot_c3\"]\n","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"and operator overlaps (e.g. c1_Op1_c2) between the replicas.","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"println(filter(contains(\"Op\"), names(df)))","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"[\"c1_Op1_c2\", \"c1_Op2_c2\", \"c1_Op3_c2\", \"c1_Op4_c2\", \"c1_Op5_c2\", \"c1_Op6_c2\", \"c1_Op1_c3\", \"c1_Op2_c3\", \"c1_Op3_c3\", \"c1_Op4_c3\", \"c1_Op5_c3\", \"c1_Op6_c3\", \"c2_Op1_c3\", \"c2_Op2_c3\", \"c2_Op3_c3\", \"c2_Op4_c3\", \"c2_Op5_c3\", \"c2_Op6_c3\"]\n","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"The vector-vector and operator overlaps go into calculating the Rayleigh quotient for an observable","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":" langle hatG^(2)(d) rangle = fracsum_ab mathbfc_a^dagger cdot hatG^(2)(d) cdot mathbfc_bsum_ab mathbfc_a^dagger cdot mathbfc_b ","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"The sum over all replica pairs (a,b), especially in the denominator, helps to avoid errors from poor sampling if the number of walkers is too low.","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"We use the function rayleigh_replica_estimator to calculate the Rayleigh quotient using all replicas in df, returning a RatioBlockingResult. Using the keyword skip will ignore the initial equilibration steps.","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"Now, we can calculate the correlation function for each value of d.","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"println(\"Two-body correlator from $n_replicas replicas:\")\nfor d in dvals\n r = rayleigh_replica_estimator(df; op_name = \"Op$(d+1)\", skip=steps_equilibrate)\n println(\" G2($d) = $(r.f) ± $(r.σ_f)\")\nend","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"Two-body correlator from 3 replicas:\n G2(0) = 0.21588758691561244 ± 0.0017906745443117286\n G2(1) = 0.9162852152091748 ± 0.0011106368247895651\n G2(2) = 0.9820537989355586 ± 0.0006230997601880472\n G2(3) = 0.9874343847949214 ± 0.0009189444068620799\n G2(4) = 0.9820537989355586 ± 0.0006230997601880472\n G2(5) = 0.9162852152091748 ± 0.0011106368247895651\n","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"As expected, the onsite correlation at d=0 is low since this is a Mott insulating state with unit filling fraction, and is close to 10 for all other values of the displacement d.","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"Since we ran multiple independent replicas, we also have multiple estimates of the shift energy.","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"println(\"Shift energy from $n_replicas replicas:\")\nfor i in 1:n_replicas\n se = shift_estimator(df; shift=\"shift_$i\", skip=steps_equilibrate)\n println(\" Replica $i: $(se.mean) ± $(se.err)\")\nend\n","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"Shift energy from 3 replicas:\n Replica 1: -4.016337436606625 ± 0.11880763464913646\n Replica 2: -4.044163449484755 ± 0.13015222463254772\n Replica 3: -4.06405078692469 ± 0.1267785087026866\n","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"This page was generated using Literate.jl.","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"EditURL = \"../../../scripts/BHM-example.jl\"","category":"page"},{"location":"generated/BHM-example.html#Example-1:-1D-Bose-Hubbard-Model","page":"1D Bose-Hubbard Model","title":"Example 1: 1D Bose-Hubbard Model","text":"","category":"section"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"This is an example calculation finding the ground state of a 1D Bose-Hubbard chain with 6 particles in 6 lattice sites.","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"A runnable script for this example is located here. Run it with julia BHM-example.jl.","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"First, we load Rimu and Plots.","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"using Rimu\nusing Plots","category":"page"},{"location":"generated/BHM-example.html#Setting-up-the-model","page":"1D Bose-Hubbard Model","title":"Setting up the model","text":"","category":"section"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"We start by defining the physical problem. First, we generate an initial configuration which will be used as a starting point of our computation. In this example, we use a bosonic Fock state with 6 particles evenly distributed in 6 lattice sites.","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"initial_address = near_uniform(BoseFS{6,6})","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"BoseFS{6,6}(1, 1, 1, 1, 1, 1)","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"The Hamiltonian is constructed by initializing a struct with an initial address and model parameters. Here, we use the Bose Hubbard model in one-dimensional real space.","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"H = HubbardReal1D(initial_address; u = 6.0, t = 1.0)","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"HubbardReal1D(fs\"|1 1 1 1 1 1⟩\"; u=6.0, t=1.0)","category":"page"},{"location":"generated/BHM-example.html#Parameters-of-the-calculation","page":"1D Bose-Hubbard Model","title":"Parameters of the calculation","text":"","category":"section"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"Now, let's setup the Monte Carlo calculation. We need to decide the number of walkers to use in this Monte Carlo run, which is equivalent to the average one-norm of the coefficient vector. Higher values will result in better statistics, but require more memory and computing power.","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"target_walkers = 1_000;","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"FCIQMC takes a certain number of steps to equllibrate, after which the observables will fluctuate around a mean value. In this example, we will devote 1000 steps to equilibration and take an additional 2000 steps for measurement.","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"steps_equilibrate = 1_000;\nsteps_measure = 2_000;\nlast_step = steps_equilibrate + steps_measure","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"3000","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"Next, we pick a time step size. FCIQMC does not have a time step error, but the time step needs to be small enough, or the computation might diverge. If the time step is too small, however, the computation might take a long time to equilibrate. The appropriate time step size is problem-dependent and is best determined through experimentation.","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"time_step = 0.001;","category":"page"},{"location":"generated/BHM-example.html#Defining-an-observable","page":"1D Bose-Hubbard Model","title":"Defining an observable","text":"","category":"section"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"Now, let's set up an observable to measure. Here we will measure the projected energy. In additon to the shift, the projected energy is a second estimator for the energy. It usually produces better statistics than the shift.","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"We first need to define a projector. Here, we use the function default_starting_vector to generate a vector with only a single occupied configuration. We will use the same vector as the starting vector for the FCIQMC calculation.","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"initial_vector = default_starting_vector(initial_address; style=IsDynamicSemistochastic())","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"DVec{BoseFS{6, 6, BitString{11, 1, UInt16}},Float64} with 1 entry, style = IsDynamicSemistochastic{Float64,ThresholdCompression,DynamicSemistochastic}()\n fs\"|1 1 1 1 1 1⟩\" => 10.0","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"The choice of the style argument already determines the FCIQMC algorithm to use. IsDynamicSemistochastic is usually the best choice as it reduces noise and improves the sign problem.","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"Observables that can be calculated by projection of the fluctuating quantum state onto a constant vector are passed into the ProjectorMonteCarloProblem with the post_step_strategy keyword argument.","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"post_step_strategy = ProjectedEnergy(H, initial_vector)","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"ProjectedEnergy{HubbardReal1D{Float64, BoseFS{6, 6, BitString{11, 1, UInt16}}, 6.0, 1.0}, Rimu.DictVectors.FrozenDVec{BoseFS{6, 6, BitString{11, 1, UInt16}}, Float64}, Rimu.DictVectors.FrozenDVec{BoseFS{6, 6, BitString{11, 1, UInt16}}, Float64}}(:vproj, :hproj, HubbardReal1D(fs\"|1 1 1 1 1 1⟩\"; u=6.0, t=1.0), Rimu.FrozenDVec([fs\"|1 1 1 1 1 1⟩\"=>10.0]), Rimu.FrozenDVec([fs\"|1 1 1 1 2 0⟩\"=>-14.1421, fs\"|0 2 1 1 1 1⟩\"=>-14.1421, fs\"|1 1 1 1 0 2⟩\"=>-14.1421, fs\"|1 2 0 1 1 1⟩\"=>-14.1421, fs\"|2 0 1 1 1 1⟩\"=>-14.1421, fs\"|1 1 1 2 0 1⟩\"=>-14.1421, fs\"|1 1 2 0 1 1⟩\"=>-14.1421, fs\"|1 1 0 2 1 1⟩\"=>-14.1421, fs\"|1 1 1 0 2 1⟩\"=>-14.1421, fs\"|1 0 2 1 1 1⟩\"=>-14.1421, fs\"|2 1 1 1 1 0⟩\"=>-14.1421, fs\"|0 1 1 1 1 2⟩\"=>-14.1421]))","category":"page"},{"location":"generated/BHM-example.html#Running-the-calculation","page":"1D Bose-Hubbard Model","title":"Running the calculation","text":"","category":"section"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"This is a two-step process: First we define a ProjectorMonteCarloProblem with all the parameters needed for the simulation","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"problem = ProjectorMonteCarloProblem(\n H;\n start_at = initial_vector,\n last_step,\n time_step,\n target_walkers,\n post_step_strategy\n);","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"To run the simulation we simply call solve on the problem","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"simulation = solve(problem);","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"The simulation object contains the results of the simulation as well as state vectors and strategies. We can extract the time series data for further analysis:","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"df = DataFrame(simulation);","category":"page"},{"location":"generated/BHM-example.html#Analysing-the-results","page":"1D Bose-Hubbard Model","title":"Analysing the results","text":"","category":"section"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"We can plot the norm of the coefficient vector as a function of the number of steps.","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"hline(\n [target_walkers];\n label=\"target_walkers\", xlabel=\"step\", ylabel=\"norm\",\n color=2, linestyle=:dash, margin = 1Plots.cm\n)\nplot!(df.step, df.norm, label=\"norm\", color=1)","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"\n\n\n \n \n \n\n\n\n \n \n \n\n\n\n \n \n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"After an initial equilibriation period, the norm fluctuates around the target number of walkers.","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"Now, let's look at using the shift to estimate the ground state energy of H. The mean of the shift is a useful estimator of the energy. Calculating the error bars is a bit more involved as autocorrelations have to be removed from the time series. This can be done with the function shift_estimator, which performs a blocking analysis on the shift column of the dataframe.","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"se = shift_estimator(df; skip=steps_equilibrate)","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"BlockingResult{Float64}\n mean = -4.029 ± 0.026\n with uncertainty of ± 0.002331601728257115\n from 62 blocks after 5 transformations (k = 6).\n","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"Here, se contains the calculated mean and standard errors of the shift, as well as some additional information related to the blocking analysis.","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"Computing the error of the projected energy is a bit more complicated, as it's a ratio of fluctuating variables contained in the hproj and vproj columns in the dataframe. Thankfully, the complications are handled by the function projected_energy.","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"pe = projected_energy(df; skip=steps_equilibrate)","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"RatioBlockingResult{Float64,MonteCarloMeasurements.Particles{Float64, 2000}}\n ratio = -4.01374 ± (0.00182987, 0.00200136) (MC)\n 95% confidence interval: [-4.01757, -4.01008] (MC)\n linear error propagation: -4.01384 ± 0.00189423\n |δ_y| = |0.00172589| (≤ 0.1 for normal approx)\n Blocking successful with 31 blocks after 6 transformations (k = 7).\n","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"The result is a ratio distribution. We extract its median and the edges of the 95% confidence interval.","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"v = val_and_errs(pe; p=0.95)","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"(val = -4.0137380929613204, val_l = 0.003831426778932112, val_u = 0.0036566501605630464)","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"Let's visualise these estimators together with the time series of the shift.","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"plot(df.step, df.shift, ylabel=\"energy\", xlabel=\"step\", label=\"shift\", margin = 1Plots.cm)\n\nplot!(x->se.mean, df.step[steps_equilibrate+1:end], ribbon=se.err, label=\"shift mean\")\nplot!(\n x -> v.val, df.step[steps_equilibrate+1:end], ribbon=(v.val_l,v.val_u),\n label=\"projected energy\",\n)\nlens!([steps_equilibrate, last_step], [-5.1, -2.9]; inset=(1, bbox(0.2, 0.25, 0.6, 0.4)))","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"\n\n\n \n \n \n\n\n\n \n \n \n\n\n\n \n \n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n \n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"In this case the projected energy and the shift are close to each other and the error bars are hard to see.","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"The problem was just a toy example, as the dimension of the Hamiltonian is rather small:","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"dimension(H)","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"462","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"In this case, it's easy (and more efficient) to calculate the exact ground state energy using standard linear algebra. Read more about Rimu's capabilities for exact diagonalization in the example \"Exact diagonalization\".","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"edp = ExactDiagonalizationProblem(H)\nexact_energy = solve(edp).values[1]","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"-4.021502406906473","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"We finish by comparing our FCIQMC results with the exact computation.","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"println(\n \"\"\"\n Energy from $steps_measure steps with $target_walkers walkers:\n Shift: $(se.mean) ± $(se.err)\n Projected Energy: $(v.val) ± ($(v.val_l), $(v.val_u))\n Exact Energy: $exact_energy\n \"\"\"\n)\n\n","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"Energy from 2000 steps with 1000 walkers:\nShift: -4.029305674616693 ± 0.025753382836897584\nProjected Energy: -4.0137380929613204 ± (0.003831426778932112, 0.0036566501605630464)\nExact Energy: -4.021502406906473\n\n","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"This page was generated using Literate.jl.","category":"page"},{"location":"statstools.html#Module-StatsTools","page":"StatsTools","title":"Module StatsTools","text":"","category":"section"},{"location":"statstools.html","page":"StatsTools","title":"StatsTools","text":"The module StatsTools contains helper function for analysis and post processing of Monte Carlo data.","category":"page"},{"location":"statstools.html#Blocking-analysis","page":"StatsTools","title":"Blocking analysis","text":"","category":"section"},{"location":"statstools.html","page":"StatsTools","title":"StatsTools","text":"After equilibration, FCIQMC produces information about observables through correlated time series. In order to estimate the statistical errors the time series need to be decorrelated. The main workhorse for achieving this is the blocking_analysis, which is based on the paper by Flyvberg and Peterson JCP (1989), and automated with the M test of Jonsson PRE (2018).","category":"page"},{"location":"statstools.html","page":"StatsTools","title":"StatsTools","text":"Analysing the stochastic errors of observables obtained from the ratio of sample means is done with ratio_of_means, where error propagation of correlated uncertainties is done with the help of the package MonteCarloMeasurements.","category":"page"},{"location":"statstools.html","page":"StatsTools","title":"StatsTools","text":"Many convenience functions are implemented for directly analysing data obtained from solve as a DataFrame. See, e.g., shift_estimator and projected_energy. Asymptotically unbiased estimators are implemented as mixed_estimator, growth_estimator and rayleigh_replica_estimator.","category":"page"},{"location":"statstools.html#Exported","page":"StatsTools","title":"Exported","text":"","category":"section"},{"location":"statstools.html","page":"StatsTools","title":"StatsTools","text":"Modules = [StatsTools]\nPages = [\"StatsTools.jl\", \"blocking.jl\", \"ratio_of_means.jl\", \"convenience.jl\",\n \"variances.jl\", \"growth_witness.jl\", \"reweighting.jl\", \"fidelity.jl\", \"variational_energy_estimator.jl\"\n]\nPrivate = false","category":"page"},{"location":"statstools.html#Rimu.StatsTools","page":"StatsTools","title":"Rimu.StatsTools","text":"Tools for the statistical analysis of Monte Carlo data.\n\nExports:\n\nblocking_analysis\nblocking_analysis_data\nratio_of_means\ngrowth_witness\nsmoothen\nshift_estimator\nprojected_energy\nvariational_energy_estimator\ngrowth_estimator\ngrowth_estimator_analysis\nmixed_estimator\nmixed_estimator_analysis\nrayleigh_replica_estimator\nrayleigh_replica_estimator_analysis\nval_and_errs\nval\nmean_and_se\n\n\n\n\n\n","category":"module"},{"location":"statstools.html#Rimu.StatsTools.blocking_analysis-Tuple{AbstractVector}","page":"StatsTools","title":"Rimu.StatsTools.blocking_analysis","text":"blocking_analysis(v::AbstractVector; α = 0.01, corrected = true, skip=0, warn=true)\n-> BlockingResult(mean, err, err_err, p_cov, k, blocks)\n\nCompute the sample mean mean and estimate the standard deviation of the mean (standard error) err of a correlated time series. It uses the blocking algorithm from Flyvberg and Peterson JCP (1989) and the M test of Jonsson PRE (2018) at significance level 1-α.\n\nUse skip to skip the first skip elements in v. corrected controls whether bias correction for variances is used. If decorrelating the time series fails according to the M test, NaN is returned as the standard error and -1 for k. The keyword argument warn controls whether a warning message is logged.\n\nThe summary result is returned as a BlockingResult. k - 1 is the number of blocking transformations required to pass the hypothesis test for an uncorrelated time series and err_err the estimated standard error or err.\n\nThe detailed results from each reblocking step can be obtained with blocking_analysis_data.\n\nSee BlockingResult, shift_estimator, ratio_of_means, blocking_analysis_data.\n\n\n\n\n\n","category":"method"},{"location":"statstools.html#Rimu.StatsTools.blocking_analysis_data-Tuple{AbstractVector}","page":"StatsTools","title":"Rimu.StatsTools.blocking_analysis_data","text":"blocking_analysis_data(v::AbstractVector; kwargs...) ->\n(; br::BlockingResult, df::DataFrame)\n\nPerform a blocking_analysis and return the summary result br as well as a DataFrame df with information about the standard error in each blocking step.\n\nFor a description of the keyword arguments see blocking_analysis.\n\nExample\n\njulia> data = smoothen(rand(10_000), 2^6); # generate correlated data\n\njulia> br, df = blocking_analysis_data(data)\n(br = BlockingResult{Float64}\n mean = 0.5088 ± 0.0029\n with uncertainty of ± 0.00023454488294744232\n from 78 blocks after 7 transformations (k = 8).\n, df = 13×6 DataFrame\n Row │ blocks mean std_err std_err_err p_cov mj\n │ Int64 Float64 Float64 Float64 Float64 Float64\n─────┼──────────────────────────────────────────────────────────────────────\n 1 │ 10000 0.508806 0.000375044 2.6521e-6 1.40658e-7 9715.08\n 2 │ 5000 0.508806 0.000528547 5.28599e-6 2.79361e-7 4778.14\n 3 │ 2500 0.508806 0.000743386 1.05152e-5 5.52622e-7 2298.64\n 4 │ 1250 0.508806 0.00104064 2.08212e-5 1.08293e-6 1056.24\n 5 │ 625 0.508806 0.00144177 4.08121e-5 2.07871e-6 427.949\n 6 │ 312 0.508736 0.00194209 7.78707e-5 3.77171e-6 128.711\n 7 │ 156 0.508736 0.00247921 0.00014081 6.14647e-6 17.3075\n 8 │ 78 0.508736 0.00291063 0.000234545 8.47174e-6 0.731386\n 9 │ 39 0.508736 0.00284613 0.000326474 8.10046e-6 0.901054\n 10 │ 19 0.508241 0.0026998 0.000449967 7.28892e-6 2.85915\n 11 │ 9 0.507939 0.00359907 0.000899766 1.29533e-5 1.08644\n 12 │ 4 0.509327 0.00440559 0.00179857 1.94092e-5 0.0370381\n 13 │ 2 0.509327 0.00432708 0.00305971 1.87237e-5 0.125)\n\njulia> using StatsPlots; unicodeplots();\n\njulia> plot([br.k,br.k],[0.0,maximum(df.std_err.+df.std_err_err)], label=\"m test\");\n\njulia> @df df plot!(\n 1:length(:std_err), :std_err;\n err=:std_err_err, xlabel=\"k\", label=\"std err\",\n title=\"std err vs blocking steps\"\n )\n ⠀⠀⠀⠀⠀⠀⠀⠀⠀std err vs blocking steps⠀⠀⠀⠀⠀⠀⠀⠀\n ┌────────────────────────────────────────┐\n 0.00423501 │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⠀⠀⠀⠀│ m test\n │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠀⠀⢸⠀⠀⠀⠀│ std err\n │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⠀⠀⢸⠀⠀⠀⠀│\n │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⠀⠀⢸⠀⠀⠀⠀│\n │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⡠⢺⠒⠒⢺⠀⠀⠀⠀│\n │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⡀⠀⠀⡆⣀⠤⡗⠉⠀⢸⠀⠀⢸⡆⠀⠀⠀│\n │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⡧⠤⠔⡗⠊⠉⡏⠀⠀⡇⠀⠀⢸⠀⠀⢸⢣⠀⠀⠀│\n │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠔⠁⡇⠀⠀⠁⠀⠀⠁⠀⠀⠁⠀⠀⠀⠀⠀⢸⠸⡀⠀⠀│\n │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠴⠁⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠸⠀⡇⠀⠀│\n │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠔⠁⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⠀⠀│\n │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠔⠊⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⣦⠀│\n │⠀⠀⠀⠀⠀⠀⠀⠀⡠⠔⠒⠁⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢹⠀│\n │⠀⠀⠀⢀⣀⠤⠒⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⠀│\n │⠀⠒⠉⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⠀│\n -0.00012335 │⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠧⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤│\n └────────────────────────────────────────┘\n ⠀0.64⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀k⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀13.36⠀\n\nA vertical line at k==8 indicates the blocking step identified by hypothesis testing to decorrelate the time series data. The decorrelation length can thus be estimated at 2^k-1 = 2^7 = 128. Note that the data was correlated with a sliding window of 2^6 steps.\n\nSee blocking_analysis, BlockingResult.\n\n\n\n\n\n","category":"method"},{"location":"statstools.html#Rimu.StatsTools.mean_and_se-Tuple{Rimu.StatsTools.BlockingResult}","page":"StatsTools","title":"Rimu.StatsTools.mean_and_se","text":"mean_and_se(v::AbstractVector; α = 0.01, corrected::Bool=true, skip=0) -> mean, err\nmean_and_se(r::BlockingResult) -> mean, err\n\nReturn the mean and standard error (as a tuple) of a time series obtained from blocking_analysis. See also BlockingResult.\n\n\n\n\n\n","category":"method"},{"location":"statstools.html#Statistics.cov-Tuple{Rimu.StatsTools.BlockingResult{<:Complex}}","page":"StatsTools","title":"Statistics.cov","text":"cov(r::BlockingResult{<:Complex})\n\nReturn the covariance matrix of the multivariate normal distribution approximating the uncertainty of the blocking result r of a complex time series. See (https://en.wikipedia.org/wiki/Complexnormaldistribution).\n\n\n\n\n\n","category":"method"},{"location":"statstools.html#Rimu.StatsTools.ratio_of_means-Tuple{Any, Any}","page":"StatsTools","title":"Rimu.StatsTools.ratio_of_means","text":"ratio_of_means(num, denom; α=0.01, corrected=true, mc_samples=nothing, skip=0, warn=true)\n-> r::RatioBlockingResult\n\nEstimate the ratio of mean(num)/mean(denom) assuming that num and denom are possibly correlated time series, skipping the first skip elements. A blocking analysis with m-test is used to uncorrelate the time series, see blocking_analysis. The remaining standard error and correlation of the means is propagated using MonteCarloMeasurements. The results are reported as a RatioBlockingResult.\n\nRobust estimates for the ratio are obtained from pmedian(r) and confidence intervals from pquantile(), e.g. pquantile(r, [0.025, 0.975]) for the 95% confidence interval.\n\nEstimates from linear uncertainty propagation are returned as r.f and r.σ_f using x_by_y_linear. The standard error estimate r.σ_f should only be trusted when the coefficient of variation std(denom)/mean(denom) is small: abs(r.δ_y) < 0.1. Under this condition can the ratio be approximated as a normal distribution. See wikipedia and Díaz-Francés, Rubio (2013)\n\nThe keyword mc_samples controls the number of samples used for error propagation by MonteCarloMeasurements. Use nothing for the default and Val(1000) to set the number to 1000 samples in a type-consistent way.\n\nThe keyword warn controls whether warning messages are logged when blocking fails or noisy denominators are encountered.\n\nNote: to compute statistics on the RatioBlockingResult, use functions pmedian, pquantile, pmiddle, piterate, pextrema, pminimum, pmaximum, pmean, and pcov.\n\n\n\n\n\n","category":"method"},{"location":"statstools.html#Rimu.StatsTools.errs-Tuple","page":"StatsTools","title":"Rimu.StatsTools.errs","text":"errs(x; n=1, p=nothing, name=:err) -> (; err_l, err_u)\n\nReturn the lower and upper error bar for the uncertain value x.\n\nSee val_and_errs.\n\n\n\n\n\n","category":"method"},{"location":"statstools.html#Rimu.StatsTools.to_measurement-Tuple{MonteCarloMeasurements.Particles}","page":"StatsTools","title":"Rimu.StatsTools.to_measurement","text":"to_measurement(p::MonteCarloMeasurements.Particles) -> ::Measurements.measurement\n\nConvert an uncertain number from MonteCarloMeasurements to Measurements format using the median as the central point. The new ± boundaries will include the 68% quantile around the median.\n\n\n\n\n\n","category":"method"},{"location":"statstools.html#Rimu.StatsTools.val-Tuple{Any}","page":"StatsTools","title":"Rimu.StatsTools.val","text":"val(x)\n\nReturn the best estimate value for an uncertain x. Defaults to the median for uncertain x represented by a (sampled) distribution. Supports MonteCarloMeasurements and Measurements.\n\nSee errs, BlockingResult, RatioBlockingResult.\n\n\n\n\n\n","category":"method"},{"location":"statstools.html#Rimu.StatsTools.val_and_errs-Tuple{Any}","page":"StatsTools","title":"Rimu.StatsTools.val_and_errs","text":"val_and_errs(x; n=1, p=nothing, name=:val) -> (;val, val_l, val_u)\n\nReturn the median and the lower and upper error bar for the uncertain value x as a NamedTuple. This is useful for plotting scripts. The interval [val - val_l, val + val_u] represents the confidence interval at level n*σ, or at probability p. Setting p overrides n. Supports MonteCarloMeasurements and Measurements. The names in the NamedTuple can be changed with name.\n\nExample:\n\njulia> results = [blocking_analysis(i:0.1:2i+20) for i in 1:3]; # mock results\n\njulia> v = val_and_errs.(results, name=\"res\"); # Vector of NamedTuple's with standard errors\n\njulia> DataFrame(v)\n3×3 DataFrame\n Row │ res res_l res_u\n │ Float64 Float64 Float64\n─────┼───────────────────────────\n 1 │ 11.5 1.7282 1.7282\n 2 │ 13.0 1.7282 1.7282\n 3 │ 14.5 1.78885 1.78885\n\nSee NamedTuple, val, errs, BlockingResult, RatioBlockingResult.\n\n\n\n\n\n","category":"method"},{"location":"statstools.html#Rimu.StatsTools.growth_witness","page":"StatsTools","title":"Rimu.StatsTools.growth_witness","text":"growth_witness(df::DataFrame, [b];\n shift=:shift,\n norm=:norm,\n time_step=determine_constant_time_step(df),\n skip=0\n)\ngrowth_witness(sim::PMCSimulation, [b]; kwargs...)\n\nCalculate the growth witness directly from the result (DataFrame or PMCSimulation) of solveing a ProjectorMonteCarloProblem. The keyword arguments shift and norm can be used to change the names of the relevant columns.\n\n\n\n\n\n","category":"function"},{"location":"statstools.html#Rimu.StatsTools.growth_witness-Tuple{AbstractArray, AbstractArray, Any}","page":"StatsTools","title":"Rimu.StatsTools.growth_witness","text":"growth_witness(shift::AbstractArray, norm::AbstractArray, dt, [b]; skip=0)\n\nCompute the growth witness\n\nG^(n) = S^(n) - fracvertmathbfc^(n+1)vert -\n vertmathbfc^(n)vertvertmathbfc^(n)vert dtau\n\nwhere S is the shift and vertmathbfc^(n)vert == norm[n, 1]. Setting b ≥ 1 a sliding average over b time steps is computed using smoothen(). The first skip time steps are skipped. mean(growth_witness) is approximately the same as growth_estimator with h=0.\n\nSee also growth_estimator.\n\n\n\n\n\n","category":"method"},{"location":"statstools.html#Rimu.StatsTools.smoothen-Tuple{AbstractVector, Integer}","page":"StatsTools","title":"Rimu.StatsTools.smoothen","text":"smoothen(noisy::AbstractVector, b)\n\nSmoothen the array noisy by averaging over a sliding window of length b and wrapping noisy periodically. The mean(noisy) is preserved.\n\n\n\n\n\n","category":"method"},{"location":"statstools.html#Rimu.StatsTools.growth_estimator-NTuple{4, Any}","page":"StatsTools","title":"Rimu.StatsTools.growth_estimator","text":"growth_estimator(\n shift, wn, h, time_step;\n skip = 0,\n E_r = mean(shift[skip+1:end]),\n weights = w_exp,\n change_type = identity,\n kwargs...\n)\ngrowth_estimator(\n df::DataFrame, h;\n shift_name=:shift,\n norm_name=:norm,\n time_step=determine_constant_time_step(df),\n kwargs...\n)\ngrowth_estimator(sim::PMCSimulation; kwargs...)\n-> r::RatioBlockingResult\n\nCompute the growth estimator with reference energy E_r by the reweighting technique described in Umrigar et al. (1993), see Eq. (20). shift and wn are equal length vectors containing the shift and walker number time series, respectively. Reweighting is done over h time steps and length(shift) - skip time steps are used for the blocking analysis done with ratio_of_means. weights is a function that calulates the weights. See w_exp and w_lin.\n\nE_gr = E_r - frac1dτln\n fracsum_n w_h+1^(n+1) N_mathrmw^(n+1)\n sum_m w_h^(m) N_mathrmw^(m) \n\nwhere dτ is the time_step\n\nWhen h is greater than the autocorrelation time scale of the shift, then E_gr (returned as r.ratio) is an unbiased but approximate estimator for the ground state energy E_0 with an error mathcalO(dτ^2) and potentially increased confidence intervals compared to the (biased) shift estimator. Error propagation is done with MonteCarloMeasurements. Propagation through the logarithm can be modified by setting change_type to to_measurement in order to avoid NaN results from negative outliers.\n\nIf success==true the blocking analysis was successful in k-1 steps, using blocks uncorrelated data points.\n\nThe second method calculates the growth estimator directly from a PMCSimulation or DataFrame returned by solve. The keyword arguments shift_name and norm_name can be used to change the names of the relevant columns.\n\nSee also mixed_estimator and RatioBlockingResult.\n\n\n\n\n\n","category":"method"},{"location":"statstools.html#Rimu.StatsTools.growth_estimator_analysis-Tuple{Any}","page":"StatsTools","title":"Rimu.StatsTools.growth_estimator_analysis","text":"growth_estimator_analysis(df::DataFrame; kwargs...)\ngrowth_estimator_analysis(sim::PMCSimulation; kwargs...)\n-> (; df_ge, correlation_estimate, se, se_l, se_u)\n\nCompute the growth_estimator on a DataFrame df or PMCSimulation sim. repeatedly over a range of reweighting depths.\n\nReturns a NamedTuple with the fields\n\ndf_ge: DataFrame with reweighting depth and growth_estiamator data. See example below.\ncorrelation_estimate: estimated correlation time from blocking analysis\nse, se_l, se_u: shift_estimator and error\n\nKeyword arguments\n\nh_range: The default is about h_values values from 0 to twice the estimated correlation time\nh_values = 100: minimum number of reweighting depths\nskip = 0: initial time steps to exclude from averaging\nthreading = Threads.nthreads() > 1: if false a progress meter is displayed\nshift_name = :shift name of column in df with shift data\nnorm_name = :norm name of column in df with walkernumber data\ntime_step = determine_constant_time_step(df) the time step\nwarn = true whether to log warning messages when blocking fails or denominators are small\n\nExample\n\nsim = solve(...)\ndf_ge, correlation_estimate, se, se_l, se_u = growth_estimator_analysis(sim; skip=5_000)\n\nusing StatsPlots\n@df df_ge plot(_ -> se, :h, ribbon = (se_l, se_u), label = \"⟨S⟩\") # constant line and ribbon for shift estimator\n@df df_ge plot!(:h, :val, ribbon = (:val_l, :val_u), label=\"E_gr\") # growth estimator as a function of reweighting depth\nxlabel!(\"h\")\n\nSee also: growth_estimator, mixed_estimator_analysis.\n\n\n\n\n\n","category":"method"},{"location":"statstools.html#Rimu.StatsTools.mixed_estimator-Tuple{AbstractVector, AbstractVector, AbstractVector, Any, Any}","page":"StatsTools","title":"Rimu.StatsTools.mixed_estimator","text":"mixed_estimator(\n hproj, vproj, shift, h, time_step;\n skip = 0,\n E_r = mean(shift[skip+1:end]),\n weights = w_exp,\n kwargs...\n)\nmixed_estimator(\n df::DataFrame, h;\n hproj_name=:hproj,\n vproj_name=:vproj,\n shift_name=:shift,\n time_step=determine_constant_time_step(df),\n kwargs...\n)\nmixed_estimator(sim::PMCSimulation, h; kwargs...)\n-> r::RatioBlockingResult\n\nCompute the mixed estimator by the reweighting technique described in Umrigar et al. (1993), Eq. (19)\n\nE_mathrmmix = fracsum_n w_h^(n) (Hmathbfv)mathbfc^(n)\n sum_m w_h^(m) mathbfvmathbfc^(m) \n\nwhere the time series hproj == (Hmathbfv)mathbfc^(n) and vproj == mathbfvmathbfc^(m) have the same length as shift (See ProjectedEnergy on how to set these up). Reweighting is done over h time steps and length(shift) - skip time steps are used for the blocking analysis done with ratio_of_means. weights is a function that calulates the weights. See w_exp and w_lin. Additional keyword arguments are passed on to ratio_of_means.\n\nWhen h is greater than the autocorrelation time scale of the shift, then r.ratio is an unbiased but approximate estimator for the ground state energy E_0 with an error mathcalO(dτ^2), where dτ is the time_step, and potentially increased confidence intervals compared to the unweighted ratio. Error propagation is done with MonteCarloMeasurements. Results are returned as RatioBlockingResult.\n\nThe second method calculates the mixed energy estimator directly from a DataFrame or PMCSimulation returned by solve. The keyword arguments hproj_name, vproj_name, and shift_name can be used to change the names of the relevant columns.\n\nSee also growth_estimator.\n\n\n\n\n\n","category":"method"},{"location":"statstools.html#Rimu.StatsTools.mixed_estimator_analysis-Tuple{DataFrame}","page":"StatsTools","title":"Rimu.StatsTools.mixed_estimator_analysis","text":"mixed_estimator_analysis(df::DataFrame; kwargs...)\nmixed_estimator_analysis(sim::PMCSimulation; kwargs...)\n-> (; df_me, correlation_estimate, se, se_l, se_u)\n\nCompute the mixed_estimator on a DataFrame df or PMCSimulation sim returned from solve repeatedly over a range of reweighting depths.\n\nReturns a NamedTuple with the fields\n\ndf_me: DataFrame with reweighting depth and mixed_estiamator data. See example below.\ncorrelation_estimate: estimated correlation time from blocking analysis\nse, se_l, se_u: shift_estimator and error\n\nKeyword arguments\n\nh_range: The default is about h_values values from 0 to twice the estimated correlation time\nh_values = 100: minimum number of reweighting depths\nskip = 0: initial time steps to exclude from averaging\nthreading = Threads.nthreads() > 1: if false a progress meter is displayed\nshift_name = :shift name of column in df with shift data\nhproj_name = :hproj name of column in df with operator overlap data\nvproj_name = :vproj name of column in df with projector overlap data\ntime_step = determine_constant_time_step(df) the time step\nwarn = true whether to log warning messages when blocking fails or denominators are small\n\nExample\n\nsim = solve(...)\ndf_me, correlation_estimate, se, se_l, se_u = mixed_estimator_analysis(sim; skip=5_000)\n\nusing StatsPlots\n@df df_me plot(_ -> se, :h, ribbon = (se_l, se_u), label = \"⟨S⟩\") # constant line and ribbon for shift estimator\n@df df_me plot!(:h, :val, ribbon = (:val_l, :val_u), label=\"E_mix\") # mixed estimator as a function of reweighting depth\nxlabel!(\"h\")\n\nSee also: mixed_estimator, growth_estimator_analysis.\n\n\n\n\n\n","category":"method"},{"location":"statstools.html#Rimu.StatsTools.projected_energy-Tuple{Any}","page":"StatsTools","title":"Rimu.StatsTools.projected_energy","text":"projected_energy(df::DataFrame; skip=0, hproj=:hproj, vproj=:vproj, kwargs...)\nprojected_energy(sim::PMCSimulation; kwargs...)\n-> r::RatioBlockingResult\n\nCompute the projected energy estimator\n\nE_mathrmp = fracsum_n mathbfvHmathbfc^(n)\n sum_m mathbfvmathbfc^(m) \n\nwhere the time series df.hproj == mathbfvHmathbfc^(n) and df.vproj == mathbfvmathbfc^(m) are taken from df, skipping the first skip entries (use post_step_strategy =ProjectedEnergy(...) to set these up in ProjectorMonteCarloProblem). projected_energy is equivalent to mixed_estimator with h=0.\n\nThe keyword arguments hproj and vproj can be used to change the names of the relevant columns. Other kwargs are passed on to ratio_of_means. Returns a RatioBlockingResult.\n\nSee NamedTuple, val_and_errs, val, errs for processing results.\n\n\n\n\n\n","category":"method"},{"location":"statstools.html#Rimu.StatsTools.rayleigh_replica_estimator-Tuple{Vector, Vector, Vector, Any, Any}","page":"StatsTools","title":"Rimu.StatsTools.rayleigh_replica_estimator","text":"rayleigh_replica_estimator(\n op_ol, vec_ol, shift, h, time_step;\n skip = 0,\n E_r = mean(shift[skip+1:end]),\n weights = w_exp,\n kwargs...\n)\nrayleigh_replica_estimator(\n df::DataFrame;\n shift_name=\"shift\",\n op_name=\"Op1\",\n vec_name=\"dot\",\n h=0,\n skip=0,\n Anorm=1,\n kwargs...\n)\nrayleigh_replica_estimator(sim::PMCSimulation; kwargs...)\n-> r::RatioBlockingResult\n\nCompute the estimator of a Rayleigh quotient of operator hatA with reweighting,\n\nA_mathrmest(h) = fracsum_ab sum_n w_ha^(n) w_hb^(n)\n mathbfc_a^(n) cdot hatA cdot mathbfc_b^(n)\n sum_ab sum_n w_ha^(n) w_hb^(n) mathbfc_a^(n) cdot mathbfc_b^(n)\n\nusing data from multiple replicas.\n\nArgument op_ol holds data for the operator overlap mathbfc_a^(n) hatA mathbfc_b^(n) and vec_ol holds data for the vector overlap mathbfc_a^(n) mathbfc_b^(n). They are of type Vector{Vector}, with each element Vector holding the data for a pair of replicas. Argument shift is of type Vector{Vector}, with each element Vector holding the shift data for each individual replica.\n\nThe second method computes the Rayleigh quotient directly from a DataFrame or PMCSimulation returned by solve. The keyword arguments shift_name, op_name and vec_name can be used to change the names of the relevant columns, see AllOverlaps for default formatting. The operator overlap data can be scaled by a prefactor Anorm. A specific reweighting depth can be set with keyword argument h. The default is h = 0 which calculates the Rayleigh quotient without reweighting.\n\nThe reweighting is an extension of the mixed estimator using the reweighting technique described in Umrigar et al. (1993). Reweighting is done over h time steps and length(shift) - skip time steps are used for the blocking analysis done with ratio_of_means. weights is a function that calulates the weights. See w_exp and w_lin. Additional keyword arguments are passed on to ratio_of_means.\n\nError propagation is done with MonteCarloMeasurements. Results are returned as RatioBlockingResult.\n\nSee also mixed_estimator, growth_estimator.\n\n\n\n\n\n","category":"method"},{"location":"statstools.html#Rimu.StatsTools.rayleigh_replica_estimator_analysis-Tuple{Any}","page":"StatsTools","title":"Rimu.StatsTools.rayleigh_replica_estimator_analysis","text":"rayleigh_replica_estimator_analysis(df::DataFrame; kwargs...)\nrayleigh_replica_estimator_analysis(sim::PMCSimulation; kwargs...)\n-> (; df_rre, df_se)\n\nCompute the rayleigh_replica_estimator on a DataFrame df or PMCSimulation sim returned from solve repeatedly over a range of reweighting depths.\n\nReturns a NamedTuple with the fields\n\ndf_rre: DataFrame with reweighting depth and rayleigh_replica_estimator data. See example below.\ndf_se: DataFrame with shift_estimator output, one row per replica\n\nKeyword arguments\n\nh_range: The default is about h_values values from 0 to twice the estimated correlation time\nh_values = 100: minimum number of reweighting depths\nskip = 0: initial time steps to exclude from averaging\nthreading = Threads.nthreads() > 1: if false a progress meter is displayed\nshift_name = \"shift\": shift data corresponding to column in df with names _1, ...\nop_name = \"Op1\": name of operator overlap corresponding to column in df with names c1__c2, ...\nvec_name = \"dot\": name of vector-vector overlap corresponding to column in df with names c1__c2, ...\nAnorm = 1: a scalar prefactor to scale the operator overlap data\nwarn = true: whether to log warning messages when blocking fails or denominators are small\n\nExample\n\nsim = solve(...)\ndf_rre, df_se = rayleigh_replica_estimator_analysis(sim; skip=5_000)\n\nusing StatsPlots\n@df df_rre plot(_ -> se, :h, ribbon = (se_l, se_u), label = \"⟨S⟩\") # constant line and ribbon for shift estimator\n@df df_rre plot!(:h, :val, ribbon = (:val_l, :val_u), label=\"E_mix\") # Rayleigh quotient estimator as a function of reweighting depth\nxlabel!(\"h\")\n\nSee also: rayleigh_replica_estimator, mixed_estimator_analysis, AllOverlaps.\n\n\n\n\n\n","category":"method"},{"location":"statstools.html#Rimu.StatsTools.shift_estimator-Tuple{Any}","page":"StatsTools","title":"Rimu.StatsTools.shift_estimator","text":"shift_estimator(df::DataFrame; shift=:shift, kwargs...)\nshift_estimator(sim::PMCSimulation; kwargs...)\n-> r::BlockingResult\n\nReturn the shift estimator from the data in df.shift. The keyword argument shift can be used to change the name of the relevant column. Other keyword arguments are passed on to blocking_analysis. Returns a BlockingResult.\n\nSee also growth_estimator, projected_energy.\n\n\n\n\n\n","category":"method"},{"location":"statstools.html#Rimu.StatsTools.w_exp-Tuple{Union{SubArray{<:Any, 1, <:Vector, <:Any, true}, Vector}, Any, Any}","page":"StatsTools","title":"Rimu.StatsTools.w_exp","text":"w_exp(shift, h, time_step; E_r = mean(shift), skip = 0)\n\nCompute the weights for reweighting over h time steps with reference energy E_r from the exponential formula\n\nw_h^(n) = prod_j=1^h exp-dτ(S^(q+n-j)-E_r) \n\nwhere q = skip and dτ is the time_step.\n\nSee also w_lin, growth_estimator, mixed_estimator.\n\n\n\n\n\n","category":"method"},{"location":"statstools.html#Rimu.StatsTools.w_lin-Tuple{Union{SubArray{<:Any, 1, <:Vector, <:Any, true}, Vector}, Any, Any}","page":"StatsTools","title":"Rimu.StatsTools.w_lin","text":"w_lin(shift, h, time_step; E_r = mean(shift), skip = 0)\n\nCompute the weights for reweighting over h time steps with reference energy E_r from the linearised formula\n\nw_h^(n) = prod_j=1^h 1-dτ(S^(q+n-j)-E_r) \n\nwhere q = skip and dτ is the time_step.\n\nSee also w_exp, growth_estimator, mixed_estimator.\n\n\n\n\n\n","category":"method"},{"location":"statstools.html#Rimu.StatsTools.replica_fidelity-Tuple{Any}","page":"StatsTools","title":"Rimu.StatsTools.replica_fidelity","text":"replica_fidelity(df::DataFrame; p_field = :hproj, skip = 0)\nreplica_fidelity(sim::PMCSimulation; kwargs...)\n\nCompute the fidelity of the average coefficient vector and the projector defined in p_field from the PMCSimulation or DataFrame returned by solve, using replicas _1 and _2. Calls ratio_of_means to perform a blocking analysis on a ratio of the means of separate time series and returns a RatioBlockingResult. The first skip steps in the time series are skipped.\n\nThe fidelity of states |ψ⟩ and |ϕ⟩ is defined as\n\nF(ψϕ) = fracψϕ^2ψψϕϕ \n\nSpecifically, replica_fidelity computes\n\nF(mathbfvmathbfc) =\n frac(mathbfc_1mathbfv)(mathbfvmathbfc_1)\n mathbfc_1mathbfc_1 \n\nwhere v is the projector specified by p_field, which is assumed to be normalised to unity with the two-norm (i.e. v⋅v == 1), and mathbfc_1 and mathbfc_2 are two replica coefficient vectors.\n\n\n\n\n\n","category":"method"},{"location":"statstools.html#Rimu.StatsTools.variational_energy_estimator-Tuple{Any, Any}","page":"StatsTools","title":"Rimu.StatsTools.variational_energy_estimator","text":"variational_energy_estimator(shifts, overlaps; kwargs...)\nvariational_energy_estimator(df::DataFrame; max_replicas=:all, kwargs...)\nvariational_energy_estimator(sim::PMCSimulation; kwargs...)\n-> r::RatioBlockingResult\n\nCompute the variational energy estimator from the replica time series of the shifts and coefficient vector overlaps by blocking analysis. The keyword argument max_replicas can be used to constrain the number of replicas processed to be smaller than all available in df. Other keyword arguments are passed on to ratio_of_means(). Returns a RatioBlockingResult.\n\nAn estimator for the variational energy\n\nfracmathbfc^ mathbfHmathbfcmathbfc^mathbfc\n\nis calculated from\n\nE_v = fracsum_ab^R overline(S_a+S_b) mathbfc_a^ mathbfc_b\n 2sum_ab^R overlinemathbfc_a^ mathbfc_b \n\nwhere the sum goes over distinct pairs out of the R replicas. See arXiv:2103.07800.\n\nThe DataFrame and PMCSimulation versions can extract the relevant information from the result of solve. Set up the ProjectorMonteCarloProblem with the keyword argument replica_strategy = AllOverlaps(R) and R ≥ 2. If passing shifts and overlaps, the data has to be arranged in the correct order (as provided in the DataFrame version).\n\nSee AllOverlaps.\n\n\n\n\n\n","category":"method"},{"location":"statstools.html#Additional-docstrings","page":"StatsTools","title":"Additional docstrings","text":"","category":"section"},{"location":"statstools.html","page":"StatsTools","title":"StatsTools","text":"Modules = [StatsTools]\nPages = [\"StatsTools.jl\", \"blocking.jl\", \"ratio_of_means.jl\", \"convenience.jl\",\n \"variances.jl\", \"growth_witness.jl\", \"reweighting.jl\"\n]\nPublic = false","category":"page"},{"location":"statstools.html#MonteCarloMeasurements.Particles-Tuple{Rimu.StatsTools.BlockingResult{<:Real}}","page":"StatsTools","title":"MonteCarloMeasurements.Particles","text":"MonteCarloMeasurements.Particles(r::BlockingResult; mc_samples = 2000)\nMonteCarloMeasurements.±(r::BlockingResult)\n\nConvert a BlockingResult into a Particles object for nonlinear error propagation with MonteCarloMeasurements.\n\n\n\n\n\n","category":"method"},{"location":"statstools.html#Rimu.StatsTools.BlockingResult","page":"StatsTools","title":"Rimu.StatsTools.BlockingResult","text":"BlockingResult(mean, err, err_err, p_cov, k, blocks)\n\nResult of blocking_analysis.\n\nFields:\n\nmean: sample mean\nerr: standard error (estimated standard deviation of the mean)\nerr_err: estimated uncertainty of err\np_cov: estimated pseudo covariance of mean, relevant for complex time series\nk::Int: k-1 blocking steps were used to uncorrelate time series\nblocks::Int: number of uncorrelated values after blocking\n\nHas methods for NamedTuple, val_and_errs, val, errs, mean_and_se, Measurements.:±, MonteCarloMeasurements.Particles, and Statistics.cov for Complex data.\n\nExample:\n\njulia> blocking_analysis(smoothen(randn(2^10), 2^5))\nBlockingResult{Float64}\n mean = -0.026 ± 0.029\n with uncertainty of ± 0.003638545517264226\n from 32 blocks after 5 transformations (k = 6).\n\n\n\n\n\n","category":"type"},{"location":"statstools.html#Measurements.measurement-Tuple{Rimu.StatsTools.BlockingResult{<:Real}}","page":"StatsTools","title":"Measurements.measurement","text":"measurement(r::BlockingResult)\nMeasurements.±(r::BlockingResult)\n\nConvert a BlockingResult into a Measurement for linear error propagation with Measurements.\n\nLimitation: Does not account for covariance in complex BlockingResult. Consider using MonteCarloMeasurements.Particles(r)!\n\n\n\n\n\n","category":"method"},{"location":"statstools.html#Rimu.StatsTools.blocker-Union{Tuple{AbstractVector{T}}, Tuple{T}} where T","page":"StatsTools","title":"Rimu.StatsTools.blocker","text":"blocker(v::Vector) -> new_v::Vector\n\nReblock the data by successively taking the mean of two adjacent data points to form a new vector with a half of the length(v). The last data point will be discarded if length(v) is odd.\n\n\n\n\n\n","category":"method"},{"location":"statstools.html#Rimu.StatsTools.blocks_with_m-Tuple{Any}","page":"StatsTools","title":"Rimu.StatsTools.blocks_with_m","text":"blocks_with_m(v; corrected = true) -> (;blocks, mean, std_err, std_err_err, p_cov, mj)\n\nPerform the blocking algorithm from Flyvberg and Peterson JCP (1989). Returns named tuple with the results from all blocking steps. See mtest().\n\n\n\n\n\n","category":"method"},{"location":"statstools.html#Rimu.StatsTools.mtest-Tuple{AbstractVector}","page":"StatsTools","title":"Rimu.StatsTools.mtest","text":"mtest(mj::AbstractVector; α = 0.01) -> k\nmtest(table::NamedTuple; α = 0.01) -> k\n\nHypothesis test for decorrelation of a time series after blocking transformations with significance level 1-α after Jonson PRE (2018). mj or table.mj is expected to be a vector with relevant M_j values from a blocking analysis as obtained from blocks_with_m(). Returns the row number k where the M-test is passed. If the M-test has failed mtest() returns the value -1.\n\n\n\n\n\n","category":"method"},{"location":"statstools.html#Rimu.StatsTools.RatioBlockingResult","page":"StatsTools","title":"Rimu.StatsTools.RatioBlockingResult","text":"RatioBlockingResult(ratio, f, σ_f, δ_y, k, success)\n\nResult of ratio_of_means().\n\nFields:\n\nratio::P: ratio with uncertainties propagated by MonteCarloMeasurements\nf::T: ratio of means\nσ_f::T: std from linear propagation\nδ_y::T: coefficient of variation for denominator (≤ 0.1 for normal approx)\nk::Int: k-1 blocking steps were used to uncorrelate time series\nblocks::Int: number of data values after blocking\nsuccess::Bool: false if any of the blocking steps failed\n\nHas methods for NamedTuple, val_and_errs, val, errs.\n\nNote: to compute statistics on the RatioBlockingResult, use functions pmedian, pquantile, pmiddle, piterate, pextrema, pminimum, pmaximum, pmean, and pcov.\n\n\n\n\n\n","category":"type"},{"location":"statstools.html#Rimu.StatsTools.particles-Tuple{Any, Any, Any}","page":"StatsTools","title":"Rimu.StatsTools.particles","text":"particles(samples, μ, σ)\nparticles(samples, μ::AbstractVector, Σ::AbstractMatrix)\n\nReturn Particles object from MonteCarloMeasurements with single- or multivariate normal distribution. Zero variance parameters are supported.\n\n\n\n\n\n","category":"method"},{"location":"statstools.html#Rimu.StatsTools.particles-Tuple{Any, Distributions.Distribution}","page":"StatsTools","title":"Rimu.StatsTools.particles","text":"particles(samples, d)\nparticles(::Nothing, d)\nparticles(::Val{T}, d) where T\n\nReturn Particles object from MonteCarloMeasurements using a type-stable constructor if possible. Pass nothing for the default number of particles or Val(1_000) for using 1000 particles in a type-stable manner. If d is a Particles object it is passed through without re-sampling.\n\n\n\n\n\n","category":"method"},{"location":"statstools.html#Rimu.StatsTools.ratio_estimators-Tuple{AbstractVector{<:Real}, AbstractVector{<:Real}}","page":"StatsTools","title":"Rimu.StatsTools.ratio_estimators","text":"ratio_estimators(x, y, [k]; corrected=true, mc_samples=10_000) -> (; r, f, σ_f, δ_y, n)\n\nEstimators for the ratio of means mean(x)/mean(y). If k is given, k-1 blocking steps are performed to remove internal correlations in the time series x and y. Otherwise these are assumed to be free of internal correlations. Correlations between x and y may be present and are taken into account.\n\nReturn values:\n\nr::Particles is the Monte Carlo sampled ratio estimator, see Particles\nf = mean(x)/mean(y)\nσ_f standard deviation of f from linear error propagation (normal approximation)\nδ_y = std(y)/mean(y) coefficient of variation; < 0.1 for normal approximation to work\nn: number of uncorrelated data used for uncertainty estimation\n\n\n\n\n\n","category":"method"},{"location":"statstools.html#Rimu.StatsTools.x_by_y_linear-NTuple{5, Any}","page":"StatsTools","title":"Rimu.StatsTools.x_by_y_linear","text":"x_by_y_linear(μ_x,μ_y,σ_x,σ_y,ρ) -> f, σ_f\n\nLinear error propagation for ratio f = x/y assuming x and y are correlated normal random variables and assuming the ratio can be approximated as a normal distribution. See wikipedia and Díaz-Francés, Rubio (2013).\n\nσ_f = sqrtfracσ_xμ_y^2 + fracμ_x σ_yμ_y^2^2 - frac2 ρ μ_xμ_y^3\n\n\n\n\n\n","category":"method"},{"location":"statstools.html#Core.NamedTuple-Tuple{Rimu.StatsTools.BlockingResult}","page":"StatsTools","title":"Core.NamedTuple","text":"NamedTuple(x::BlockingResult; n=1, p=nothing, name=:val)\nNamedTuple(x::RatioBlockingResult; n=1, p=nothing, name=:val)\n\nReturn a named tuple with value and error bars (see val_and_errs) as well as additional numerical fields relevant for x.\n\nExample:\n\njulia> results = [blocking_analysis(i:0.1:2i+20) for i in 1:3]; # mock results\n\njulia> df = NamedTuple.(results, name=:res)|>DataFrame\n3×7 DataFrame\n Row │ res res_l res_u res_err_err res_p_cov res_k res_blocks\n │ Float64 Float64 Float64 Float64 Float64 Int64 Int64\n─────┼──────────────────────────────────────────────────────────────────────\n 1 │ 11.5 1.7282 1.7282 0.352767 2.98667 5 13\n 2 │ 13.0 1.7282 1.7282 0.352767 2.98667 5 13\n 3 │ 14.5 1.78885 1.78885 0.350823 3.2 5 14\n\njulia> rbs = ratio_of_means(1 .+sin.(1:0.1:11),2 .+sin.(2:0.1:12)); # more mock results\n\njulia> [NamedTuple(rbs),]|>DataFrame\n1×9 DataFrame\n Row │ val val_l val_u val_f val_σ_f val_δ_y val_k val_blocks val_success\n │ Float64 Float64 Float64 Float64 Float64 Float64 Int64 Int64 Bool\n─────┼────────────────────────────────────────────────────────────────────────────────────────────────\n 1 │ 0.581549 0.0925669 0.0812292 0.560532 0.0875548 0.0875548 4 12 true\n\n\nSee val_and_errs, val, errs, BlockingResult, RatioBlockingResult.\n\n\n\n\n\n","category":"method"},{"location":"statstools.html#Rimu.StatsTools.autocovariance-Tuple{AbstractVector, Int64}","page":"StatsTools","title":"Rimu.StatsTools.autocovariance","text":"autocovariance(v::Vector,h::Int; corrected::Bool=true)\n\nhatgamma(h) =frac1nsum_t=1^n-h(v_t+h-barv)(v_t-barv)^* Calculate the autocovariance of dataset v with a delay h. If corrected is true (the default) then the sum is scaled with n-h, whereas the sum is scaled with n if corrected is false where n = length(v).\n\n\n\n\n\n","category":"method"},{"location":"statstools.html#Rimu.StatsTools.pseudo_cov-Tuple{Any, Any}","page":"StatsTools","title":"Rimu.StatsTools.pseudo_cov","text":"pseudo_cov(x, y; xmean = mean(x), ymean = mean(y), corrected = true)\n\nCompute the pseudo covariance between collections x and y returning a scalar:\n\nfrac1nsum_i=1^n (x_i - barx)(y_i - bary)\n\nOptionally, precomputed means can be passed as keyword arguments. pseudo_cov(x,y) is functionally equivalent to Statistics.cov(x, conj(y); corrected = false) but it is found to be significantly faster and avoids allocations.\n\n\n\n\n\n","category":"method"},{"location":"statstools.html#Rimu.StatsTools.determine_constant_time_step-Tuple{Any}","page":"StatsTools","title":"Rimu.StatsTools.determine_constant_time_step","text":"determine_constant_time_step(df) -> time_step\n\nGiven a DataFrame df, determine the time step that was used to compute it. Throw an error if time step is not constant.\n\n\n\n\n\n","category":"method"},{"location":"statstools.html#Index","page":"StatsTools","title":"Index","text":"","category":"section"},{"location":"statstools.html","page":"StatsTools","title":"StatsTools","text":"Pages = [\"statstools.md\"]","category":"page"},{"location":"interfaces.html#Module-Interfaces","page":"Interfaces","title":"Module Interfaces","text":"","category":"section"},{"location":"interfaces.html","page":"Interfaces","title":"Interfaces","text":"Interfaces","category":"page"},{"location":"interfaces.html#Rimu.Interfaces","page":"Interfaces","title":"Rimu.Interfaces","text":"module Interfaces\n\nThis module contains interfaces that can be used to extend and modify the algorithms and behaviours of Rimu.\n\nInterfaces\n\nFollow the links for the definitions of the interfaces!\n\nAbstractHamiltonian for defining Hamiltonians\nAbstractOperator for defining observable operators\nAbstractDVec for defining data structures for Rimu as in DictVectors\nStochasticStyle for controlling the stochastic algorithms used by ProjectorMonteCarloProblem as implemented in StochasticStyles\n\nAdditional exports\n\nInterface functions forAbstractHamiltonians:\n\ndiagonal_element\nnum_offdiagonals\nget_offdiagonal\noffdiagonals.\nrandom_offdiagonal\nstarting_address\nLOStructure\nallows_address_type\n\nworking with AbstractDVecs and StochasticStyle\n\ndeposit!\ndefault_style\nCompressionStrategy\nThe interface from VectorInterface.jl.\n\nFunctions Rimu.jl uses to do FCIQMC:\n\napply_column!\napply_operator!\nstep_stats\n\n\n\n\n\n","category":"module"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"EditURL = \"../../../scripts/HO-example.jl\"","category":"page"},{"location":"generated/HO-example.html#Example-5:-Degenerate-perturbation-theory-in-a-harmonic-oscillator-basis","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Example 5: Degenerate perturbation theory in a harmonic oscillator basis","text":"","category":"section"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"Rimu can also handle non-lattice systems. This example looks at weakly-interacting bosonic particles in a harmonic oscillator external potential using a basis of (Cartesian product) single-particle eigenstates of the harmonic oscillator potential. Blocks of degenerate non-interacting states are coupled by a contact interaction in first order degenerate perturbation theory. This example shows how to generate these blocks and find the energy and angular momentum eigenstates.","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"A runnable script for this example is located here. Run it with julia HO-example.jl.","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"First, load all needed packages.","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"using Rimu\nusing DataFrames\nusing LinearAlgebra","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"Define the system size for N=2 particles in a 2D harmonic oscillator allowing M=4 levels in each dimension, including the groundstate.","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"N = 2\nM = 4;","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"Use a tuple S to define the range of harmonic oscillator states in a Cartesian basis, in this isotropic case n_xn_y=01ldotsM-1.","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"S = (M, M);","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"In Rimu the N-particle states are still stored as Fock states.","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"P = prod(S)\naddr = BoseFS(P, M => N)","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"BoseFS{2,16}(0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"Here, the numbering of the modes folds in the two spatial dimensions. Use the utility function fock_to_cart to convert a Fock address to human-readable Cartesian quantum numbers for inspection.","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"fock_to_cart(addr, S)","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"2-element StaticArraysCore.SVector{2, Tuple{Int64, Int64}} with indices SOneTo(2):\n (3, 0)\n (3, 0)","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"The output shows that all N particles are in single-particle state n_x=M-1 n_y=0.","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"The harmonic oscillator Hamiltonian HOCartesianContactInteractions handles contact interactions with first-order perturbation theory, so the matrix representation will block according to the non-interacting energy of the basis states. The first task is to find all blocks of basis states with the same energy. The strength of the interaction is not relevant at this point, just that it is non-zero. Use an arbitrary N-particle starting address to build the Hamiltonian.","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"H = HOCartesianContactInteractions(BoseFS(P, 1 => N); S);","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"Then, use the utility function get_all_blocks to find all blocks. The blocks are found by looping over all possible states with N particles in Cartesian states defined by S. Note that this will only work for total energy up to the maximum accessible by a single particle. The N-particle groundstate energy for a 2D harmonic oscillator is E_0 = N hbar omega and the maximum single-particle energy is E = (E_0 + M - 1) hbar omega.","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"block_df = get_all_blocks(H; max_energy = N + M - 1)","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"
7×6 DataFrame
Rowblock_idblock_E0block_sizeaddrindicest_basis
Int64Float64Int64BoseFS…Tuple…Float64
112.01fs"|2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0⟩"(1, 1)1.12114
223.01fs"|1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0⟩"(2, 1)3.4755e-5
334.04fs"|0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0⟩"(2, 2)2.1049e-5
445.05fs"|0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0⟩"(3, 2)1.5679e-5
553.01fs"|1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0⟩"(5, 1)3.557e-6
664.02fs"|0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0⟩"(5, 2)7.003e-6
775.05fs"|0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0⟩"(5, 3)1.4186e-5
","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"This outputs a list of blocks in H indexed by the noninteracting energy of all states in the block, and a single address that can be used to rebuild the block for further analysis.","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"addr1 = block_df[7,:addr]\nE = block_df[7,:block_E0]","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"5.0","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"First, notice that all basis states have the same energy, defined by the block.","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"basis1 = build_basis(H, addr1)\nmap(b -> Hamiltonians.noninteracting_energy(H, b), basis1)","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"5-element Vector{Float64}:\n 5.0\n 5.0\n 5.0\n 5.0\n 5.0","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"There are two blocks at each energy level (except the groundstate), which are different due to parity conservation, which is the only other symmetry in the Cartesian harmonic oscillator. The basis of this other block is different,","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"addr2 = block_df[4,:addr]\nbasis2 = build_basis(H, addr2);\nbasis1 ≠ basis2","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"true","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"but its basis elements have the same energy.","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"map(b -> Hamiltonians.noninteracting_energy(H, b), basis2)","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"5-element Vector{Float64}:\n 5.0\n 5.0\n 5.0\n 5.0\n 5.0","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"However, since this system is an isotropic harmonic oscillator, it is possible to build simultaneous eigenstates of the angular momentum operator L_z, implemented with AxialAngularMomentumHO.","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"Lz = AxialAngularMomentumHO(S)","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"AxialAngularMomentumHO((4, 4); z_dim = 3, addr = BoseFS{0,16}(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"L_z does not conserve parity, so both blocks are required. First combine the bases of each block and convert to DVecs.","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"dvs = map(b -> DVec(b => 1.0), vcat(basis1, basis2));","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"and then compute overlaps for the matrix elements of L_z.","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"Lz_mat = [dot(v, Lz, w) for v in dvs, w in dvs]","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"10×10 Matrix{ComplexF64}:\n 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+1.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0-1.41421im\n 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+1.0im 0.0+0.0im 0.0+0.0im 0.0+1.41421im\n 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0-2.0im 0.0+1.73205im 0.0+0.0im\n 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+1.41421im 0.0-1.41421im 0.0+0.0im 0.0+0.0im 0.0-1.0im\n 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+1.73205im 0.0+0.0im 0.0+0.0im\n 0.0-1.0im 0.0+0.0im 0.0+0.0im 0.0-1.41421im 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im\n 0.0+0.0im 0.0-1.0im 0.0+0.0im 0.0+1.41421im 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im\n 0.0+0.0im 0.0+0.0im 0.0+2.0im 0.0+0.0im 0.0-1.73205im 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im\n 0.0+0.0im 0.0+0.0im 0.0-1.73205im 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im\n 0.0+1.41421im 0.0-1.41421im 0.0+0.0im 0.0+1.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"By diagonalising this matrix the eigenstate have energy E and well-defined angular momentum.","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"Diagonalise this matrix to obtain the eigenstates of L_z. The eigenvectors provide the linear combinations of basis states with well-defined angular momentum, within the subspace of energy E.","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"Lz_vals, Lz_vecs = eigen(Lz_mat)","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"Eigen{ComplexF64, Float64, Matrix{ComplexF64}, Vector{Float64}}\nvalues:\n10-element Vector{Float64}:\n -2.9999999999999956\n -2.999999999999992\n -0.9999999999999991\n -0.9999999999999991\n -0.9999999999999989\n 1.0000000000000002\n 1.0000000000000027\n 1.0000000000000036\n 3.0\n 3.0000000000000004\nvectors:\n10×10 Matrix{ComplexF64}:\n -5.21142e-19-1.11022e-16im 0.0+0.353553im 8.5601e-18-0.0618116im 0.0+0.353553im 0.0394729+0.494592im -0.000677524+0.16408im 0.0-0.353553im -3.16732e-17-0.472311im 0.0+0.353553im -5.48449e-18-5.55112e-17im\n -5.21142e-19-5.55112e-17im 0.0-0.353553im 8.5601e-18-0.0618116im 0.0-0.353553im 0.0394729+0.494592im -0.000677524+0.16408im 0.0+0.353553im -3.16732e-17-0.472311im 0.0-0.353553im -5.48449e-18-5.55112e-17im\n -7.63858e-18-0.612372im 0.0+0.0im 1.29697e-17-0.350841im 0.0+0.0im -0.00347719-0.0435689im -0.00137905+0.333971im 0.0+0.0im -4.17496e-17+0.116023im 0.0+0.0im 5.13001e-18-0.612372im\n 4.62223e-33-2.77556e-17im 0.0+0.5im 3.08149e-33+5.55112e-17im 0.0-0.5im 8.67362e-18+3.46945e-17im 0.0+0.0im 0.0+0.5im -6.16298e-33+1.38778e-17im 0.0+0.5im -1.54074e-33-2.77556e-17im\n 0.0+0.353553im 0.0+0.0im 0.0-0.607675im 0.0+0.0im -0.00602267-0.0754635im -0.00238858+0.578455im 0.0+0.0im -8.32667e-17+0.200958im 0.0+0.0im 0.0+0.353553im\n -3.33067e-16+1.80109e-17im -0.353553+0.0im 0.0618116-6.81613e-18im 0.353553+0.0im -0.494592+0.0394729im 0.16408+0.000677524im 0.353553+0.0im -0.472311-1.92131e-17im 0.353553+0.0im 5.55112e-17+6.86785e-18im\n -2.77556e-16+1.80109e-17im 0.353553+0.0im 0.0618116-6.81613e-18im -0.353553+0.0im -0.494592+0.0394729im 0.16408+0.000677524im -0.353553+0.0im -0.472311-1.92131e-17im -0.353553+0.0im -1.66533e-16+6.86785e-18im\n -0.612372+1.31535e-17im 0.0+0.0im 0.350841-1.23225e-17im 0.0+0.0im 0.0435689-0.00347719im 0.333971+0.00137905im 0.0+0.0im 0.116023+4.42387e-17im 0.0+0.0im 0.612372-5.88226e-18im\n 0.353553-2.94055e-17im 0.0+0.0im 0.607675-3.22708e-17im 5.55112e-17+0.0im 0.0754635-0.00602267im 0.578455+0.00238858im -1.38778e-16+0.0im 0.200958+5.6114e-17im 0.0+0.0im -0.353553+1.82545e-17im\n 0.0+0.0im 0.5+0.0im 0.0+0.0im 0.5+0.0im 0.0+0.0im 0.0+0.0im 0.5+0.0im 0.0+0.0im -0.5-0.0im 0.0+0.0im","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"Finally, consider the effect of interactions by looking at how states in a single block are perturbed. Only the energy shift due to the interaction is relevant so now rebuild the Hamiltonian without the non-interacting energy.","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"Hint = HOCartesianContactInteractions(addr1; S, interaction_only = true)\nΔE = eigvals(Matrix(Hint, addr1))","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"5-element Vector{Float64}:\n -2.081668171172327e-17\n 1.0625181290352691e-17\n 0.15915494309189532\n 0.15915494309189535\n 0.15915494309189543","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"Two eigenstates in this block are unaffected by the interaction and three have a non-zero energy shift.","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"The default strength of the interaction is g = 1.0. Other interactions strengths can be obtained by using keyword argument g in HOCartesianContactInteractions or by rescaling ΔE since the interactions are handled with first-order perturbation theory.","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"Rimu also contains HOCartesianEnergyConservedPerDim which is a similar Hamiltonian but with the stricter condition that the contact interaction only connects states that have the same total energy in each dimension, rather than conserving the overall total energy. Both Hamiltonians can handle anisotropic systems by passing a tuple S whose elements are not all the same. This will alter which states are connected by the interaction, but assumes that the harmonic trapping frequencies in each dimension are commensurate.","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"This page was generated using Literate.jl.","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"EditURL = \"../../../scripts/exact-example.jl\"","category":"page"},{"location":"generated/exact-example.html#Example-4:-Exact-diagonalization","page":"Exact diagonalization","title":"Example 4: Exact diagonalization","text":"","category":"section"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"When working with smaller systems or when multiple eigenvalues of a system are required, one can use an exact diagonalization method. There are a few ways to go about this, each with its pros and cons. The purpose of this tutorial is to show off the methods as well as provide a few tips regarding them.","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"A runnable script for this example is located here. Run it with julia exact-example.jl.","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"We start by loading Rimu.","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"using Rimu","category":"page"},{"location":"generated/exact-example.html#Introduction","page":"Exact diagonalization","title":"Introduction","text":"","category":"section"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"We will look at a bosonic system of 4 particles in 5 sites, formulated in momentum space. Let's start by building the Hamiltonian. To create a Fock state where all particles have zero momentum, we put all the particles in the mode at the centre of the address.","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"M = 5\nN = 4\nadd = BoseFS(M, cld(M, 2) => N)\nham = HubbardMom1D(add)","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"HubbardMom1D(fs\"|0 0 4 0 0⟩\"; u=1.0, t=1.0)","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"Before performing exact diagonalization, it is a good idea to check the dimension of the Hamiltonian.","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"dimension(ham)","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"70","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"Keep in mind that this is an estimate of the number of Fock states the Hamiltonian can act on, not the actual matrix size - the matrix size can sometimes be smaller. It can still be used as a guide to decide whether a Hamiltonian is amenable to exact diagonalization and to determine which algorithm would be best suited to diagonalising it.","category":"page"},{"location":"generated/exact-example.html#The-BasisSetRepresentation","page":"Exact diagonalization","title":"The BasisSetRepresentation","text":"","category":"section"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"As we'll see later, there are two ways to construct the matrices from Hamiltonians directly, but they both use BasisSetRepresentation under the hood. The BasisSetRepresentation, when called with a Hamiltonian and optionally a starting address, constructs the sparse matrix of the system, as well as its basis. The starting address defaults to the one that was used to initialize the Hamiltonian. BasisSetRepresentation only returns the part of the matrix that is accessible from this starting address through non-zero offdiagonal elements.","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"bsr = BasisSetRepresentation(ham);","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"To access the matrix or basis, access the sparse_matrix and basis fields, respectively.","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"bsr.sparse_matrix","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"14×14 SparseArrays.SparseMatrixCSC{Float64, Int32} with 104 stored entries:\n -6.8 0.69282 0.69282 ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ \n 0.69282 -3.03607 0.4 0.4 0.8 ⋅ 0.4 0.282843 0.565685 0.8 ⋅ ⋅ ⋅ ⋅ \n 0.69282 0.4 1.43607 0.8 0.4 0.565685 0.8 0.282843 ⋅ 0.4 ⋅ ⋅ ⋅ ⋅ \n ⋅ 0.4 0.8 2.81803 0.4 0.282843 ⋅ 0.565685 ⋅ 0.4 0.69282 0.69282 ⋅ ⋅ \n ⋅ 0.8 0.4 0.4 0.581966 ⋅ 0.4 0.565685 0.282843 ⋅ ⋅ 0.69282 0.69282 ⋅ \n ⋅ ⋅ 0.565685 0.282843 ⋅ 8.47214 0.282843 0.8 ⋅ ⋅ ⋅ 0.489898 ⋅ 0.489898\n ⋅ 0.4 0.8 ⋅ 0.4 0.282843 2.81803 0.565685 ⋅ 0.4 ⋅ ⋅ 0.69282 0.69282\n ⋅ 0.282843 0.282843 0.565685 0.565685 0.8 0.565685 4.4 0.8 0.565685 0.489898 0.489898 0.489898 0.489898\n ⋅ 0.565685 ⋅ ⋅ 0.282843 ⋅ ⋅ 0.8 -0.472136 0.282843 0.489898 ⋅ 0.489898 ⋅ \n ⋅ 0.8 0.4 0.4 ⋅ ⋅ 0.4 0.565685 0.282843 0.581966 0.69282 ⋅ ⋅ 0.69282\n ⋅ ⋅ ⋅ 0.69282 ⋅ ⋅ ⋅ 0.489898 0.489898 0.69282 1.56393 ⋅ ⋅ ⋅ \n ⋅ ⋅ ⋅ 0.69282 0.69282 0.489898 ⋅ 0.489898 ⋅ ⋅ ⋅ 6.03607 ⋅ ⋅ \n ⋅ ⋅ ⋅ ⋅ 0.69282 ⋅ 0.69282 0.489898 0.489898 ⋅ ⋅ ⋅ 1.56393 ⋅ \n ⋅ ⋅ ⋅ ⋅ ⋅ 0.489898 0.69282 0.489898 ⋅ 0.69282 ⋅ ⋅ ⋅ 6.03607","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"bsr.basis","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"14-element Vector{BoseFS{4, 5, BitString{8, 1, UInt8}}}:\n fs\"|0 0 4 0 0⟩\"\n fs\"|0 1 2 1 0⟩\"\n fs\"|1 0 2 0 1⟩\"\n fs\"|2 1 1 0 0⟩\"\n fs\"|1 0 1 2 0⟩\"\n fs\"|2 0 0 0 2⟩\"\n fs\"|0 0 1 1 2⟩\"\n fs\"|1 1 0 1 1⟩\"\n fs\"|0 2 0 2 0⟩\"\n fs\"|0 2 1 0 1⟩\"\n fs\"|1 3 0 0 0⟩\"\n fs\"|3 0 0 1 0⟩\"\n fs\"|0 0 0 3 1⟩\"\n fs\"|0 1 0 0 3⟩\"","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"When the basis is not needed, we can use Matrix or sparse directly.","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"Matrix(ham)","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"14×14 Matrix{Float64}:\n -6.8 0.69282 0.69282 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0\n 0.69282 -3.03607 0.4 0.4 0.8 0.0 0.4 0.282843 0.565685 0.8 0.0 0.0 0.0 0.0\n 0.69282 0.4 1.43607 0.8 0.4 0.565685 0.8 0.282843 0.0 0.4 0.0 0.0 0.0 0.0\n 0.0 0.4 0.8 2.81803 0.4 0.282843 0.0 0.565685 0.0 0.4 0.69282 0.69282 0.0 0.0\n 0.0 0.8 0.4 0.4 0.581966 0.0 0.4 0.565685 0.282843 0.0 0.0 0.69282 0.69282 0.0\n 0.0 0.0 0.565685 0.282843 0.0 8.47214 0.282843 0.8 0.0 0.0 0.0 0.489898 0.0 0.489898\n 0.0 0.4 0.8 0.0 0.4 0.282843 2.81803 0.565685 0.0 0.4 0.0 0.0 0.69282 0.69282\n 0.0 0.282843 0.282843 0.565685 0.565685 0.8 0.565685 4.4 0.8 0.565685 0.489898 0.489898 0.489898 0.489898\n 0.0 0.565685 0.0 0.0 0.282843 0.0 0.0 0.8 -0.472136 0.282843 0.489898 0.0 0.489898 0.0\n 0.0 0.8 0.4 0.4 0.0 0.0 0.4 0.565685 0.282843 0.581966 0.69282 0.0 0.0 0.69282\n 0.0 0.0 0.0 0.69282 0.0 0.0 0.0 0.489898 0.489898 0.69282 1.56393 0.0 0.0 0.0\n 0.0 0.0 0.0 0.69282 0.69282 0.489898 0.0 0.489898 0.0 0.0 0.0 6.03607 0.0 0.0\n 0.0 0.0 0.0 0.0 0.69282 0.0 0.69282 0.489898 0.489898 0.0 0.0 0.0 1.56393 0.0\n 0.0 0.0 0.0 0.0 0.0 0.489898 0.69282 0.489898 0.0 0.69282 0.0 0.0 0.0 6.03607","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"sparse(ham)","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"14×14 SparseArrays.SparseMatrixCSC{Float64, Int32} with 104 stored entries:\n -6.8 0.69282 0.69282 ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ \n 0.69282 -3.03607 0.4 0.4 0.8 ⋅ 0.4 0.282843 0.565685 0.8 ⋅ ⋅ ⋅ ⋅ \n 0.69282 0.4 1.43607 0.8 0.4 0.565685 0.8 0.282843 ⋅ 0.4 ⋅ ⋅ ⋅ ⋅ \n ⋅ 0.4 0.8 2.81803 0.4 0.282843 ⋅ 0.565685 ⋅ 0.4 0.69282 0.69282 ⋅ ⋅ \n ⋅ 0.8 0.4 0.4 0.581966 ⋅ 0.4 0.565685 0.282843 ⋅ ⋅ 0.69282 0.69282 ⋅ \n ⋅ ⋅ 0.565685 0.282843 ⋅ 8.47214 0.282843 0.8 ⋅ ⋅ ⋅ 0.489898 ⋅ 0.489898\n ⋅ 0.4 0.8 ⋅ 0.4 0.282843 2.81803 0.565685 ⋅ 0.4 ⋅ ⋅ 0.69282 0.69282\n ⋅ 0.282843 0.282843 0.565685 0.565685 0.8 0.565685 4.4 0.8 0.565685 0.489898 0.489898 0.489898 0.489898\n ⋅ 0.565685 ⋅ ⋅ 0.282843 ⋅ ⋅ 0.8 -0.472136 0.282843 0.489898 ⋅ 0.489898 ⋅ \n ⋅ 0.8 0.4 0.4 ⋅ ⋅ 0.4 0.565685 0.282843 0.581966 0.69282 ⋅ ⋅ 0.69282\n ⋅ ⋅ ⋅ 0.69282 ⋅ ⋅ ⋅ 0.489898 0.489898 0.69282 1.56393 ⋅ ⋅ ⋅ \n ⋅ ⋅ ⋅ 0.69282 0.69282 0.489898 ⋅ 0.489898 ⋅ ⋅ ⋅ 6.03607 ⋅ ⋅ \n ⋅ ⋅ ⋅ ⋅ 0.69282 ⋅ 0.69282 0.489898 0.489898 ⋅ ⋅ ⋅ 1.56393 ⋅ \n ⋅ ⋅ ⋅ ⋅ ⋅ 0.489898 0.69282 0.489898 ⋅ 0.69282 ⋅ ⋅ ⋅ 6.03607","category":"page"},{"location":"generated/exact-example.html#Computing-eigenvalues","page":"Exact diagonalization","title":"Computing eigenvalues","text":"","category":"section"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"Now that we have a way of constructing matrices from Hamiltonians, we can use standard Julia functionality to diagonalise them.","category":"page"},{"location":"generated/exact-example.html#The-built-in-method","page":"Exact diagonalization","title":"The built-in method","text":"","category":"section"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"Let's begin by looking at the eigen, eigvecs, and eigvals functions from the LinearAlgebra standard library. They operate on dense matrices and return the full spectra, hence they are only useful for small systems, or when all eigenvalues are required.","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"using LinearAlgebra\n\nmat = Matrix(ham)\neig = eigen(mat);","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"The values can be accessed like so:","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"eig.values","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"14-element Vector{Float64}:\n -6.979863998321608\n -3.3631242916133672\n -0.759019192277071\n 0.1358418221962303\n 0.1578999869460933\n 0.8767114411781449\n 1.5305929970973349\n 1.5835732611867455\n 3.072870330325866\n 3.1256726539518453\n 4.862107221562177\n 6.2606948503805935\n 6.402671211183116\n 9.093371706203953","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"The vectors are stored as columns in eig.vectors:","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"eig.vectors","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"14×14 Matrix{Float64}:\n -0.980348 -0.175378 -0.0135766 -3.15026e-15 0.0221221 0.0697193 9.29812e-16 -0.0314466 -1.42247e-16 -0.0360987 -0.0161557 -9.02056e-17 0.00625248 -0.0058099\n 0.177701 -0.932229 -0.105473 3.33067e-14 -0.225254 0.132826 9.4369e-16 0.00292026 -1.49013e-15 -0.0861158 -0.0907789 -1.16573e-15 0.0591715 -0.0264275\n 0.0768085 0.0622307 -0.0129069 -6.11039e-14 0.447424 0.63969 1.24831e-14 -0.383444 -3.80078e-15 -0.431051 -0.181167 -1.16573e-15 0.0599783 -0.106852\n -0.0119687 0.0373038 -0.0678797 0.0693699 -0.0495446 -0.416847 0.33773 -0.0584554 -0.601232 -0.467179 -0.215841 -0.140166 0.190543 -0.114342\n -0.0214153 0.175119 0.20169 -0.616673 -0.522017 0.296818 0.31234 0.122119 0.123629 -0.106455 -0.126661 -0.0829132 0.148347 -0.0574235\n -0.00237613 -0.00294196 -0.00143189 6.05072e-15 -0.0427486 -0.0110863 -1.72085e-15 0.0663108 -5.55112e-17 0.00167015 0.0832916 4.36456e-15 -0.448519 -0.8863\n -0.0119687 0.0373038 -0.0678797 -0.0693699 -0.0495446 -0.416847 -0.33773 -0.0584554 0.601232 -0.467179 -0.215841 0.140166 0.190543 -0.114342\n -0.00234782 -0.00840544 0.098969 -1.28231e-14 0.0847116 -0.082999 6.70297e-15 -0.274424 3.2474e-15 0.575786 -0.61385 -5.37764e-15 0.353775 -0.259338\n -0.0138439 0.165902 -0.922758 1.50713e-14 -0.1111 0.172508 -4.02109e-15 0.207974 -4.85723e-17 0.0848902 -0.149153 -8.60423e-16 0.0712921 -0.0301968\n -0.0214153 0.175119 0.20169 0.616673 -0.522017 0.296818 -0.31234 0.122119 -0.123629 -0.106455 -0.126661 0.0829132 0.148347 -0.0574235\n 0.00363555 -0.0455298 0.133824 -0.332825 0.290831 0.057199 -0.527627 0.588225 -0.332816 -0.0472302 -0.18528 -0.00844536 0.0915588 -0.0346434\n 0.00195478 -0.0150664 -0.0206752 0.0642658 0.0638689 0.0250518 -0.0999631 0.012992 0.111668 0.0393523 0.423534 -0.688046 0.513839 -0.222499\n 0.00363555 -0.0455298 0.133824 0.332825 0.290831 0.057199 0.527627 0.588225 0.332816 -0.0472302 -0.18528 0.00844536 0.0915588 -0.0346434\n 0.00195478 -0.0150664 -0.0206752 -0.0642658 0.0638689 0.0250518 0.0999631 0.012992 -0.111668 0.0393523 0.423534 0.688046 0.513839 -0.222499","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"If you need the full spectrum, but would like to use less memory, consider using the in-place eigen!.","category":"page"},{"location":"generated/exact-example.html#Iterative-sparse-solvers","page":"Exact diagonalization","title":"Iterative sparse solvers","text":"","category":"section"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"For larger Hamiltonians, it is better to use an iterative solver. There are several options. We will look at eigs from Arpack.jl and eigsolve from KrylovKit.jl.","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"Let's start with Arpack's eigs. It is important to set the nev and which keyword arguments. nev sets the number of eigenpairs to find. which should in most cases be set to :SR, which will find the eigenvalues with the smallest real part.","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"using Arpack\n\nnum_eigvals = 3\n\nsparse_matrix = sparse(ham)\nvals_ar, vecs_ar = eigs(sparse_matrix; which=:SR, nev=num_eigvals)\nvals_ar","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"3-element Vector{Float64}:\n -6.979863998321618\n -3.363124291613361\n -0.7590191922770777","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"Using KrylovKit's eigsolve is similar, but the nev and which are given as positional arguments. Note that KrylovKit may sometimes return more than nev eigenpairs if it happens to find them.","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"using KrylovKit\n\nvals_kk, vecs_kk = eigsolve(sparse_matrix, num_eigvals, :SR)\nvals_kk","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"14-element Vector{Float64}:\n -6.979863998321633\n -3.3631242916133512\n -0.7590191922770817\n 0.13584182219620367\n 0.1578999869460933\n 0.8767114411781343\n 1.530592997097334\n 1.583573261186734\n 3.0728703303258706\n 3.125672653951841\n 4.862107221562171\n 6.2606948503805935\n 6.402671211183112\n 9.093371706203957","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"Both solvers use variants of the Lanczos algorithm for Hermitian matrices and the Arnoldi algorithm for non-Hermitian ones. These may in some cases miss degenerate eigenpairs.","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"If diagonalization takes too long, you can reduce the tolerance by setting the tol keyword argument to eigs or eigsolve. Using drastically lower tolerances than the default can still produce good results in practice. This, however, should be checked on a case-by-case basis.","category":"page"},{"location":"generated/exact-example.html#The-matrix-free-method","page":"Exact diagonalization","title":"The matrix-free method","text":"","category":"section"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"KrylovKit's eigsolve function is implemented in a way that does not require the linear operator and vector to be Julia arrays. Rimu leverages this functionality, which allows diagonalising Hamiltonians without ever needing to construct the matrix - all matrix elements are generated on the fly.","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"While this method is by far the slowest of the ones discussed, it also uses drastically less memory. This allows us to diagonalise much larger Hamiltonians.","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"To use this method, you first need a starting vector. It's best to use PDVec here as it leverages threading during the diagonalization.","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"dvec = PDVec(add => 1.0)","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"1-element PDVec: style = IsDeterministic{Float64}()\n fs\"|0 0 4 0 0⟩\" => 1.0","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"Then, pass that vector and the Hamiltonian to eigsolve.","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"vals_mf, vecs_mf = eigsolve(ham, dvec, num_eigvals, :SR; issymmetric=true)\nvals_mf","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"10-element Vector{Float64}:\n -6.979863998321612\n -3.3631242916133406\n -0.7590191922770728\n 0.1578999869460862\n 0.8767114411781503\n 1.5835732611867401\n 3.125672653951839\n 4.862107221562172\n 6.402671211183112\n 9.093371706203953","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"Keep in mind that if an eigenvector is orthogonal to dvec, KrylovKit will miss it. Consider the following example:","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"eigsolve(ham, vecs_mf[2], num_eigvals, :SR, issymmetric=true)[1]","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"1-element Vector{Float64}:\n -3.3631242916133606","category":"page"},{"location":"generated/exact-example.html#Reducing-matrix-size-with-symmetries","page":"Exact diagonalization","title":"Reducing matrix size with symmetries","text":"","category":"section"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"As these matrices tend to get large quickly, memory is usually the bottleneck. There are currently two methods implemented to reduce the matrix size, ParitySymmetry and TimeReversalSymmetry. These symmetries work by performing a unitary transformation on the Hamiltonian which causes it to become block-diagonal. When building a matrix from a block-diagonal Hamiltonian, only the block that contains the starting address is constructed.","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"You should only use these where the relevant symmetries actually apply - no checks are performed to make sure they do. There is also currently no way of using both at the same time. Please consult the documentation for a more in-depth description of these options.","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"The Hamiltonian presented in this example is compatible with ParitySymmetry. Let's see how the matrix size is reduced when applying it.","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"size(sparse(ham))","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"(14, 14)","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"size(sparse(ParitySymmetry(ham)))","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"(10, 10)","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"In this small example, the size reduction is modest, but for larger systems, you can expect to reduce the dimension of the matrix by about half.","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"all_eigs = eigvals(Matrix(ham))\neven_eigs = eigvals(Matrix(ParitySymmetry(ham)))","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"10-element Vector{Float64}:\n -6.979863998321619\n -3.3631242916133615\n -0.7590191922770766\n 0.1578999869460802\n 0.876711441178143\n 1.5835732611867412\n 3.1256726539518436\n 4.862107221562176\n 6.4026712111831126\n 9.093371706203952","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"The eigenvalues of the transformed Hamiltonian are a subset of the full spectrum. To get the other half, we can pass the even=false keyword argument to ParitySymmetry. When doing that, we need to make sure the starting address of the Hamiltonian is not symmetric under reversal:","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"add_odd = BoseFS(M, cld(M, 2) => N - 3, cld(M, 2) - 1 => 2, cld(M, 2) + 2 => 1)","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"BoseFS{4,5}(0, 2, 1, 0, 1)","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"odd_eigs = eigvals(Matrix(ParitySymmetry(HubbardMom1D(add_odd); even=false)))","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"4-element Vector{Float64}:\n 0.135841822196218\n 1.530592997097328\n 3.0728703303258613\n 6.260694850380591","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"Now, let's check that combining the two sets of eigenvalues indeed recovers the whole spectrum.","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"sort([even_eigs; odd_eigs]) ≈ all_eigs","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"true","category":"page"},{"location":"generated/exact-example.html#Computing-observables","page":"Exact diagonalization","title":"Computing observables","text":"","category":"section"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"Since building a matrix from an operator only builds the part that is reachable from the starting address, we need to use a different approach when computing observables.","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"To demonstrate this, we will use the DensityMatrixDiagonal operator, which in this case will give the momentum density.","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"The idea here is to construct a PDVec from the computed eigenvector and use it directly with the operator.","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"dvec = PDVec(zip(bsr.basis, eigvecs(Matrix(ham))[:, 1]))","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"14-element PDVec: style = IsDeterministic{Float64}()\n fs\"|1 3 0 0 0⟩\" => 0.00363555\n fs\"|1 0 1 2 0⟩\" => -0.0214153\n fs\"|2 0 0 0 2⟩\" => -0.00237613\n fs\"|0 0 4 0 0⟩\" => -0.980348\n fs\"|0 1 2 1 0⟩\" => 0.177701\n fs\"|0 0 1 1 2⟩\" => -0.0119687\n fs\"|3 0 0 1 0⟩\" => 0.00195478\n fs\"|0 0 0 3 1⟩\" => 0.00363555\n fs\"|0 2 0 2 0⟩\" => -0.0138439\n fs\"|2 1 1 0 0⟩\" => -0.0119687\n fs\"|1 1 0 1 1⟩\" => -0.00234782\n fs\"|0 1 0 0 3⟩\" => 0.00195478\n fs\"|1 0 2 0 1⟩\" => 0.0768085\n fs\"|0 2 1 0 1⟩\" => -0.0214153","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"The eigenvectors these methods produce are normalized, hence we can use the three-argument dot to compute the values of observables. Here we are computing the single particle momentum density distribution, which is just the diagonal of the single-particle density matrix in momentum space.","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"[dot(dvec, DensityMatrixDiagonal(i), dvec) for i in 1:M]","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"5-element Vector{Float64}:\n 0.006686138945087834\n 0.03307039977204201\n 3.9204869225657397\n 0.033070399772041965\n 0.006686138945087815","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"This page was generated using Literate.jl.","category":"page"},{"location":"rimuio.html#Module-RimuIO","page":"I/O","title":"Module RimuIO","text":"","category":"section"},{"location":"rimuio.html","page":"I/O","title":"I/O","text":"Modules = [RimuIO]","category":"page"},{"location":"rimuio.html#Rimu.RimuIO","page":"I/O","title":"Rimu.RimuIO","text":"Module to provide file input and output functionality for Rimu. Provides convenience functions:\n\nRimuIO.save_df(filename, df::DataFrame) Save dataframe in Arrow format.\nRimuIO.load_df(filename) Load Arrow file into dataframe.\nRimuIO.save_state(filename, vector; metadata...) Save a vector and optinal metadata in Arrow format.\nRimuIO.load_state(filename) Load a file created by save_state.\n\n\n\n\n\n","category":"module"},{"location":"rimuio.html#Rimu.RimuIO.DVecAsTable","page":"I/O","title":"Rimu.RimuIO.DVecAsTable","text":"struct DVecAsTable\n\nWrapper over the storage of a DVec that allows us to treat a DVec as a table from Tables.jl. Constructed with Tables.table(::DVec).\n\n\n\n\n\n","category":"type"},{"location":"rimuio.html#Rimu.RimuIO.PDVecAsTable","page":"I/O","title":"Rimu.RimuIO.PDVecAsTable","text":"struct PDVecAsTable\n\nWrapper over the storage of a PDVec that allows us to treat a PDVec as a table from Tables.jl. Constructed with Tables.table(::PDVec).\n\n\n\n\n\n","category":"type"},{"location":"rimuio.html#Rimu.RimuIO.load_df-Tuple{Any}","page":"I/O","title":"Rimu.RimuIO.load_df","text":"load_df(filename; propagate_metadata = true, add_filename = true) -> DataFrame\n\nLoad Arrow file into DataFrame. Optionally propagate metadata to DataFrame and add the file name as metadata.\n\nSee also RimuIO.save_df.\n\n\n\n\n\n","category":"method"},{"location":"rimuio.html#Rimu.RimuIO.load_state-Union{Tuple{D}, Tuple{Type{D}, Any}} where D","page":"I/O","title":"Rimu.RimuIO.load_state","text":"load_state(filename; kwargs...) -> PDVec, NamedTuple\nload_state(PDVec, filename; kwargs...) -> PDVec, NamedTuple\nload_state(DVec, filename; kwargs...) -> DVec, NamedTuple\n\nLoad the state saved in the Arrow file filename. kwargs are passed to the constructor of PDVec/DVec. Any metadata stored in the file is be parsed as a number (if possible) and returned alongside the vector in a NamedTuple.\n\nSee also save_state.\n\n\n\n\n\n","category":"method"},{"location":"rimuio.html#Rimu.RimuIO.save_df-Tuple{Any, DataFrame}","page":"I/O","title":"Rimu.RimuIO.save_df","text":"save_df(filename, df::DataFrame; kwargs...)\n\nSave dataframe in Arrow format.\n\nKeyword arguments are passed on to Arrow.write. Compression is enabled by default for large DataFrames (over 10,000 rows).\n\nTable-level metadata of the DataFrame is saved as Arrow metadata (with String value) unless overwritten with the keyword argument metadata.\n\nSee also RimuIO.load_df.\n\n\n\n\n\n","category":"method"},{"location":"rimuio.html#Rimu.RimuIO.save_state-Tuple{Any, Any}","page":"I/O","title":"Rimu.RimuIO.save_state","text":"save_state(filename, vector; io, kwargs...)\n\nSave PDVec or DVec vector to an arrow file filename.\n\nio determines the output stream to write progress to. Defaults to stderr when MPI is enabled and devnull otherwise.\n\nAll other kwargs are saved as strings to the arrow file and will be parsed back when the state is loaded.\n\nSee also load_state.\n\n\n\n\n\n","category":"method"},{"location":"rimuio.html#Index","page":"I/O","title":"Index","text":"","category":"section"},{"location":"rimuio.html","page":"I/O","title":"I/O","text":"Pages = [\"rimuio.md\"]","category":"page"},{"location":"hamiltonians.html#Module-Hamiltonians","page":"Hamiltonians","title":"Module Hamiltonians","text":"","category":"section"},{"location":"hamiltonians.html","page":"Hamiltonians","title":"Hamiltonians","text":"This module contains definitions of Hamiltonians, in particular specific physical models of interest. These are organised by means of an interface around the abstract type AbstractHamiltonian, in the spirit of the AbstractArray interface as discussed in the Julia Documentation.","category":"page"},{"location":"hamiltonians.html","page":"Hamiltonians","title":"Hamiltonians","text":"The Hamiltonians can be used for projector quantum Monte Carlo with ProjectorMonteCarloProblem or for exact diagonalization with ExactDiagonalizationProblem, see Exact Diagonalization.","category":"page"},{"location":"hamiltonians.html","page":"Hamiltonians","title":"Hamiltonians","text":"Hamiltonians","category":"page"},{"location":"hamiltonians.html#Rimu.Hamiltonians","page":"Hamiltonians","title":"Rimu.Hamiltonians","text":"The module Rimu.Hamiltonians defines types and functions for working with Hamiltonians.\n\nExported concrete Hamiltonian types\n\nReal space Hubbard models\n\nHubbardReal1D\nHubbardReal1DEP\nHubbardRealSpace\nExtendedHubbardReal1D\n\nMomentum space Hubbard models\n\nHubbardMom1D\nHubbardMom1DEP\n\nHarmonic oscillator models\n\nHOCartesianContactInteractions\nHOCartesianEnergyConservedPerDim\nHOCartesianCentralImpurity\n\nOther\n\nFroehlichPolaron\nMatrixHamiltonian\nTranscorrelated1D\n\nWrappers\n\nGutzwillerSampling\nGuidingVectorSampling\nParitySymmetry\nTimeReversalSymmetry\nStoquastic\n\nObservables\n\nParticleNumberOperator\nG2RealCorrelator\nG2MomCorrelator\nG2RealSpace\nDensityMatrixDiagonal\nSingleParticleExcitation\nTwoParticleExcitation\nMomentum\nAxialAngularMomentumHO\n\nInterface for working with Hamiltonians\n\nAbstractHamiltonian: defined in the module Interfaces\n\n\n\n\n\n","category":"module"},{"location":"hamiltonians.html","page":"Hamiltonians","title":"Hamiltonians","text":"Here is a list of fully implemented model Hamiltonians. There are several variants of the Hubbard model in real and momentum space, as well as some other models.","category":"page"},{"location":"hamiltonians.html#Real-space-Hubbard-models","page":"Hamiltonians","title":"Real space Hubbard models","text":"","category":"section"},{"location":"hamiltonians.html","page":"Hamiltonians","title":"Hamiltonians","text":"HubbardReal1D\nHubbardReal1DEP\nHubbardRealSpace\nExtendedHubbardReal1D","category":"page"},{"location":"hamiltonians.html#Rimu.Hamiltonians.HubbardReal1D","page":"Hamiltonians","title":"Rimu.Hamiltonians.HubbardReal1D","text":"HubbardReal1D(address; u=1.0, t=1.0)\n\nImplements a one-dimensional Bose Hubbard chain in real space.\n\nhatH = -t sum_langle ijrangle a_i^ a_j + fracu2sum_i n_i (n_i-1)\n\nArguments\n\naddress: the starting address, defines number of particles and sites.\nu: the interaction parameter.\nt: the hopping strength.\n\nSee also\n\nHubbardMom1D\nExtendedHubbardReal1D\n\n\n\n\n\n","category":"type"},{"location":"hamiltonians.html#Rimu.Hamiltonians.HubbardReal1DEP","page":"Hamiltonians","title":"Rimu.Hamiltonians.HubbardReal1DEP","text":"HubbardReal1DEP(address; u=1.0, t=1.0, v_ho=1.0)\n\nImplements a one-dimensional Bose Hubbard chain in real space with external potential.\n\nhatH = -t sum_langle ijrangle a_i^ a_j + sum_i ϵ_i n_i\n+ fracu2sum_i n_i (n_i-1)\n\nArguments\n\naddress: the starting address, defines number of particles and sites.\nu: the interaction parameter.\nt: the hopping strength.\nv_ho: strength of the external harmonic oscillator potential ϵ_i = v_ho i^2.\n\nThe first index is i=0 and the maximum of the potential occurs in the centre of the lattice.\n\nSee also\n\nHubbardReal1D\nHubbardMom1D\nExtendedHubbardReal1D\n\n\n\n\n\n","category":"type"},{"location":"hamiltonians.html#Rimu.Hamiltonians.HubbardRealSpace","page":"Hamiltonians","title":"Rimu.Hamiltonians.HubbardRealSpace","text":"HubbardRealSpace(address; geometry=PeriodicBoundaries(M,), t=ones(C), u=ones(C, C), v=zeros(C, D))\n\nHubbard model in real space. Supports single or multi-component Fock state addresses (with C components) and various (rectangular) lattice geometries in D dimensions.\n\n hatH = -sum_langle ijrangleσ t_σ a^_iσ a_jσ +\n frac12sum_iσ u_σσ n_iσ (n_iσ - 1) +\n sum_iστu_στ n_iσ n_iτ\n\nIf v is nonzero then this calculates hatH + hatV by adding the harmonic trapping potential\n\n hatV = sum_iσd v_σd x_di^2 n_iσ\n\nwhere x_di is the distance of site i from the centre of the trap along dimension d.\n\nAddress types\n\nBoseFS: Single-component Bose-Hubbard model.\nFermiFS: Single-component Fermi-Hubbard model.\nCompositeFS: For multi-component models.\n\nNote that a single component of fermions cannot interact with itself. A warning is produced if addressis incompatible with the interaction parameters u.\n\nGeometries\n\nImplemented CubicGrids for keyword geometry\n\nPeriodicBoundaries\nHardwallBoundaries\nLadderBoundaries\n\nDefault is geometry=PeriodicBoundaries(M,), i.e. a one-dimensional lattice with the number of sites M inferred from the number of modes in address.\n\nOther parameters\n\nt: the hopping strengths. Must be a vector of length C. The i-th element of the vector corresponds to the hopping strength of the i-th component.\nu: the on-site interaction parameters. Must be a symmetric matrix. u[i, j] corresponds to the interaction between the i-th and j-th component. u[i, i] corresponds to the interaction of a component with itself. Note that u[i,i] must be zero for fermionic components.\nv: the trap potential strengths. Must be a matrix of size C × D. v[i,j] is the strength of the trap for component i in the jth dimension.\n\n\n\n\n\n","category":"type"},{"location":"hamiltonians.html#Rimu.Hamiltonians.ExtendedHubbardReal1D","page":"Hamiltonians","title":"Rimu.Hamiltonians.ExtendedHubbardReal1D","text":"ExtendedHubbardReal1D(address; u=1.0, v=1.0, t=1.0, boundary_condition=:periodic)\n\nImplements the extended Hubbard model on a one-dimensional chain in real space. This Hamiltonian can be either real or complex, depending on the choice of boundary_condition.\n\nhatH = -t sum_langle ijrangle a_i^ a_j + fracu2sum_i n_i (n_i-1) +\nv sum_langle ijrangle n_i n_j\n\nArguments\n\naddress: the starting address.\nu: on-site interaction parameter\nv: the next-neighbor interaction\nt: the hopping strength\nboundary_condition The following values are supported:\n:periodic: usual period boundary condition realising a ring geometry.\n:hard_wall: hopping over the boundary is not allowed.\n:twisted: like :periodic but hopping over the boundary incurs an additional factor of -1.\nθ <: Number: like :periodic and :twisted but hopping over the boundary incurs a factor exp(iθ) for a hop to the right and exp(iθ) for a hop to the left. With this choice the Hamiltonian will have a complex eltype whereas otherwise the eltype is determined by the type of the parameters t, u, and v.\n\nSee also HubbardRealSpace.\n\n\n\n\n\n","category":"type"},{"location":"hamiltonians.html#Momentum-space-Hubbard-models","page":"Hamiltonians","title":"Momentum space Hubbard models","text":"","category":"section"},{"location":"hamiltonians.html","page":"Hamiltonians","title":"Hamiltonians","text":"HubbardMom1D\nHubbardMom1DEP\nExtendedHubbardMom1D","category":"page"},{"location":"hamiltonians.html#Rimu.Hamiltonians.HubbardMom1D","page":"Hamiltonians","title":"Rimu.Hamiltonians.HubbardMom1D","text":"HubbardMom1D(address; u=1.0, t=1.0, dispersion=hubbard_dispersion)\n\nImplements a one-dimensional Bose Hubbard chain in momentum space.\n\nhatH = sum_k ϵ_k n_k + fracuMsum_kpqr a^_r a^_q a_p a_k δ_r+qp+k\n\nArguments\n\naddress: the starting address, defines number of particles and sites.\nu: the interaction parameter.\nt: the hopping strength.\ndispersion: defines ϵ_k =dispersion(t, k)\nhubbard_dispersion: ϵ_k = -2(Re(t) cos(k) + Im(t) sin(k))\ncontinuum_dispersion: ϵ_k = Re(t) k^2 - 2 Im(t) k\n\nSee also\n\nHubbardReal1D\nExtendedHubbardReal1D\n\n\n\n\n\n","category":"type"},{"location":"hamiltonians.html#Rimu.Hamiltonians.HubbardMom1DEP","page":"Hamiltonians","title":"Rimu.Hamiltonians.HubbardMom1DEP","text":"HubbardMom1DEP(address; u=1.0, t=1.0, v_ho=1.0, dispersion=hubbard_dispersion)\n\nImplements a one-dimensional Bose Hubbard chain in momentum space with harmonic external potential.\n\nH = sum_k ϵ_k n_k + fracuMsum_kpqr a^_r a^_q a_p a_k δ_r+qp+k\n + V_mathrmho \n\nwhere\n\nbeginaligned\nV_mathrmho = frac1M sum_pq mathrmDFTV_ext_p-q \n a^_p a_q \nV_mathrmext(x) = v_mathrmho x^2 \nendaligned\n\nis an external harmonic potential in momentum space, mathrmDFT_k is a discrete Fourier transform performed by fft()[k%M + 1], and M == num_modes(address).\n\nArguments\n\naddress: the starting address, defines number of particles and sites.\nu: the interaction parameter.\nt: the hopping strength.\ndispersion: defines ϵ_k =dispersion(t, k)\nhubbard_dispersion: ϵ_k = -2Re(t) cos(k) + Im(t) sin(k)\ncontinuum_dispersion: ϵ_k = Re(t) k^2 - 2 Im(t) k\nv_ho: strength of the external harmonic oscillator potential v_mathrmho.\n\nSee also HubbardMom1D, HubbardReal1DEP, Transcorrelated1D, Hamiltonians.\n\n\n\n\n\n","category":"type"},{"location":"hamiltonians.html#Rimu.Hamiltonians.ExtendedHubbardMom1D","page":"Hamiltonians","title":"Rimu.Hamiltonians.ExtendedHubbardMom1D","text":"ExtendedHubbardMom1D(\n address; \n u=1.0, t=1.0, v=1.0, dispersion=hubbard_dispersion, boundary_condition = 0.0\n)\n\nImplements a one-dimensional extended Hubbard chain, also known as the t - V model, in momentum space.\n\nhatH = sum_k ϵ_k n_k + frac12M sum_kpqr (u + 2v cos(q-p)) a^_r a^_q a_p a_k δ_r+qp+k\n\nArguments\n\naddress: the starting address, defines number of particles and sites.\nu: the interaction parameter.\nt: the hopping strength.\nboundary_condition: θ <: Number: hopping over the boundary incurs a factor exp(iθ) for a hop to the right and exp(iθ) for a hop to the left.\ndispersion: defines ϵ_k =dispersion(t, k + θ)\nhubbard_dispersion: ϵ_k = -2 (Re(t) cos(k + θ) + Im(t) sin(k + θ))\ncontinuum_dispersion: ϵ_k = Re(t) (k + θ)^2 - 2 Im(t) (k + θ)\n\nSee also\n\nHubbardMom1D\nHubbardReal1D\nExtendedHubbardReal1D\n\n\n\n\n\n","category":"type"},{"location":"hamiltonians.html#Harmonic-oscillator-models","page":"Hamiltonians","title":"Harmonic oscillator models","text":"","category":"section"},{"location":"hamiltonians.html","page":"Hamiltonians","title":"Hamiltonians","text":"HOCartesianContactInteractions\nHOCartesianEnergyConservedPerDim\nHOCartesianCentralImpurity","category":"page"},{"location":"hamiltonians.html#Rimu.Hamiltonians.HOCartesianContactInteractions","page":"Hamiltonians","title":"Rimu.Hamiltonians.HOCartesianContactInteractions","text":"HOCartesianContactInteractions(addr; S, η, g = 1.0, interaction_only = false, block_by_level = true)\n\nImplements a bosonic harmonic oscillator in Cartesian basis with contact interactions\n\nhatH = sum_i epsilon_mathbfi n_mathbfi + fracg2sum_mathbfijkl\n V_mathbfijkl a^_mathbfi a^_mathbfj a_mathbfk a_mathbfl\n\nFor a D-dimensional harmonic oscillator indices mathbfi mathbfj ldots are D-tuples. The energy scale is defined by the first dimension i.e. hbar omega_x so that single particle energies are\n\n fracepsilon_mathbfihbar omega_x = (i_x + 12) + eta_y (i_y+12) + ldots\n\nThe factors eta_y ldots allow for anisotropic trapping geometries and are assumed to be greater than 1 so that omega_x is the smallest trapping frequency.\n\nBy default the offdiagonal elements due to the interactions are consistent with first-order degenerate perturbation theory\n\n V_mathbfijkl = delta_epsilon_mathbfi + epsilon_mathbfj\n ^epsilon_mathbfk + epsilon_mathbfl\n prod_d in x yldots mathcalI(i_dj_dk_dl_d)\n\nwhere the delta function indicates that the total noninteracting energy is conserved meaning all states with the same noninteracting energy are connected by this interaction and the Hamiltonian blocks according to noninteracting energy levels. Setting block_by_level = false will disable this restriction and allow coupling between basis states of any noninteracting energy level, leading to many more offdiagonals and fewer but larger blocks (the blocks are still distinguished by parity of basis states). Alternatively, see HOCartesianEnergyConservedPerDim for a model with the stronger restriction that conserves energy separately per spatial dimension. The integral mathcalI(abcd) is of four one dimensional harmonic oscillator basis functions, implemented in four_oscillator_integral_general.\n\nArguments\n\naddr: the starting address, defines number of particles and total number of modes.\nS: Tuple of the number of levels in each dimension, including the groundstate. The allowed couplings between states is defined by the aspect ratio of S .- 1. Defaults to a 1D spectrum with number of levels matching modes of addr. Will be sorted to make the first dimension the largest.\nη: Define a custom aspect ratio for the trapping potential strengths, instead of deriving from S .- 1. This will only affect the single particle energy scale and not the interactions. The values are always scaled relative to the first dimension, which sets the energy scale of the system, hbaromega_x.\ng: the (isotropic) bare interaction parameter. The value of g is assumed to be in trap units.\ninteraction_only: if set to true then the noninteracting single-particle terms are ignored. Useful if only energy shifts due to interactions are required.\nblock_by_level: if set to false will allow the interactions to couple all states without comparing their noninteracting energy.\n\nwarning: Warning\nnum_offdiagonals is a bad estimate for this Hamiltonian. Take care when building a matrix or using QMC methods. Use get_all_blocks first then pass option col_hint = block_size to BasisSetRep to safely build the matrix.\n\n\n\n\n\n","category":"type"},{"location":"hamiltonians.html#Rimu.Hamiltonians.HOCartesianEnergyConservedPerDim","page":"Hamiltonians","title":"Rimu.Hamiltonians.HOCartesianEnergyConservedPerDim","text":"HOCartesianEnergyConservedPerDim(addr; S, η, g = 1.0, interaction_only = false)\n\nImplements a bosonic harmonic oscillator in Cartesian basis with contact interactions\n\nhatH = sum_i ϵ_i n_i + fracg2sum_ijkl V_ijkl a^_i a^_j a_k a_l\n\nwith the additional restriction that the interactions only couple states with the same energy in each dimension separately. See HOCartesianContactInteractions for a model that conserves total energy.\n\nFor a D-dimensional harmonic oscillator indices mathbfi mathbfj ldots are D-tuples. The energy scale is defined by the first dimension i.e. hbar omega_x so that single particle energies are\n\n fracepsilon_mathbfihbar omega_x = (i_x + 12) + eta_y (i_y+12) + ldots\n\nThe factors eta_y ldots allow for anisotropic trapping geometries and are assumed to be greater than 1 so that omega_x is the smallest trapping frequency.\n\nMatrix elements V_mathbfijkl are for a contact interaction calculated in this basis using first-order degenerate perturbation theory.\n\n V_mathbfijkl = prod_d in x yldots mathcalI(i_dj_dk_dl_d)\n delta_i_d + j_d^k_d + l_d\n\nwhere the delta-function indicates that the noninteracting energy is conserved along each dimension. The integral mathcalI(abcd) is of four one dimensional harmonic oscillator basis functions, see four_oscillator_integral_general, with the additional restriction that energy is conserved in each dimension.\n\nArguments\n\naddr: the starting address, defines number of particles and total number of modes.\nS: Tuple of the number of levels in each dimension, including the groundstate. Defaults to a 1D spectrum with number of levels matching modes of addr. Will be sorted to make the first dimension the largest.\nη: Define a custom aspect ratio for the trapping potential strengths, instead of deriving from S .- 1. The values are always scaled relative to the first dimension, which sets the energy scale of the system, hbaromega_x.\ng: the (isotropic) interparticle interaction parameter. The value of g is assumed to be in trap units.\ninteraction_only: if set to true then the noninteracting single-particle terms are ignored. Useful if only energy shifts due to interactions are required.\n\n\n\n\n\n","category":"type"},{"location":"hamiltonians.html#Rimu.Hamiltonians.HOCartesianCentralImpurity","page":"Hamiltonians","title":"Rimu.Hamiltonians.HOCartesianCentralImpurity","text":"HOCartesianCentralImpurity(addr; kwargs...)\n\nHamiltonian of non-interacting particles in an arbitrary harmonic trap with a delta-function potential at the centre, with strength g,\n\nhatH_mathrmrel = sum_mathbfi ϵ_mathbfi n_mathbfi\n + gsum_mathbfij V_mathbfij a^_mathbfi a_mathbfj\n\nFor a D-dimensional harmonic oscillator indices mathbfi mathbfj ldots are D-tuples. The energy scale is defined by the first dimension i.e. hbar omega_x so that single particle energies are\n\n fracepsilon_mathbfihbar omega_x = (i_x + 12) + eta_y (i_y+12) + ldots\n\nThe factors eta_y ldots allow for anisotropic trapping geometries and are assumed to be greater than 1 so that omega_x is the smallest trapping frequency.\n\nMatrix elements V_mathbfij are for a delta function potential calculated in this basis\n\n V_mathbfij = prod_d in x yldots psi_i_d(0) psi_j_d(0)\n\nOnly even parity states feel this impurity, so all i_d are even. Note that the matrix representation of this Hamiltonian for a single particle is completely dense in the even-parity subspace.\n\nArguments\n\naddr: the starting address, defines number of particles and total number of modes.\nmax_nx = num_modes(addr) - 1: the maximum harmonic oscillator index number in the x-dimension. Must be even. Index number for the harmonic oscillator groundstate is 0.\nηs = (): a tuple of aspect ratios for the remaining dimensions (η_y, ...). Should be empty for a 1D trap or contain values greater than 1.0. The maximum index in other dimensions will be the largest even number less than M/η_y.\nS = nothing: Instead of max_nx, manually set the number of levels in each dimension, including the groundstate. Must be a Tuple of Ints.\ng = 1.0: the strength of the delta impurity in (x-dimension) trap units.\nimpurity_only=false: if set to true then the trap energy terms are ignored. Useful if only energy shifts due to the impurity are required.\n\nwarning: Warning\nDue to use of `SpecialFunctions` with large arguments the matrix representation of\nthis Hamiltonian may not be strictly symmetric, but is approximately symmetric within\nmachine precision.\n\nSee also HOCartesianContactInteractions andHOCartesianEnergyConservedPerDim.\n\n\n\n\n\n","category":"type"},{"location":"hamiltonians.html#Other-model-Hamiltonians","page":"Hamiltonians","title":"Other model Hamiltonians","text":"","category":"section"},{"location":"hamiltonians.html","page":"Hamiltonians","title":"Hamiltonians","text":"MatrixHamiltonian\nTranscorrelated1D\nFroehlichPolaron","category":"page"},{"location":"hamiltonians.html#Rimu.Hamiltonians.MatrixHamiltonian","page":"Hamiltonians","title":"Rimu.Hamiltonians.MatrixHamiltonian","text":"MatrixHamiltonian(\n mat::AbstractMatrix{T};\n starting_address::Int = starting_address(mat)\n) <: AbstractHamiltonian{T}\n\nWrap an abstract matrix mat as an AbstractHamiltonian object. Works with stochastic methods of ProjectorMonteCarloProblem() and DVec. Optionally, a valid index can be provided as the starting_address.\n\nSpecialised methods are implemented for sparse matrices of type AbstractSparseMatrixCSC. One based indexing is required for the matrix mat.\n\n\n\n\n\n","category":"type"},{"location":"hamiltonians.html#Rimu.Hamiltonians.Transcorrelated1D","page":"Hamiltonians","title":"Rimu.Hamiltonians.Transcorrelated1D","text":"Transcorrelated1D(address; t=1.0, v=1.0, v_ho=0.0, cutoff=1, three_body_term=true)\n\nImplements a transcorrelated Hamiltonian for contact interactions in one dimensional momentum space from Jeszenski et al. (2018). Currently limited to two component fermionic addresses.\n\nbeginaligned\n\ntildeH = t sum_kσk^2 n_kσ \n quad + sum_pqkσσ T_pqk a^_p-kσ a^_q+kσ a_qσ a_pσ \n quad + sum_pqskkσσ Q_kka^_p-kσ a^_q+kσ a^_s+k-kσ\n a_sσ a_qσ a_pσ \n quad + V_mathrmho\nendaligned\n\nwhere\n\nbeginaligned\ntildeu(k) = begincases -frac2k^2 mathrmif k k_c\n0 mathrmotherwise\nendcases\n\n\nT_pqk = fracvM + frac2vMleftk^2tildeu(k)\n - (p - q)ktildeu(k)right + frac2v^2tW(k)\nW(k) = frac1M^2sum_q (k - q)q tildeu(q)tildeu(k - q) \nQ_kl = -fracv^2t M^2k tildeu(k)ltildeu(l)\nendaligned\n\nArguments\n\naddress: The starting address, defines number of particles and sites.\nv: The interaction parameter.\nt: The kinetic energy prefactor.\nv_ho: Strength of the external harmonic oscillator potential V_mathrmho. See HubbardMom1DEP.\ncutoff controls k_c in equations above. Note: skipping generating off-diagonal elements below the cutoff is not implemented - zero-valued elements are returned instead.\nthree_body_term: If set to false, generating three body excitations is skipped. Note: when disabling three body terms, cutoff should be set to a higher value for best results.\n\nSee also\n\nHubbardMom1D\nHubbardMom1DEP\n\n\n\n\n\n","category":"type"},{"location":"hamiltonians.html#Rimu.Hamiltonians.FroehlichPolaron","page":"Hamiltonians","title":"Rimu.Hamiltonians.FroehlichPolaron","text":"FroehlichPolaron(address::OccupationNumberFS{M}; kwargs...) <: AbstractHamiltonian\n\nThe Froehlich polaron Hamiltonian for a 1D lattice with M momentum modes is given by\n\nH = (p_f - p)^2m + ωN - v Σₖ(aₖ^ + aₖ)\n\nwhere p is the total momentum, p_f = Σ_k k aₖ^ aₖ is the momentum operator for the bosons, and k part of the momentum lattice with separation 2πl. N is the number operator for the bosons.\n\nKeyword Arguments\n\np=0.0: the total momentum p.\nv=1.0: the coupling strength v.\nmass=1.0: the particle mass m.\nomega=1.0: the oscillation frequency of the phonons ω.\nl=1.0: the box size in real space l. Provides scale parameter of the momentum lattice.\nmomentum_cutoff=nothing: the maximum boson momentum allowed for an address.\nmode_cutoff: the maximum number of bosons in each momentum mode. Defaults to the maximum value supported by the address type OccupationNumberFS.\n\nExamples\n\njulia> fs = OccupationNumberFS(0,0,0)\nOccupationNumberFS{3, UInt8}(0, 0, 0)\n\njulia> ham = FroehlichPolaron(fs; v=0.5)\nFroehlichPolaron(fs\"|0 0 0⟩{8}\"; v=0.5, mass=1.0, omega=1.0, l=1.0, p=0.0, mode_cutoff=255)\n\njulia> dimension(ham)\n16777216\n\njulia> dimension(FroehlichPolaron(fs; v=0.5, mode_cutoff=5))\n216\n\nSee also OccupationNumberFS, dimension, AbstractHamiltonian.\n\n\n\n\n\n","category":"type"},{"location":"hamiltonians.html#Convenience-functions","page":"Hamiltonians","title":"Convenience functions","text":"","category":"section"},{"location":"hamiltonians.html","page":"Hamiltonians","title":"Hamiltonians","text":"rayleigh_quotient\nmomentum\nhubbard_dispersion\ncontinuum_dispersion\nshift_lattice\nshift_lattice_inv","category":"page"},{"location":"hamiltonians.html#Rimu.Hamiltonians.rayleigh_quotient","page":"Hamiltonians","title":"Rimu.Hamiltonians.rayleigh_quotient","text":"rayleigh_quotient(H, v)\n\nReturn the Rayleigh quotient of the linear operator H and the vector v:\n\nfrac v H v vv \n\n\n\n\n\n","category":"function"},{"location":"hamiltonians.html#Rimu.Hamiltonians.momentum","page":"Hamiltonians","title":"Rimu.Hamiltonians.momentum","text":"momentum(ham::AbstractHamiltonian)\n\nMomentum as a linear operator in Fock space. Pass a Hamiltonian ham in order to convey information about the Fock basis. Returns an AbstractHamiltonian that represents the momentum operator.\n\nNote: momentum is currently only defined on HubbardMom1D.\n\nExample\n\njulia> add = BoseFS((1, 0, 2, 1, 2, 1, 1, 3));\n\n\njulia> ham = HubbardMom1D(add; u = 2.0, t = 1.0);\n\n\njulia> mom = momentum(ham);\n\n\njulia> diagonal_element(mom, add) # calculate the momentum of a single configuration\n-1.5707963267948966\n\njulia> v = DVec(add => 10; capacity=1000);\n\n\njulia> rayleigh_quotient(mom, v) # momentum expectation value for state vector `v`\n-1.5707963267948966\n\nPart of the AbstractHamiltonian interface.\n\n\n\n\n\n","category":"function"},{"location":"hamiltonians.html#Rimu.Hamiltonians.hubbard_dispersion","page":"Hamiltonians","title":"Rimu.Hamiltonians.hubbard_dispersion","text":"hubbard_dispersion(t, k)\n\nDispersion relation for HubbardMom1D. Returns -2(Re(t) cos(k) + Im(t) sin(k)).\n\nSee also continuum_dispersion.\n\n\n\n\n\n","category":"function"},{"location":"hamiltonians.html#Rimu.Hamiltonians.continuum_dispersion","page":"Hamiltonians","title":"Rimu.Hamiltonians.continuum_dispersion","text":"continuum_dispersion(t, k)\n\nDispersion relation for HubbardMom1D. Returns Re(t) k^2 - 2 Im(t) k.\n\nSee also hubbard_dispersion.\n\n\n\n\n\n","category":"function"},{"location":"hamiltonians.html#Rimu.Hamiltonians.shift_lattice","page":"Hamiltonians","title":"Rimu.Hamiltonians.shift_lattice","text":"shift_lattice(is)\n\nCircular shift contiguous indices is in interval [M÷2, M÷2) such that set starts with 0, where M=length(is).\n\nInverse operation: shift_lattice_inv. Used in HubbardReal1DEP and HubbardMom1DEP\n\n\n\n\n\n","category":"function"},{"location":"hamiltonians.html#Rimu.Hamiltonians.shift_lattice_inv","page":"Hamiltonians","title":"Rimu.Hamiltonians.shift_lattice_inv","text":"shift_lattice_inv(js)\n\nCircular shift indices starting with 0 into a contiguous set in interval [M÷2, M÷2), where M=length(js).\n\nInverse operation of shift_lattice. Used in HubbardReal1DEP and HubbardMom1DEP\n\n\n\n\n\n","category":"function"},{"location":"hamiltonians.html#Hamiltonian-wrappers","page":"Hamiltonians","title":"Hamiltonian wrappers","text":"","category":"section"},{"location":"hamiltonians.html","page":"Hamiltonians","title":"Hamiltonians","text":"The following Hamiltonians are constructed from an existing Hamiltonian instance and change its behaviour:","category":"page"},{"location":"hamiltonians.html","page":"Hamiltonians","title":"Hamiltonians","text":"GutzwillerSampling\nGuidingVectorSampling\nParitySymmetry\nTimeReversalSymmetry\nStoquastic","category":"page"},{"location":"hamiltonians.html#Rimu.Hamiltonians.GutzwillerSampling","page":"Hamiltonians","title":"Rimu.Hamiltonians.GutzwillerSampling","text":"GutzwillerSampling(::AbstractHamiltonian; g)\n\nWrapper over any AbstractHamiltonian that implements Gutzwiller sampling. In this importance sampling scheme the Hamiltonian is modified as follows\n\ntildeH_ij = H_ij e^-g(H_ii - H_jj) \n\nThis way off-diagonal spawns to higher-energy configurations are discouraged and spawns to lower-energy configurations encouraged for positive g.\n\nConstructor\n\nGutzwillerSampling(::AbstractHamiltonian, g)\nGutzwillerSampling(::AbstractHamiltonian; g)\n\nAfter construction, we can access the underlying Hamiltonian with G.hamiltonian and the g parameter with G.g.\n\nExample\n\njulia> H = HubbardMom1D(BoseFS(1,1,1); u=6.0, t=1.0)\nHubbardMom1D(fs\"|1 1 1⟩\"; u=6.0, t=1.0)\n\njulia> G = GutzwillerSampling(H, g=0.3)\nGutzwillerSampling(HubbardMom1D(fs\"|1 1 1⟩\"; u=6.0, t=1.0); g=0.3)\n\njulia> get_offdiagonal(H, BoseFS(2, 1, 0), 1)\n(BoseFS{3,3}(1, 0, 2), 2.0)\n\njulia> get_offdiagonal(G, BoseFS(2, 1, 0), 1)\n(BoseFS{3,3}(1, 0, 2), 0.8131393194811987)\n\nObservables\n\nTo calculate observables, pass the transformed Hamiltonian G to AllOverlaps with keyword argument transform=G.\n\n\n\n\n\n","category":"type"},{"location":"hamiltonians.html#Rimu.Hamiltonians.GuidingVectorSampling","page":"Hamiltonians","title":"Rimu.Hamiltonians.GuidingVectorSampling","text":"GuidingVectorSampling\n\nWrapper over any AbstractHamiltonian that implements guided vector a.k.a. guided wave function sampling. In this importance sampling scheme the Hamiltonian is modified as follows.\n\ntildeH_ij = v_i H_ij v_j^-1\n\nand where v is the guiding vector. v_i and v_j are also thresholded to avoid dividing by zero (see below).\n\nConstructors\n\nGuidingVectorSampling(::AbstractHamiltonian, vector, eps)\nGuidingVectorSampling(::AbstractHamiltonian; vector, eps)\n\neps is a thresholding parameter used to avoid dividing by zero; all values below eps are set to eps. It is recommended that eps is in the same value range as the guiding vector. The default value is set to eps=norm(v, Inf) * 1e-2\n\nAfter construction, we can access the underlying hamiltonian with G.hamiltonian, the eps parameter with G.eps, and the guiding vector with G.vector.\n\nExample\n\njulia> H = HubbardReal1D(BoseFS(1,1,1); u=6.0, t=1.0);\n\njulia> v = DVec(starting_address(H) => 10; capacity=1);\n\njulia> G = GuidingVectorSampling(H, v, 0.1);\n\njulia> get_offdiagonal(H, starting_address(H), 4)\n(BoseFS{3,3}(2, 0, 1), -1.4142135623730951)\n\njulia> get_offdiagonal(G, starting_address(G), 4)\n(BoseFS{3,3}(2, 0, 1), -0.014142135623730952)\n\nObservables\n\nTo calculate observables, pass the transformed Hamiltonian G to AllOverlaps with keyword argument transform=G.\n\n\n\n\n\n","category":"type"},{"location":"hamiltonians.html#Rimu.Hamiltonians.ParitySymmetry","page":"Hamiltonians","title":"Rimu.Hamiltonians.ParitySymmetry","text":"ParitySymmetry(ham::AbstractHamiltonian{T}; even=true) <: AbstractHamiltonian{T}\n\nImpose even or odd parity on all states and the Hamiltonian ham as controlled by the keyword argument even. Parity symmetry of the Hamiltonian is assumed. For some Hamiltonians, ParitySymmetry reduces the size of the Hilbert space by half.\n\nParitySymmetry performs a unitary transformation, leaving the eigenvalues unchanged and preserving the LOStructure. This is achieved by changing the basis set to states with defined parity. Effectively, a non-even address α is replaced by frac12(α α) for even and odd parity, respectively, where ᾱ == reverse(α).\n\nNotes\n\nThis modifier currently only works on starting_addresss with an odd number of modes.\nFor odd parity, the starting_address of the underlying Hamiltonian cannot be symmetric.\nIf parity is not a symmetry of the Hamiltonian ham then the result is undefined.\nParitySymmetry works by modifying the offdiagonals iterator.\n\njulia> ham = HubbardReal1D(BoseFS(0,2,1))\nHubbardReal1D(fs\"|0 2 1⟩\"; u=1.0, t=1.0)\n\njulia> size(Matrix(ham))\n(10, 10)\n\njulia> size(Matrix(ParitySymmetry(ham)))\n(6, 6)\n\njulia> size(Matrix(ParitySymmetry(ham; odd=true)))\n(4, 4)\n\njulia> eigvals(Matrix(ham))[1] ≈ eigvals(Matrix(ParitySymmetry(ham)))[1]\ntrue\n\nSee also TimeReversalSymmetry.\n\n\n\n\n\n","category":"type"},{"location":"hamiltonians.html#Rimu.Hamiltonians.TimeReversalSymmetry","page":"Hamiltonians","title":"Rimu.Hamiltonians.TimeReversalSymmetry","text":"TimeReversalSymmetry(ham::AbstractHamiltonian{T}; even=true) <: AbstractHamiltonian{T}\n\nImpose even or odd time reversal on all states and the Hamiltonian ham as controlled by the keyword argument even. If time reversal is a symmetry of the Hamiltonian it will block (reducing Hilbert space dimension) preserving the eigenvalues and LOStructure.\n\nNotes\n\nThis modifier only works two component starting_addresses.\nFor odd time reversal symmetry, the starting_address of the underlying Hamiltonian must not be symmetric.\nIf time reversal is not a symmetry of the Hamiltonian ham then the result is undefined.\nTimeReversalSymmetry works by modifying the offdiagonals iterator.\n\njulia> ham = HubbardMom1D(FermiFS2C((1,0,1),(0,1,1)));\n\njulia> size(Matrix(ham))\n(3, 3)\n\njulia> size(Matrix(TimeReversalSymmetry(ham)))\n(2, 2)\n\njulia> size(Matrix(TimeReversalSymmetry(ham, even=false)))\n(1, 1)\n\njulia> eigvals(Matrix(TimeReversalSymmetry(ham)))[1] ≈ eigvals(Matrix(ham))[1]\ntrue\n\nSee also ParitySymmetry.\n\n\n\n\n\n","category":"type"},{"location":"hamiltonians.html#Rimu.Hamiltonians.Stoquastic","page":"Hamiltonians","title":"Rimu.Hamiltonians.Stoquastic","text":"Stoquastic(ham <: AbstractHamiltonian) <: AbstractHamiltonian\n\nA wrapper for an AbstractHamiltonian that replaces all off-diagonal matrix elements v by -abs(v), thus making the new Hamiltonian stoquastic.\n\nA stoquastic Hamiltonian does not have a Monte Carlo sign problem. For a hermitian ham the smallest eigenvalue of Stoquastic(ham) is ≤ the smallest eigenvalue of ham.\n\n\n\n\n\n","category":"type"},{"location":"hamiltonians.html#Observables","page":"Hamiltonians","title":"Observables","text":"","category":"section"},{"location":"hamiltonians.html","page":"Hamiltonians","title":"Hamiltonians","text":"Rimu.jl offers two other supertypes for operators that are less restrictive than AbstractHamiltonian. AbstractObservable and AbstractOperators both can represent a physical observable. Their expectation values can be sampled during a ProjectorMonteCarloProblem simulation by passing them into a suitable ReplicaStrategy, e.g. AllOverlaps. Some observables are also AbstractHamiltonians. The full type hierarchy is","category":"page"},{"location":"hamiltonians.html","page":"Hamiltonians","title":"Hamiltonians","text":"AbstractHamiltonian{T} <: AbstractOperator{T} <: AbstractObservable{T}","category":"page"},{"location":"hamiltonians.html","page":"Hamiltonians","title":"Hamiltonians","text":"ParticleNumberOperator\nG2RealCorrelator\nG2RealSpace\nG2MomCorrelator\nSuperfluidCorrelator\nStringCorrelator\nDensityMatrixDiagonal\nSingleParticleExcitation\nTwoParticleExcitation\nReducedDensityMatrix\nMomentum\nAxialAngularMomentumHO","category":"page"},{"location":"hamiltonians.html#Rimu.Hamiltonians.ParticleNumberOperator","page":"Hamiltonians","title":"Rimu.Hamiltonians.ParticleNumberOperator","text":"ParticleNumberOperator() <: AbstractOperator{Float64}\n\nThe number operator in Fock space. This operator is diagonal in the Fock basis and returns the number of particles in the Fock state. It works with any address type that is a subtype of AbstractFockAddress.\n\njulia> p = ExactDiagonalizationProblem(FroehlichPolaron(fs\"|0 0⟩{}\"; mode_cutoff=5, v=3));\n\njulia> gs = solve(p).vectors[1]; # normalised ground state vector\n\njulia> dot(gs, ParticleNumberOperator(), gs) # particle number expectation value\n2.8823297252925917\n\nSee also AbstractHamiltonian.\n\n\n\n\n\n","category":"type"},{"location":"hamiltonians.html#Rimu.Hamiltonians.G2RealCorrelator","page":"Hamiltonians","title":"Rimu.Hamiltonians.G2RealCorrelator","text":"G2RealCorrelator(d::Int) <: AbstractOperator{Float64}\n\nTwo-body operator for density-density correlation between sites separated by d with 0 ≤ d < M.\n\n hatG^(2)(d) = frac1M sum_i^M hatn_i (hatn_i+d - delta_0d)\n\nAssumes a one-dimensional lattice with periodic boundary conditions where\n\n hatG^(2)(-M2 leq d 0) = hatG^(2)(d)\n\n hatG^(2)(M2 d M) = hatG^(2)(M - d)\n\nand normalisation\n\n sum_d=0^M-1 langle hatG^(2)(d) rangle = fracN (N-1)M\n\nFor multicomponent basis, calculates correlations between all particles equally, equivalent to stacking all components into a single Fock state.\n\nArguments\n\nd::Integer: distance between sites.\n\nSee also\n\nHubbardReal1D\nG2RealSpace\nG2MomCorrelator\nAbstractOperator\nAllOverlaps\n\n\n\n\n\n","category":"type"},{"location":"hamiltonians.html#Rimu.Hamiltonians.G2RealSpace","page":"Hamiltonians","title":"Rimu.Hamiltonians.G2RealSpace","text":"G2RealSpace(geometry::CubicGrid, σ=1, τ=1; sum_components=false) <: AbstractOperator{SArray}\n\nTwo-body operator for density-density correlation for all Displacements d in the specified geometry.\n\n hatG^(2)_στ(d) = frac1M _i n_σi (n_τi+d - δ_0dδ_στ)\n\nFor multicomponent addresses, σ and τ control the components involved. Alternatively, sum_components can be set to true, which treats all particles as belonging to the same component.\n\nExamples\n\njulia> geom = CubicGrid(2, 2);\n\njulia> g2 = G2RealSpace(geom)\nG2RealSpace(CubicGrid((2, 2), (true, true)), 1,1)\n\njulia> diagonal_element(g2, BoseFS(2,0,1,1))\n2×2 StaticArraysCore.SMatrix{2, 2, Float64, 4} with indices SOneTo(2)×SOneTo(2):\n 0.5 1.0\n 0.5 1.0\n\njulia> g2_cross = G2RealSpace(geom, 1, 2)\nG2RealSpace(CubicGrid((2, 2), (true, true)), 1,2)\n\njulia> g2_sum = G2RealSpace(geom, sum_components=true)\nG2RealSpace(CubicGrid((2, 2), (true, true)); sum_components=true)\n\njulia> diagonal_element(g2, fs\"|⇅⋅↓↑⟩\")\n2×2 StaticArraysCore.SMatrix{2, 2, Float64, 4} with indices SOneTo(2)×SOneTo(2):\n 0.0 0.0\n 0.0 0.5\n\njulia> diagonal_element(g2_cross, fs\"|⇅⋅↓↑⟩\")\n2×2 StaticArraysCore.SMatrix{2, 2, Float64, 4} with indices SOneTo(2)×SOneTo(2):\n 0.25 0.25\n 0.25 0.25\n\njulia> diagonal_element(g2_sum, fs\"|⇅⋅↓↑⟩\")\n2×2 StaticArraysCore.SMatrix{2, 2, Float64, 4} with indices SOneTo(2)×SOneTo(2):\n 0.5 1.0\n 0.5 1.0\n\nSee also\n\nCubicGrid\nHubbardRealSpace\nG2RealCorrelator\nG2MomCorrelator\nAbstractOperator\nAllOverlaps\n\n\n\n\n\n","category":"type"},{"location":"hamiltonians.html#Rimu.Hamiltonians.G2MomCorrelator","page":"Hamiltonians","title":"Rimu.Hamiltonians.G2MomCorrelator","text":"G2MomCorrelator(d::Int) <: AbstractOperator{ComplexF64}\n\nTwo-body correlation operator representing the density-density correlation at distance d. It returns a Complex value.\n\nCorrelation within a single component:\n\nhatG^(2)(d) = frac1Msum_spqr=1^M e^-id(p-q)2πM a^_s a^_p a_q a_r δ_s+pq+r\n\nThe diagonal element, where (p-q)=0, is\n\nfrac1Msum_kp=1^M a^_k b^_p b_p a_k \n\nArguments\n\nd::Integer: the distance between two particles.\n\nSee also\n\nRimu.G2RealCorrelator\nRimu.G2RealSpace\nRimu.AbstractOperator\nRimu.AllOverlaps\n\n\n\n\n\n","category":"type"},{"location":"hamiltonians.html#Rimu.Hamiltonians.SuperfluidCorrelator","page":"Hamiltonians","title":"Rimu.Hamiltonians.SuperfluidCorrelator","text":"SuperfluidCorrelator(d::Int) <: AbstractOperator{Float64}\n\nOperator for extracting superfluid correlation between sites separated by a distance d with 0 ≤ d < M:\n\n hatC_textSF(d) = frac1M sum_i^M a_i^dagger a_i + d\n\nAssumes a one-dimensional lattice with M sites and periodic boundary conditions. M is also the number of modes in the Fock state address.\n\nUsage\n\nSuperfluid correlations can be extracted from a Monte Carlo calculation by wrapping SuperfluidCorrelator with AllOverlaps and passing into ProjectorMonteCarloProblem with the replica keyword argument. For an example with a similar use of G2RealCorrelator see G2 Correlator Example.\n\nSee also HubbardReal1D, G2RealCorrelator, AbstractOperator, and AllOverlaps.\n\n\n\n\n\n","category":"type"},{"location":"hamiltonians.html#Rimu.Hamiltonians.StringCorrelator","page":"Hamiltonians","title":"Rimu.Hamiltonians.StringCorrelator","text":"StringCorrelator(d::Int; address=nothing, type=nothing) <: AbstractOperator{T}\n\nOperator for extracting string correlation between lattice sites on a one-dimensional Hubbard lattice separated by a distance d with 0 ≤ d < M\n\n C_textstring(d) = frac1M sum_j^M δ n_j\n (e^i π sum_j k j + d δ n_k) δ n_j+d\n\nHere, δ n_j = n_j - n is the boson number deviation from the mean filling number and n = NM is the mean filling number of lattice sites with N particles and M lattice sites (or modes).\n\nAssumes a one-dimensional lattice with periodic boundary conditions. For usage see SuperfluidCorrelator and AllOverlaps.\n\nThe default element type T is ComplexF64. This can be overridden with the type keyword argument. If an address is provided, then T is calculated from the address type. It is set to ComplexF64 for non-integer filling numbers, and to Float64 for integer filling numbers or if d==0.\n\nSee also HubbardReal1D, G2RealCorrelator, SuperfluidCorrelator, AbstractOperator, and AllOverlaps.\n\n\n\n\n\n","category":"type"},{"location":"hamiltonians.html#Rimu.Hamiltonians.DensityMatrixDiagonal","page":"Hamiltonians","title":"Rimu.Hamiltonians.DensityMatrixDiagonal","text":"DensityMatrixDiagonal(mode; component=0) <: AbstractHamiltonian\n\nRepresent a diagonal element of the single-particle density:\n\nhatn_iσ = hat a^_iσ hat a_iσ\n\nwhere i is the mode and σ is the component. If component is zero, the sum over all components is computed.\n\nSee also\n\nsingle_particle_density\nSingleParticleDensity\nSingleParticleExcitation\n\n\n\n\n\n","category":"type"},{"location":"hamiltonians.html#Rimu.Hamiltonians.SingleParticleExcitation","page":"Hamiltonians","title":"Rimu.Hamiltonians.SingleParticleExcitation","text":"SingleParticleExcitation(i, j) <: AbstractOperator\n\nRepresent the ij element of the single-particle reduced density matrix:\n\nρ^(1)_ij = a^_i a_j\n\nwhere i <: Int and j <: Int specify the mode numbers.\n\nSee also\n\nsingle_particle_density\nSingleParticleDensity\nTwoParticleExcitation\n\n\n\n\n\n","category":"type"},{"location":"hamiltonians.html#Rimu.Hamiltonians.TwoParticleExcitation","page":"Hamiltonians","title":"Rimu.Hamiltonians.TwoParticleExcitation","text":"TwoParticleExcitation(i, j, k, l) <: AbstractOperator\n\nRepresent the ij kl element of the two-particle reduced density matrix:\n\nρ^(2)_ij kl = a^_i a^_j a_l a_k\n\nwhere i, j, k, and l (all <: Int) specify the mode numbers.\n\nSee also\n\nsingle_particle_density\nSingleParticleDensity\nSingleParticleExcitation\n\n\n\n\n\n","category":"type"},{"location":"hamiltonians.html#Rimu.Hamiltonians.ReducedDensityMatrix","page":"Hamiltonians","title":"Rimu.Hamiltonians.ReducedDensityMatrix","text":"ReducedDensityMatrix{T=Float64}(p) <: AbstractObservable{Hermitian{T, Matrix{T}}}\n\nA matrix-valued operator that can be used to calculate the p-particle reduced density matrix. The matrix elements are defined as:\n\nhatρ^(p)_j_1j_1k_1k_p = prod_i=1^p a^_j_i prod_l=p^1 a_k_l\n\nThe integer indices j_i and k_i represent single particle modes. For efficiency they are chosen to be distinct and ordered:\n\nj_1 j_2 ldots j_p quad land quad k_1 k_2 ldots k_p\n\nReducedDensityMatrix can be used to construct the single-particle reduced density matrix (with p == 1) for fermionic and bosonic Fock spaces with address types <: SingleComponentFockAddress. For higher order reduced density matrices with p > 1 only fermionic Fock addresses (FermiFS) are supported due to the ordering of indices.\n\nReducedDensityMatrix can be used with dot or AllOverlaps to calculate the whole matrix in one go.\n\nExamples\n\njulia> dvec_b = PDVec(BoseFS(1,1) => 0.5, BoseFS(2,0) => 0.5)\n2-element PDVec: style = IsDeterministic{Float64}()\n fs\"|2 0⟩\" => 0.5\n fs\"|1 1⟩\" => 0.5\n\njulia> Op1 = ReducedDensityMatrix(1)\nReducedDensityMatrix{Float64}(1)\n\njulia> dot(dvec_b, Op1, dvec_b)\n2×2 Hermitian{Float64, Matrix{Float64}}:\n 0.75 0.353553\n 0.353553 0.25\n\njulia> Op2 = ReducedDensityMatrix{Float32}(2)\nReducedDensityMatrix{Float32}(2)\n\njulia> dot(dvec_b, Op2, dvec_b)\nERROR: ArgumentError: ReducedDensityMatrix(p) with `p > 1` requires `FermiFS` addresses\n\njulia> dvec_f = PDVec(FermiFS(1,1,0,0) => 0.5, FermiFS(0,1,1,0) => 0.5)\n2-element PDVec: style = IsDeterministic{Float64}()\n fs\"|⋅↑↑⋅⟩\" => 0.5\n fs\"|↑↑⋅⋅⟩\" => 0.5\n\njulia> dot(dvec_f, Op2, dvec_f)\n6×6 Hermitian{Float32, Matrix{Float32}}:\n 0.25 0.0 0.25 0.0 0.0 0.0\n 0.0 0.0 0.0 0.0 0.0 0.0\n 0.25 0.0 0.25 0.0 0.0 0.0\n 0.0 0.0 0.0 0.0 0.0 0.0\n 0.0 0.0 0.0 0.0 0.0 0.0\n 0.0 0.0 0.0 0.0 0.0 0.0\n\nSee also single_particle_density, SingleParticleDensity, SingleParticleExcitation, TwoParticleExcitation.\n\n\n\n\n\n","category":"type"},{"location":"hamiltonians.html#Rimu.Hamiltonians.Momentum","page":"Hamiltonians","title":"Rimu.Hamiltonians.Momentum","text":"Momentum(component=0; fold=true) <: AbstractHamiltonian\n\nThe momentum operator P.\n\nThe component argument controls which component of the address is taken into consideration. A value of 0 sums the contributions of all components. If fold is true, the momentum is folded into the Brillouin zone.\n\njulia> address = BoseFS((1, 0, 2, 1, 2, 1, 1, 3))\nBoseFS{11,8}(1, 0, 2, 1, 2, 1, 1, 3)\n\njulia> v = DVec(address => 10);\n\njulia> rayleigh_quotient(Momentum(), DVec(address => 1))\n-2.0\n\njulia> rayleigh_quotient(Momentum(fold=false), DVec(address => 1))\n14.0\n\n\n\n\n\n","category":"type"},{"location":"hamiltonians.html#Rimu.Hamiltonians.AxialAngularMomentumHO","page":"Hamiltonians","title":"Rimu.Hamiltonians.AxialAngularMomentumHO","text":"AxialAngularMomentumHO(S; z_dim = 3, addr = BoseFS(prod(S))) <: AbstractHamiltonian\n\nAngular momentum operator for application to Cartesian harmonic oscillator basis, see HOCartesianContactInteractions or HOCartesianEnergyConservedPerDim. Represents the projection of angular momentum onto z-axis:\n\nhatL_z = i hbar sum_j=1^N left( b_x b_y^dag - b_y b_x^dag right)\n\nwhere b_x^dag and b_x are raising and lowering (ladder) operators for a harmonic oscillator in the x dimension, and simlarly for y.\n\nThis is implemented for an N particle Fock space with creation and annihilation operators as\n\nfrac1hbar hatL_z = i sum_n_x=1^M_x sum_n_y=1^M_y\n left( a_n_x-1n_y+1^dag - a_n_x+1n_y-1^dag right) a_n_x n_y\n\nin units of hbar.\n\nArgument S is a tuple defining the range of Cartesian modes in each dimension and their mapping to Fock space modes in a SingleComponentFockAddress. If S indicates a 3D system the z dimension can be changed by setting z_dim; S should be be isotropic in the remaining x-y plane, i.e. must have S[x_dim] == S[y_dim]. The starting address addr only needs to satisfy num_modes(addr) == prod(S).\n\nExample\n\nCalculate the overlap of two Fock addresses interpreted as harmonic oscillator states in a 2D Cartesian basis\n\njulia> S = (2,2)\n(2, 2)\n\njulia> Lz = AxialAngularMomentumHO(S)\nAxialAngularMomentumHO((2, 2); z_dim = 3, addr = BoseFS{0,4}(0, 0, 0, 0))\n\njulia> v = DVec(BoseFS(prod(S), 2 => 1) => 1.0)\nDVec{BoseFS{1, 4, BitString{4, 1, UInt8}},Float64} with 1 entry, style = IsDeterministic{Float64}()\n fs\"|0 1 0 0⟩\" => 1.0\n\njulia> w = DVec(BoseFS(prod(S), 3 => 1) => 1.0)\nDVec{BoseFS{1, 4, BitString{4, 1, UInt8}},Float64} with 1 entry, style = IsDeterministic{Float64}()\n fs\"|0 0 1 0⟩\" => 1.0\n\njulia> dot(w, Lz, v)\n0.0 + 1.0im\n\n\n\n\n\n","category":"type"},{"location":"hamiltonians.html#Geometry","page":"Hamiltonians","title":"Geometry","text":"","category":"section"},{"location":"hamiltonians.html","page":"Hamiltonians","title":"Hamiltonians","text":"Lattices in higher dimensions are defined here and can be passed with the keyword argument geometry to HubbardRealSpace and G2RealSpace.","category":"page"},{"location":"hamiltonians.html","page":"Hamiltonians","title":"Hamiltonians","text":"CubicGrid\nHamiltonians.Directions\nHamiltonians.Displacements\nHamiltonians.neighbor_site\nPeriodicBoundaries\nHardwallBoundaries\nLadderBoundaries","category":"page"},{"location":"hamiltonians.html#Rimu.Hamiltonians.CubicGrid","page":"Hamiltonians","title":"Rimu.Hamiltonians.CubicGrid","text":"CubicGrid(dims::NTuple{D,Int}, fold::NTuple{D,Bool})\n\nRepresents a D-dimensional grid. Used to define a cubic lattice and boundary conditions for some AbstractHamiltonians, e.g. with the keyword argument geometry when constructing a HubbardRealSpace. The type instance can be used to convert between cartesian vector indices (tuples or SVectors) and linear indices (integers). When indexed with vectors, it folds them back into the grid if the out-of-bounds dimension is periodic and 0 otherwise (see example below).\n\ndims controls the size of the grid in each dimension.\nfold controls whether the boundaries in each dimension are periodic (or folded in the case of momentum space).\n\njulia> geo = CubicGrid((2,3), (true,false))\nCubicGrid{2}((2, 3), (true, false))\n\njulia> geo[1]\n(1, 1)\n\njulia> geo[2]\n(2, 1)\n\njulia> geo[3]\n(1, 2)\n\njulia> geo[(1,2)]\n3\n\njulia> geo[(3,2)] # 3 is folded back into 1\n3\n\njulia> geo[(3,3)]\n5\n\njulia> geo[(3,4)] # returns 0 if out of bounds\n0\n\nSee also PeriodicBoundaries, HardwallBoundaries and LadderBoundaries for special-case constructors. See also HubbardRealSpace and G2RealSpace.\n\n\n\n\n\n","category":"type"},{"location":"hamiltonians.html#Rimu.Hamiltonians.Directions","page":"Hamiltonians","title":"Rimu.Hamiltonians.Directions","text":"Directions(D) <: AbstractVector{SVector{D,Int}}\nDirections(geometry::CubicGrid) <: AbstractVector{SVector{D,Int}}\n\nIterate over axis-aligned direction vectors in D dimensions.\n\njulia> Directions(3)\n6-element Directions{3}:\n [1, 0, 0]\n [0, 1, 0]\n [0, 0, 1]\n [-1, 0, 0]\n [0, -1, 0]\n [0, 0, -1]\n\n\nSee also CubicGrid.\n\n\n\n\n\n","category":"type"},{"location":"hamiltonians.html#Rimu.Hamiltonians.Displacements","page":"Hamiltonians","title":"Rimu.Hamiltonians.Displacements","text":"Displacements(geometry::CubicGrid) <: AbstractVector{SVector{D,Int}}\n\nReturn all valid offset vectors in a CubicGrid. If center=true the (0,0) displacement is placed at the centre of the array.\n\njulia> geometry = CubicGrid((3,4));\n\njulia> reshape(Displacements(geometry), (3,4))\n3×4 reshape(::Displacements{2, CubicGrid{2, (3, 4), (true, true)}}, 3, 4) with eltype StaticArraysCore.SVector{2, Int64}:\n [0, 0] [0, 1] [0, 2] [0, 3]\n [1, 0] [1, 1] [1, 2] [1, 3]\n [2, 0] [2, 1] [2, 2] [2, 3]\n\njulia> reshape(Displacements(geometry; center=true), (3,4))\n3×4 reshape(::Displacements{2, CubicGrid{2, (3, 4), (true, true)}}, 3, 4) with eltype StaticArraysCore.SVector{2, Int64}:\n [-1, -1] [-1, 0] [-1, 1] [-1, 2]\n [0, -1] [0, 0] [0, 1] [0, 2]\n [1, -1] [1, 0] [1, 1] [1, 2]\n\n\n\n\n\n\n","category":"type"},{"location":"hamiltonians.html#Rimu.Hamiltonians.neighbor_site","page":"Hamiltonians","title":"Rimu.Hamiltonians.neighbor_site","text":"neighbor_site(geom::CubicGrid, site, i)\n\nFind the i-th neighbor of site in the geometry. If the move is illegal, return 0.\n\nSee also CubicGrid.\n\n\n\n\n\n","category":"function"},{"location":"hamiltonians.html#Rimu.Hamiltonians.PeriodicBoundaries","page":"Hamiltonians","title":"Rimu.Hamiltonians.PeriodicBoundaries","text":"PeriodicBoundaries(dims...) -> CubicGrid\nPeriodicBoundaries(dims) -> CubicGrid\n\nReturn a CubicGrid with all dimensions periodic. Equivalent to CubicGrid(dims).\n\n\n\n\n\n","category":"function"},{"location":"hamiltonians.html#Rimu.Hamiltonians.HardwallBoundaries","page":"Hamiltonians","title":"Rimu.Hamiltonians.HardwallBoundaries","text":"HardwallBoundaries(dims...) -> CubicGrid\nHardwallBoundaries(dims) -> CubicGrid\n\nReturn a CubicGrid with all dimensions non-periodic. Equivalent to CubicGrid(dims, (false, false, ...)).\n\n\n\n\n\n","category":"function"},{"location":"hamiltonians.html#Rimu.Hamiltonians.LadderBoundaries","page":"Hamiltonians","title":"Rimu.Hamiltonians.LadderBoundaries","text":"LadderBoundaries(dims...) -> CubicGrid\nLadderBoundaries(dims) -> CubicGrid\n\nReturn a CubicGrid where the first dimension is dimensions non-periodic and the rest are periodic. Equivalent to CubicGrid(dims, (true, false, ...)).\n\n\n\n\n\n","category":"function"},{"location":"hamiltonians.html#Index","page":"Hamiltonians","title":"Index","text":"","category":"section"},{"location":"hamiltonians.html","page":"Hamiltonians","title":"Hamiltonians","text":"Pages = [\"hamiltonians.md\"]","category":"page"},{"location":"testing.html#Code-testing","page":"Code testing","title":"Code testing","text":"","category":"section"},{"location":"testing.html","page":"Code testing","title":"Code testing","text":"The script runtest.jl in the test/ folder contains tests of the code in Rimu. To run the test simply run the script from the Julia REPL or run","category":"page"},{"location":"testing.html","page":"Code testing","title":"Code testing","text":"Rimu$ julia test/runtest.jl","category":"page"},{"location":"testing.html","page":"Code testing","title":"Code testing","text":"from the command line.","category":"page"},{"location":"testing.html","page":"Code testing","title":"Code testing","text":"More tests should be added over time to test core functionality of the code. To add new tests, directly edit the file runtest.jl.","category":"page"},{"location":"testing.html#Automated-testing-with-GitHub-Actions","page":"Code testing","title":"Automated testing with GitHub Actions","text":"","category":"section"},{"location":"testing.html","page":"Code testing","title":"Code testing","text":"GitHub Actions are set up to run the test script automatically on the GitHub cloud server every time a new commit to the master branch is pushed to the server. The setup for this to happen is configured in the file actions.yml in the Rimu/.github/workflows folder.","category":"page"},{"location":"testing.html#Testing-of-custom-types-for-use-with-Rimu","page":"Code testing","title":"Testing of custom types for use with Rimu","text":"","category":"section"},{"location":"testing.html","page":"Code testing","title":"Code testing","text":"The module Rimu.InterfaceTests contains a number of functions to test the interfaces of the AbstractHamiltonian type hierarchy. See Interface tests in the section Advanced operator usage and custom Hamiltonians.","category":"page"},{"location":"exactdiagonalization.html#Exact-Diagonalization","page":"Exact Diagonalization","title":"Exact Diagonalization","text":"","category":"section"},{"location":"exactdiagonalization.html","page":"Exact Diagonalization","title":"Exact Diagonalization","text":"The main functionality of Rimu for exact diagonalization is contained in the module ExactDiagonalization.","category":"page"},{"location":"exactdiagonalization.html","page":"Exact Diagonalization","title":"Exact Diagonalization","text":"ExactDiagonalization","category":"page"},{"location":"exactdiagonalization.html#Rimu.ExactDiagonalization","page":"Exact Diagonalization","title":"Rimu.ExactDiagonalization","text":"The module Rimu.ExactDiagonalization provides a framework for exact diagonalization of quantum many-body systems defined by an AbstractHamiltonian type.\n\nThe main usage is through defining an ExactDiagonalizationProblem and solving it with the solve function. The module provides a unified interface for accessing different solver algorithms, which make use of solvers provided by external packages.\n\nExports\n\nExactDiagonalizationProblem\nBasisSetRepresentation\nbuild_basis\nKrylovKitSolver\nLinearAlgebraSolver\nArpackSolver\nLOBPCGSolver\n\n\n\n\n\n","category":"module"},{"location":"exactdiagonalization.html#ExactDiagonalizationProblem","page":"Exact Diagonalization","title":"ExactDiagonalizationProblem","text":"","category":"section"},{"location":"exactdiagonalization.html","page":"Exact Diagonalization","title":"Exact Diagonalization","text":"ExactDiagonalizationProblem\nsolve(::ExactDiagonalizationProblem)\ninit(::ExactDiagonalizationProblem)","category":"page"},{"location":"exactdiagonalization.html#Rimu.ExactDiagonalization.ExactDiagonalizationProblem","page":"Exact Diagonalization","title":"Rimu.ExactDiagonalization.ExactDiagonalizationProblem","text":"ExactDiagonalizationProblem(hamiltonian::AbstractHamiltonian, [v0]; kwargs...)\n\nDefines an exact diagonalization problem with an AbstractHamiltonian hamiltonian. Optionally, a starting vector of type AbstractDVec, or a single address or a collection of addresses can be passed as v0.\n\nExactDiagonalizationProblems can be solved with solve.\n\nKeyword arguments\n\nalgorithm=LinearAlgebraSolver(): The algorithm to use for solving the problem. The algorithm can also be specified as the second positional argument in the init function.\nOptional keyword arguments will be passed on to the init and solve functions.\n\nAlgorithms\n\nLinearAlgebraSolver(): An algorithm for solving the problem using the dense-matrix eigensolver from the LinearAlgebra standard library (eventually using LAPACK). Only suitable for small matrices.\nKrylovKitSolver(matrix_free=true): An algorithm for finding a few eigenvalues and vectors. With matrix_free=true the problem is solved without instatiating a matrix. This is suitable for large dimensions. With matrix_free=false the problem is solved after instantiating a sparse matrix. This is faster if sufficient memory is available. Requires using KrylovKit.\nArpackSolver(): An algorithm for solving the problem after instantiating a sparse matrix and using the Arpack Fortran library. Requires using Arpack.\nLOBPCGSolver(): An algorithm for solving the problem after instantiating a sparse matrix using the LOBPCG method. Requires using IterativeSolvers.\n\nKeyword arguments for matrix-based algorithms (also accepted by init)\n\nSee BasisSetRepresentation for more information.\n\nsizelim: The maximum size of the basis set representation. The default is 10^6 for sparse matrices and 10^5 for dense matrices.\ncutoff: A cutoff value for the basis set representation.\nfilter: A filter function for the basis set representation.\nmax_depth = Inf: Limit the depth when building the matrix.\nminimum_size = Inf: Stop building the matrix after this size is reached.\nnnzs = 0: A hint for the number of non-zero elements in the basis set representation. Setting a non-zero value can speed up the computation.\ncol_hint = 0: A hint for the number of columns in the basis set representation.\nsort = false: Whether to sort the basis set representation.\n\nKeyword arguments for iterative algorithms (also accepted by solve)\n\nverbose = false: Whether to print additional information.\nabstol = nothing: The absolute tolerance for the solver. If nothing, the solver chooses a default value.\nhowmany = 1: The minimum number of eigenvalues to compute.\nwhich = :SR: Whether to compute the largest or smallest eigenvalues.\nmaxiters = nothing: The maximum number of iterations for the solver. If nothing, the solver chooses a default value.\n\nSolving an ExactDiagonalizationProblem\n\nThe solve function can be called directly on an ExactDiagonalizationProblem to solve it. Alternatively, the init function can be used to initialize a solver, which can then be solved with solve. The solve function returns a result type with the eigenvalues, eigenvectors, and convergence information.\n\nResult type\n\nThe result type for the solve function is determined by the algorithm used. It has the following fields:\n\nvalues::Vector: The eigenvalues.\nvectors::Vector{<:AbstractDVec}: The eigenvectors.\nsuccess::Bool: A boolean flag indicating whether the solver was successful.\ninfo: Convergence information.\nalgorithm: The algorithm used for the computation.\nproblem: The ExactDiagonalizationProblem that was solved.\nAdditional fields may be present depending on the algorithm used.\n\nIterating the result type will yield the eigenvalues, eigenvectors, and a boolean flag success in that order.\n\nExamples\n\njulia> p = ExactDiagonalizationProblem(HubbardReal1D(BoseFS(1,1,1)))\nExactDiagonalizationProblem(\n HubbardReal1D(fs\"|1 1 1⟩\"; u=1.0, t=1.0),\n nothing;\n NamedTuple()...\n)\n\njulia> result = solve(p) # convert to dense matrix and solve with LinearAlgebra.eigen\nEDResult for algorithm LinearAlgebraSolver() with 10 eigenvalue(s),\n values = [-5.09593, -1.51882, -1.51882, 1.55611, 1.6093, 1.6093, 4.0, 4.53982, 4.90952, 4.90952],\n and vectors of length 10.\n Convergence info: \"Dense matrix eigensolver solution from `LinearAlgebra.eigen`\", with howmany = 10 eigenvalues requested.\n success = true.\n\njulia> using KrylovKit # an external package has to be installed and loaded\n\njulia> s = init(p; algorithm = KrylovKitSolver(true)) # solve without building a matrix\nKrylovKitDirectEDSolver\n with algorithm KrylovKitSolver(matrix_free = true,) for hamiltonian = HubbardReal1D(fs\"|1 1 1⟩\"; u=1.0, t=1.0),\n v0 = 1-element PDVec: style = IsDeterministic{Float64}()\n fs\"|1 1 1⟩\" => 1.0,\n kwargs = NamedTuple()\n)\n\njulia> values, vectors, success = solve(s);\n\njulia> result.values[1] ≈ values[1]\ntrue\n\nSee also solve(::ExactDiagonalizationProblem), init(::ExactDiagonalizationProblem), KrylovKitSolver, ArpackSolver, LinearAlgebraSolver.\n\nnote: Note\nUsing the KrylovKitSolver() algorithms requires the KrylovKit.jl package. The package can be loaded with using KrylovKit. Using the ArpackSolver() algorithm requires the Arpack.jl package. The package can be loaded with using Arpack. Using the LOBPCGSolver() algorithm requires the IterativeSolvers.jl package. The package can be loaded with using IterativeSolvers.\n\n\n\n\n\n","category":"type"},{"location":"exactdiagonalization.html#CommonSolve.solve-Tuple{ExactDiagonalizationProblem}","page":"Exact Diagonalization","title":"CommonSolve.solve","text":"solve(p::ExactDiagonalizationProblem, [algorithm]; kwargs...)\n\nSolve an ExactDiagonalizationProblem p directly. Optionally specify an algorithm. Returns a result type with the eigenvalues, eigenvectors, and convergence information.\n\nFor a description of the keyword arguments, see the documentation for ExactDiagonalizationProblem.\n\nSee also solve(::ProjectorMonteCarloProblem).\n\n\n\n\n\n","category":"method"},{"location":"exactdiagonalization.html#CommonSolve.init-Tuple{ExactDiagonalizationProblem}","page":"Exact Diagonalization","title":"CommonSolve.init","text":"init(p::ExactDiagonalizationProblem, [algorithm]; kwargs...)\n\nInitialize a solver for an ExactDiagonalizationProblem p with an optional algorithm. Returns a solver instance that can be solved with solve.\n\nFor a description of the keyword arguments, see the documentation for ExactDiagonalizationProblem.\n\n\n\n\n\n","category":"method"},{"location":"exactdiagonalization.html#Solver-algorithms","page":"Exact Diagonalization","title":"Solver algorithms","text":"","category":"section"},{"location":"exactdiagonalization.html","page":"Exact Diagonalization","title":"Exact Diagonalization","text":"KrylovKitSolver\nLinearAlgebraSolver\nArpackSolver\nLOBPCGSolver","category":"page"},{"location":"exactdiagonalization.html#Rimu.ExactDiagonalization.KrylovKitSolver","page":"Exact Diagonalization","title":"Rimu.ExactDiagonalization.KrylovKitSolver","text":"KrylovKitSolver(matrix_free::Bool; kwargs...)\nKrylovKitSolver(; matrix_free = false, kwargs...)\n\nAlgorithm for solving a large ExactDiagonalizationProblem to find a few eigenvalues and vectors using the KrylovKit.jl package. The Lanczos method is used for hermitian matrices, and the Arnoldi method is used for non-hermitian matrices.\n\nArguments\n\nmatrix_free = false: Whether to use a matrix-free algorithm. If false, a sparse matrix will be instantiated. This is typically faster and recommended for small matrices, but requires more memory. If true, the matrix is not instantiated, which is useful for large matrices that would not fit into memory. The calculation will parallelise using threading and MPI if available by making use of PDVec.\nkwargs: Additional keyword arguments are passed on to the function KrylovKit.eigsolve().\n\nSee also ExactDiagonalizationProblem, solve.\n\nnote: Note\nRequires the KrylovKit.jl package to be loaded with using KrylovKit.\n\n\n\n\n\n","category":"type"},{"location":"exactdiagonalization.html#Rimu.ExactDiagonalization.LinearAlgebraSolver","page":"Exact Diagonalization","title":"Rimu.ExactDiagonalization.LinearAlgebraSolver","text":"LinearAlgebraSolver(; kwargs...)\n\nAlgorithm for solving an ExactDiagonalizationProblem using the dense-matrix eigensolver from the LinearAlgebra standard library. This is only suitable for small matrices.\n\nThe kwargs are passed on to function LinearAlgebra.eigen.\n\nKeyword arguments\n\npermute = true: Whether to permute the matrix before diagonalization.\nscale = true: Whether to scale the matrix before diagonalization.\nsortby: The sorting order for the eigenvalues.\n\nSee also ExactDiagonalizationProblem, solve.\n\n\n\n\n\n","category":"type"},{"location":"exactdiagonalization.html#Rimu.ExactDiagonalization.ArpackSolver","page":"Exact Diagonalization","title":"Rimu.ExactDiagonalization.ArpackSolver","text":"ArpackSolver(; kwargs...)\n\nAlgorithm for solving an ExactDiagonalizationProblem after instantiating a sparse matrix. It uses the Lanzcos method for hermitian problems, and the Arnoldi method for non-hermitian problems, using the Arpack Fortran library. This is faster than KrylovKitSolver(; matrix_free=true), but it requires more memory and will only be useful if the matrix fits into memory.\n\nThe kwargs are passed on to the function Arpack.eigs().\n\nSee also ExactDiagonalizationProblem, solve.\n\nnote: Note\nRequires the Arpack.jl package to be loaded with using Arpack.\n\n\n\n\n\n","category":"type"},{"location":"exactdiagonalization.html#Rimu.ExactDiagonalization.LOBPCGSolver","page":"Exact Diagonalization","title":"Rimu.ExactDiagonalization.LOBPCGSolver","text":"LOBPCGSolver(; kwargs...)\n\nThe Locally Optimal Block Preconditioned Conjugate Gradient Method (LOBPCG). Algorithm for solving an ExactDiagonalizationProblem after instantiating a sparse matrix.\n\nLOBPCG is not suitable for non-hermitian eigenvalue problems.\n\nThe kwargs are passed on to the function IterativeSolvers.lobpcg().\n\nSee also ExactDiagonalizationProblem, solve.\n\nnote: Note\nRequires the IterativeSolvers.jl package to be loaded with using IterativeSolvers.\n\n\n\n\n\n","category":"type"},{"location":"exactdiagonalization.html#Converting-a-Hamiltonian-in-to-a-matrix","page":"Exact Diagonalization","title":"Converting a Hamiltonian in to a matrix","text":"","category":"section"},{"location":"exactdiagonalization.html","page":"Exact Diagonalization","title":"Exact Diagonalization","text":"BasisSetRepresentation\nbuild_basis\nMatrix\nsparse","category":"page"},{"location":"exactdiagonalization.html#Rimu.ExactDiagonalization.BasisSetRepresentation","page":"Exact Diagonalization","title":"Rimu.ExactDiagonalization.BasisSetRepresentation","text":"BasisSetRepresentation(\n hamiltonian::AbstractHamiltonian, addr=starting_address(hamiltonian);\n sizelim=10^7, cutoff, filter, max_depth, minimum_size, sort=false, kwargs...\n)\nBasisSetRepresentation(hamiltonian::AbstractHamiltonian, addresses::AbstractVector; kwargs...)\n\nEagerly construct the basis set representation of the operator hamiltonian with all addresses reachable from addr. Instead of a single address, a vector of addresses can be passed.\n\nAn ArgumentError is thrown if dimension(hamiltonian) > sizelim in order to prevent memory overflow. Set sizelim = Inf in order to disable this behaviour.\n\nProviding the number nnzs of expected calculated matrix elements and col_hint for the estimated number of nonzero off-diagonal matrix elements in each matrix column may improve performance.\n\nProviding an energy cutoff will skip the columns and rows with diagonal elements greater than cutoff. Alternatively, an arbitrary filter function can be used instead. Addresses passed as arguments are not filtered. To generate the matrix truncated to the subspace spanned by the addresses, use filter = Returns(false).\n\nProviding a max_depth will limit the size of the matrix and basis by only visiting addresses that are connected to the starting_address through max_depth hops through the Hamiltonian. Similarly, providing minimum_size will stop the bulding process after the basis reaches a length of at least minimum_size.\n\nSetting sort to true will sort the matrix rows and columns. This is useful when the order of the columns matters, e.g. when comparing matrices. Any additional keyword arguments are passed on to Base.sortperm.\n\nwarning: Warning\nThe order of the returned basis and matrix rows and columns is arbitrary and\nnon-deterministic. Use `sort=true` if the ordering matters.\n\nFields\n\nsparse_matrix: sparse matrix representing hamiltonian in the basis basis\nbasis: vector of addresses\nhamiltonian: the Hamiltonian hamiltonian\n\nExample\n\njulia> hamiltonian = HubbardReal1D(BoseFS(1,0,0));\n\njulia> bsr = BasisSetRepresentation(hamiltonian)\nBasisSetRepresentation(HubbardReal1D(fs\"|1 0 0⟩\"; u=1.0, t=1.0)) with dimension 3 and 6 stored entries:3×3 SparseArrays.SparseMatrixCSC{Float64, Int32} with 6 stored entries:\n ⋅ -1.0 -1.0\n -1.0 ⋅ -1.0\n -1.0 -1.0 ⋅\n\njulia> BasisSetRepresentation(hamiltonian, bsr.basis[1:2]; filter = Returns(false)) # passing addresses and truncating\nBasisSetRepresentation(HubbardReal1D(fs\"|1 0 0⟩\"; u=1.0, t=1.0)) with dimension 2 and 2 stored entries:2×2 SparseArrays.SparseMatrixCSC{Float64, Int32} with 2 stored entries:\n ⋅ -1.0\n -1.0 ⋅\n\njulia> using LinearAlgebra; round.(eigvals(Matrix(bsr)); digits = 4) # eigenvalues\n3-element Vector{Float64}:\n -2.0\n 1.0\n 1.0\n\njulia> ev = eigvecs(Matrix(bsr))[:,1]; ev = ev .* sign(ev[1]) # ground state eigenvector\n3-element Vector{Float64}:\n 0.5773502691896257\n 0.5773502691896255\n 0.5773502691896257\n\njulia> dv = DVec(zip(bsr.basis, ev)) # ground state as DVec\nDVec{BoseFS{1, 3, BitString{3, 1, UInt8}},Float64} with 3 entries, style = IsDeterministic{Float64}()\n fs\"|0 0 1⟩\" => 0.57735\n fs\"|0 1 0⟩\" => 0.57735\n fs\"|1 0 0⟩\" => 0.57735\n\nHas methods for dimension, sparse, Matrix, starting_address.\n\nPart of the AbstractHamiltonian interface. See also build_basis.\n\n\n\n\n\n","category":"type"},{"location":"exactdiagonalization.html#Rimu.ExactDiagonalization.build_basis","page":"Exact Diagonalization","title":"Rimu.ExactDiagonalization.build_basis","text":"build_basis(\n ham, address=starting_address(ham);\n cutoff, filter, sizelim, sort=false, kwargs...\n) -> basis\nbuild_basis(ham, addresses::AbstractVector; kwargs...)\n\nGet all basis element of a linear operator ham that are reachable (via non-zero matrix elements) from the address address, returned as a vector. Instead of a single address, a vector of addresses can be passed. Does not return the matrix, for that purpose use BasisSetRepresentation.\n\nProviding an energy cutoff will skip addresses with diagonal elements greater than cutoff. Alternatively, an arbitrary filter function can be used instead. Addresses passed as arguments are not filtered.\n\nProviding a max_depth will limit the size of the basis by only visiting addresses that are connected to the starting_address through max_depth hops through the Hamiltonian. Similarly, providing minimum_size will stop the bulding process after the basis reaches a length of at least minimum_size.\n\nA maximum basis size sizelim can be set which will throw an error if the expected dimension of ham is larger than sizelim. This may be useful when memory may be a concern. These options are disabled by default.\n\nwarning: Warning\nThe order the basis is returned in is arbitrary and non-deterministic. Use\n`sort=true` if the ordering matters.\n\n\n\n\n\nbuild_basis(addr::AbstractFockAddress)\nbuild_basis(::Type{<:AbstractFockAddress}) -> basis\n\nReturn all possible Fock states of a given type as a vector. This method is much faster than build_basis(::AbstractHamiltonian, ...), but does not take matrix blocking into account. This version of build_basis accepts no additional arguments.\n\nAll address types except OccupationNumberFS are supported.\n\nReturns a sorted vector of length equal to the dimension of addr.\n\nSee also AbstractFockAddress.\n\n\n\n\n\n","category":"function"},{"location":"exactdiagonalization.html#Base.Matrix","page":"Exact Diagonalization","title":"Base.Matrix","text":"Matrix(\n hamiltonian::AbstractHamiltonian, addr=starting_address(hamiltonian);\n sizelim=10^4, kwargs...\n)\nMatrix(bsr::BasisSetRepresentation)\n\nReturn a dense matrix representation of hamiltonian or bsr. kwargs are passed to BasisSetRepresentation.\n\nSee BasisSetRepresentation.\n\n\n\n\n\n","category":"type"},{"location":"exactdiagonalization.html#SparseArrays.sparse","page":"Exact Diagonalization","title":"SparseArrays.sparse","text":"sparse(hamiltonian::AbstractHamiltonian, addr=starting_address(hamiltonian); kwargs...)\nsparse(bsr::BasisSetRepresentation)\n\nReturn a sparse matrix representation of hamiltonian or bsr. kwargs are passed to BasisSetRepresentation.\n\nSee BasisSetRepresentation.\n\n\n\n\n\n","category":"function"},{"location":"exactdiagonalization.html#Deprecated","page":"Exact Diagonalization","title":"Deprecated","text":"","category":"section"},{"location":"exactdiagonalization.html","page":"Exact Diagonalization","title":"Exact Diagonalization","text":"BasisSetRep","category":"page"},{"location":"exactdiagonalization.html#Rimu.ExactDiagonalization.BasisSetRep","page":"Exact Diagonalization","title":"Rimu.ExactDiagonalization.BasisSetRep","text":"BasisSetRep(args...; kwargs...)\n\nBasisSetRep is deprecated. Use BasisSetRepresentation instead.\n\n\n\n\n\n","category":"function"},{"location":"documentation.html#Documentation-generation","page":"Documentation generation","title":"Documentation generation","text":"","category":"section"},{"location":"documentation.html","page":"Documentation generation","title":"Documentation generation","text":"We are using Documenter.jl to generate the documentation web site based on markdown files stored in docs/src. Please help keeping the documentation up-to-date by editing the markdown files! For instructions on how to write appropriate documentation please refer to the relevant chapter in the Julia documentation and the Documenter.jl documentation.","category":"page"},{"location":"documentation.html#Generating-the-documentation-web-site","page":"Documentation generation","title":"Generating the documentation web site","text":"","category":"section"},{"location":"documentation.html","page":"Documentation generation","title":"Documentation generation","text":"The documentation pages can be generated by running the build script by typing","category":"page"},{"location":"documentation.html","page":"Documentation generation","title":"Documentation generation","text":"Rimu$ julia --project=docs docs/make.jl","category":"page"},{"location":"documentation.html","page":"Documentation generation","title":"Documentation generation","text":"on the shell prompt from the Rimu/ folder. A complete image of the static documentation web site will be generated in the folder docs/build/. It can be viewed locally by pointing a web browser to file docs/build/index.html, or by deploying it to the GitHub pages web server.","category":"page"},{"location":"documentation.html#Automatic-documentation-generation-and-deployment","page":"Documentation generation","title":"Automatic documentation generation and deployment","text":"","category":"section"},{"location":"documentation.html","page":"Documentation generation","title":"Documentation generation","text":"Our documentation is hosted on GitHub pages. The documentation web site can be built and deployed automatically with GitHub Actions. This needs to be set up with an appropriate script in the file .github/workflows/docs.yml, where triggers for this to happen can be defined. In the current set up, a new documentation web site is generated and deployed whenever someone pushes to the develop branch on the GitHub server. The updated documentation can then be accessed here.","category":"page"},{"location":"documentation.html","page":"Documentation generation","title":"Documentation generation","text":"Previews for pull-requests can be accessed by replacing 101 in the following link with the PR number: https://RimuQMC.github.io/Rimu.jl/previews/PR101/","category":"page"},{"location":"documentation.html#Example-scripts","page":"Documentation generation","title":"Example scripts","text":"","category":"section"},{"location":"documentation.html","page":"Documentation generation","title":"Documentation generation","text":"Examples should be added to the scripts folder, in the form of .jl files suitable for parsing by Literate. The process of generating documentation is automated in the docs/make.jl file and assumes that the following line is at (or near) the top of the script:","category":"page"},{"location":"documentation.html","page":"Documentation generation","title":"Documentation generation","text":"# # Example N: Title","category":"page"},{"location":"documentation.html","page":"Documentation generation","title":"Documentation generation","text":"where the number N and Title will be extracted automatically.","category":"page"},{"location":"documentation.html","page":"Documentation generation","title":"Documentation generation","text":"Tests for the results and output of specific scripts should be added at the end of each example. The code to run the test should be hidden from the final generated document by appending \"#hide\" to each line of testing code. For example,","category":"page"},{"location":"documentation.html","page":"Documentation generation","title":"Documentation generation","text":"using Test #hide\n@test isfile(\"result.out\") #hide\n@test result == expected_result #hide","category":"page"},{"location":"addresses.html#Module-BitStringAddresses","page":"BitString addresses","title":"Module BitStringAddresses","text":"","category":"section"},{"location":"addresses.html","page":"BitString addresses","title":"BitString addresses","text":"This module contains the implementations of BitString and various Fock addresses. The addresses serve as a basis for a Hamiltonian.","category":"page"},{"location":"addresses.html","page":"BitString addresses","title":"BitString addresses","text":"While there are not restrictions on the type of address a Hamiltonian uses, Rimu provides implementations for Bosonic, Fermionic, and mixed Fock States.","category":"page"},{"location":"addresses.html","page":"BitString addresses","title":"BitString addresses","text":"When implementing a new address type, care must be taken to make them space-efficient and stack-allocated - avoid using (heap-allocated) arrays to represent your addresses at all costs!","category":"page"},{"location":"addresses.html#Fock-addresses","page":"BitString addresses","title":"Fock addresses","text":"","category":"section"},{"location":"addresses.html","page":"BitString addresses","title":"BitString addresses","text":"Rimu provides a variety of address implementations that should make it straightforward to implement efficient Hamiltonians. Examples are:","category":"page"},{"location":"addresses.html","page":"BitString addresses","title":"BitString addresses","text":"BoseFS Single-component bosonic Fock state with fixed particle and mode number.\nFermiFS Single-component fermionic Fock state with fixed particle and mode number.\nCompositeFS Multi-component Fock state composed of the above types.\nOccupationNumberFS Single-component bosonic Fock state with a fixed number of modes. The number of particles is not part of the type and can be changed by operators.","category":"page"},{"location":"addresses.html#Fock-address-API","page":"BitString addresses","title":"Fock address API","text":"","category":"section"},{"location":"addresses.html","page":"BitString addresses","title":"BitString addresses","text":"Modules = [BitStringAddresses]\nPages = [\"fockaddress.jl\",\"bosefs.jl\",\"fermifs.jl\",\"multicomponent.jl\",\"occupationnumberfs.jl\"]\nPrivate = false","category":"page"},{"location":"addresses.html#Rimu.BitStringAddresses.AbstractFockAddress","page":"BitString addresses","title":"Rimu.BitStringAddresses.AbstractFockAddress","text":"AbstractFockAddress{N,M}\n\nAbstract type representing a Fock state with N particles and M modes.\n\nSee also SingleComponentFockAddress, CompositeFS, BoseFS, FermiFS.\n\n\n\n\n\n","category":"type"},{"location":"addresses.html#Rimu.BitStringAddresses.BoseFSIndex","page":"BitString addresses","title":"Rimu.BitStringAddresses.BoseFSIndex","text":"BoseFSIndex\n\nStruct used for indexing and performing excitations on a BoseFS.\n\nFields:\n\noccnum: the occupation number.\nmode: the index of the mode.\noffset: the position of the mode in the address. This is the bit offset of the mode when\n\nthe address is represented by a bitstring, and the position in the list when it is represented by SortedParticleList.\n\n\n\n\n\n","category":"type"},{"location":"addresses.html#Rimu.BitStringAddresses.FermiFSIndex","page":"BitString addresses","title":"Rimu.BitStringAddresses.FermiFSIndex","text":"FermiFSIndex\n\nStruct used for indexing and performing excitations on a FermiFS.\n\nFields:\n\noccnum: the occupation number.\nmode: the index of the mode.\noffset: the position of the mode in the address. This is mode - 1 when the address is represented by a bitstring, and the position in the list when using SortedParticleList.\n\n\n\n\n\n","category":"type"},{"location":"addresses.html#Rimu.BitStringAddresses.OccupiedModeMap","page":"BitString addresses","title":"Rimu.BitStringAddresses.OccupiedModeMap","text":"OccupiedModeMap(addr) <: AbstractVector\n\nGet a map of occupied modes in address as an AbstractVector of indices compatible with excitation - BoseFSIndex or FermiFSIndex.\n\nOccupiedModeMap(addr)[i] contains the index for the i-th occupied mode. This is useful because repeatedly looking for occupied modes with find_occupied_mode can be time-consuming. OccupiedModeMap(addr) is an eager version of the iterator returned by occupied_modes. It is similar to onr but contains more information.\n\nExample\n\njulia> b = BoseFS(10, 0, 0, 0, 2, 0, 1)\nBoseFS{13,7}(10, 0, 0, 0, 2, 0, 1)\n\njulia> mb = OccupiedModeMap(b)\n3-element OccupiedModeMap{7, BoseFSIndex}:\n BoseFSIndex(occnum=10, mode=1, offset=0)\n BoseFSIndex(occnum=2, mode=5, offset=14)\n BoseFSIndex(occnum=1, mode=7, offset=18)\n\njulia> f = FermiFS(1,1,1,1,0,0,1,0,0)\nFermiFS{5,9}(1, 1, 1, 1, 0, 0, 1, 0, 0)\n\njulia> mf = OccupiedModeMap(f)\n5-element OccupiedModeMap{5, FermiFSIndex}:\n FermiFSIndex(occnum=1, mode=1, offset=0)\n FermiFSIndex(occnum=1, mode=2, offset=1)\n FermiFSIndex(occnum=1, mode=3, offset=2)\n FermiFSIndex(occnum=1, mode=4, offset=3)\n FermiFSIndex(occnum=1, mode=7, offset=6)\n\njulia> mf == collect(occupied_modes(f))\ntrue\n\njulia> dot(mf, mb)\n11\n\njulia> dot(mf, 1:20)\n17\n\nSee also dot, SingleComponentFockAddress.\n\n\n\n\n\n","category":"type"},{"location":"addresses.html#Rimu.BitStringAddresses.OccupiedPairsMap","page":"BitString addresses","title":"Rimu.BitStringAddresses.OccupiedPairsMap","text":"OccupiedPairsMap(addr::SingleComponentFockAddress) <: AbstractVector\n\nGet a map of all distinct pairs of indices in addr. Pairs involving multiply-occupied modes are counted once, (including self-pairing). This is useful for cases where identifying pairs of particles for eg. interactions is not well-defined or efficient to do on the fly. This is an eager iterator whose elements are a tuple of particle indices that can be given to excitation\n\nExample\n\njulia> addr = BoseFS(10, 0, 0, 0, 2, 0, 1)\nBoseFS{13,7}(10, 0, 0, 0, 2, 0, 1)\n\njulia> pairs = OccupiedPairsMap(addr)\n5-element OccupiedPairsMap{78, Tuple{BoseFSIndex, BoseFSIndex}}:\n (BoseFSIndex(occnum=10, mode=1, offset=0), BoseFSIndex(occnum=10, mode=1, offset=0))\n (BoseFSIndex(occnum=2, mode=5, offset=14), BoseFSIndex(occnum=2, mode=5, offset=14))\n (BoseFSIndex(occnum=2, mode=5, offset=14), BoseFSIndex(occnum=10, mode=1, offset=0))\n (BoseFSIndex(occnum=1, mode=7, offset=18), BoseFSIndex(occnum=10, mode=1, offset=0))\n (BoseFSIndex(occnum=1, mode=7, offset=18), BoseFSIndex(occnum=2, mode=5, offset=14))\n\njulia> excitation(addr, pairs[2], pairs[4])\n(BoseFS{13,7}(9, 0, 0, 0, 4, 0, 0), 10.954451150103322)\n\nSee also OccupiedModeMap.\n\n\n\n\n\n","category":"type"},{"location":"addresses.html#Rimu.BitStringAddresses.SingleComponentFockAddress","page":"BitString addresses","title":"Rimu.BitStringAddresses.SingleComponentFockAddress","text":"SingleComponentFockAddress{N,M} <: AbstractFockAddress{N,M}\n\nA type representing a single component Fock state with N particles and M modes.\n\nImplemented subtypes: BoseFS, FermiFS.\n\nSupported functionality\n\nfind_mode\nfind_occupied_mode\nnum_occupied_modes\noccupied_modes: Lazy iterator.\nOccupiedModeMap: AbstractVector with eager construction.\nexcitation: Create a new address.\nBoseFSIndex and FermiFSIndex for indexing.\n\nSee also CompositeFS, AbstractFockAddress.\n\n\n\n\n\n","category":"type"},{"location":"addresses.html#Rimu.BitStringAddresses.excitation","page":"BitString addresses","title":"Rimu.BitStringAddresses.excitation","text":"excitation(addr::SingleComponentFockAddress, creations::NTuple, destructions::NTuple)\n\nGenerate an excitation on address addr by applying creations and destructions, which are tuples of the appropriate address indices (i.e. BoseFSIndex for bosons, or FermiFSIndex for fermions).\n\na^_c_1 a^_c_2 ldots a_d_1 a_d_2 ldots mathrmaddrrangle to\nαmathrmnaddrrangle\n\nReturns the new address naddr and the factor α. The value of α is given by the square root of the product of mode occupations before destruction and after creation. If the excitation is illegal, returns an arbitrary address and the value 0.0.\n\nExample\n\njulia> f = FermiFS(1,1,0,0,1,1,1,1)\nFermiFS{6,8}(1, 1, 0, 0, 1, 1, 1, 1)\n\njulia> i, j, k, l = find_mode(f, (3,4,2,5))\n(FermiFSIndex(occnum=0, mode=3, offset=2), FermiFSIndex(occnum=0, mode=4, offset=3), FermiFSIndex(occnum=1, mode=2, offset=1), FermiFSIndex(occnum=1, mode=5, offset=4))\n\njulia> excitation(f, (i,j), (k,l))\n(FermiFS{6,8}(1, 0, 1, 1, 0, 1, 1, 1), -1.0)\n\nSee SingleComponentFockAddress.\n\n\n\n\n\n","category":"function"},{"location":"addresses.html#Rimu.BitStringAddresses.find_mode","page":"BitString addresses","title":"Rimu.BitStringAddresses.find_mode","text":"find_mode(::SingleComponentFockAddress, i)\n\nFind the i-th mode in address. Returns BoseFSIndex for BoseFS, and FermiFSIndex for FermiFS. Can work on a tuple of modes. Does not check bounds.\n\njulia> find_mode(BoseFS(1, 0, 2), 2)\nBoseFSIndex(occnum=0, mode=2, offset=2)\n\njulia> find_mode(FermiFS(1, 1, 1, 0), (2,3))\n(FermiFSIndex(occnum=1, mode=2, offset=1), FermiFSIndex(occnum=1, mode=3, offset=2))\n\nSee SingleComponentFockAddress.\n\n\n\n\n\n","category":"function"},{"location":"addresses.html#Rimu.BitStringAddresses.find_occupied_mode","page":"BitString addresses","title":"Rimu.BitStringAddresses.find_occupied_mode","text":"find_occupied_mode(::SingleComponentFockAddress, k)\nfind_occupied_mode(::BoseFS, k, [n])\n\nFind the k-th occupied mode in address (with at least n particles). Returns BoseFSIndex for BoseFS, and FermiFSIndex for FermiFS. When unsuccessful it returns a zero index.\n\nExample\n\njulia> find_occupied_mode(FermiFS(1, 1, 1, 0), 2)\nFermiFSIndex(occnum=1, mode=2, offset=1)\n\njulia> find_occupied_mode(BoseFS(1, 0, 2), 1)\nBoseFSIndex(occnum=1, mode=1, offset=0)\n\njulia> find_occupied_mode(BoseFS(1, 0, 2), 1, 2)\nBoseFSIndex(occnum=2, mode=3, offset=3)\n\nSee also occupied_modes, OccupiedModeMap, SingleComponentFockAddress.\n\n\n\n\n\n","category":"function"},{"location":"addresses.html#Rimu.BitStringAddresses.num_components-Tuple{AbstractFockAddress}","page":"BitString addresses","title":"Rimu.BitStringAddresses.num_components","text":"num_components(::Type{<:AbstractFockAddress})\nnum_components(::AbstractFockAddress)\n\nNumber of components in address.\n\n\n\n\n\n","category":"method"},{"location":"addresses.html#Rimu.BitStringAddresses.num_modes-Tuple{AbstractFockAddress}","page":"BitString addresses","title":"Rimu.BitStringAddresses.num_modes","text":"num_modes(::Type{<:AbstractFockAddress})\nnum_modes(::AbstractFockAddress)\n\nNumber of modes represented by address.\n\n\n\n\n\n","category":"method"},{"location":"addresses.html#Rimu.BitStringAddresses.num_occupied_modes","page":"BitString addresses","title":"Rimu.BitStringAddresses.num_occupied_modes","text":"num_occupied_modes(::SingleComponentFockAddress)\n\nGet the number of occupied modes in address. Equivalent to length(occupied_modes(address)), or the number of non-zeros in its ONR representation.\n\nExample\n\njulia> num_occupied_modes(BoseFS((1, 0, 2)))\n2\njulia> num_occupied_modes(FermiFS((1, 1, 1, 0)))\n3\n\nSee SingleComponentFockAddress.\n\n\n\n\n\n","category":"function"},{"location":"addresses.html#Rimu.BitStringAddresses.num_particles-Tuple{AbstractFockAddress}","page":"BitString addresses","title":"Rimu.BitStringAddresses.num_particles","text":"num_particles(::Type{<:AbstractFockAddress})\nnum_particles(::AbstractFockAddress)\n\nNumber of particles represented by address.\n\n\n\n\n\n","category":"method"},{"location":"addresses.html#Rimu.BitStringAddresses.occupied_modes","page":"BitString addresses","title":"Rimu.BitStringAddresses.occupied_modes","text":"occupied_modes(::SingleComponentFockAddress)\n\nReturn a lazy iterator over all occupied modes in an address. Iterates over BoseFSIndexs for BoseFS, and over FermiFSIndexs for FermiFS. See OccupiedModeMap for an eager version.\n\nExample\n\njulia> b = BoseFS((1,5,0,4));\n\njulia> foreach(println, occupied_modes(b))\nBoseFSIndex(occnum=1, mode=1, offset=0)\nBoseFSIndex(occnum=5, mode=2, offset=2)\nBoseFSIndex(occnum=4, mode=4, offset=9)\n\njulia> f = FermiFS((1,1,0,1,0,0,1));\n\njulia> foreach(println, occupied_modes(f))\nFermiFSIndex(occnum=1, mode=1, offset=0)\nFermiFSIndex(occnum=1, mode=2, offset=1)\nFermiFSIndex(occnum=1, mode=4, offset=3)\nFermiFSIndex(occnum=1, mode=7, offset=6)\n\nSee also find_occupied_mode, SingleComponentFockAddress.\n\n\n\n\n\n","category":"function"},{"location":"addresses.html#Rimu.BitStringAddresses.onr","page":"BitString addresses","title":"Rimu.BitStringAddresses.onr","text":"occupation_number_representation(fs::SingleComponentFockAddress)\nonr(fs::SingleComponentFockAddress)\n\nCompute and return the occupation number representation of the Fock state fs as an SVector{M}, where M is the number of modes.\n\n\n\n\n\n","category":"function"},{"location":"addresses.html#Rimu.BitStringAddresses.@fs_str-Tuple{Any}","page":"BitString addresses","title":"Rimu.BitStringAddresses.@fs_str","text":"fs\"$(string)\"\n\nParse the compact representation of a Fock state. Useful for copying the printout from a vector to the REPL.\n\nExample\n\njulia> DVec(BoseFS{3,4}(0, 1, 2, 0) => 1)\nDVec{BoseFS{3, 4, BitString{6, 1, UInt8}},Int64} with 1 entry, style = IsStochasticInteger{Int64}()\n fs\"|0 1 2 0⟩\" => 1\n\njulia> fs\"|0 1 2 0⟩\" => 1 # Copied from above printout\nBoseFS{3,4}(0, 1, 2, 0) => 1\n\njulia> fs\"|1 2 3⟩⊗|0 1 0⟩\" # composite bosonic Fock state\nCompositeFS(\n BoseFS{6,3}(1, 2, 3),\n BoseFS{1,3}(0, 1, 0),\n)\n\njulia> fs\"|↑↓↑⟩\" # construct a fermionic Fock state\nCompositeFS(\n FermiFS{2,3}(1, 0, 1),\n FermiFS{1,3}(0, 1, 0),\n)\n\njulia> s = fs\"|0 1 2 0⟩{}\" # constructing OccupationNumberFS with default UInt8 container\nOccupationNumberFS{4, UInt8}(0, 1, 2, 0)\n\njulia> [s] # prints out with the signifcant number of bits specified in braces\n1-element Vector{OccupationNumberFS{4, UInt8}}:\n fs\"|0 1 2 0⟩{8}\"\n\nSee also FermiFS, BoseFS, CompositeFS, FermiFS2C, OccupationNumberFS.\n\n\n\n\n\n","category":"macro"},{"location":"addresses.html#Rimu.BitStringAddresses.BoseFS","page":"BitString addresses","title":"Rimu.BitStringAddresses.BoseFS","text":"BoseFS{N,M,S} <: SingleComponentFockAddress\n\nAddress type that represents a Fock state of N spinless bosons in M modes by wrapping a BitString, or a SortedParticleList. Which is wrapped is chosen automatically based on the properties of the address.\n\nConstructors\n\nBoseFS{[N,M]}(val::Integer...): Create BoseFS{N,M} from occupation numbers. This is type-stable if the number of modes M and the number of particles N are provided. Otherwise, M and N are inferred from the arguments.\nBoseFS{[N,M]}(onr): Create BoseFS{N,M} from occupation number representation, see onr. This is efficient if N and M are provided, and onr is a statically-sized collection, such as a Tuple or SVector.\nBoseFS{[N,M]}([M, ]pairs...): Provide the number of modes M and mode => occupation_number pairs. If M is provided as a type parameter, it should not be provided as the first argument. Useful for creating sparse addresses. pairs can be multiple arguments or an iterator of pairs.\nBoseFS{N,M,S}(bs::S): Unsafe constructor. Does not check whether the number of particles in bs is equal to N.\n@fs_str: Addresses are sometimes printed in a compact manner. This representation can also be used as a constructor. See the last example below.\n\nExamples\n\njulia> BoseFS{6,5}(0, 1, 2, 3, 0)\nBoseFS{6,5}(0, 1, 2, 3, 0)\n\njulia> BoseFS([abs(i - 3) ≤ 1 ? i - 1 : 0 for i in 1:5])\nBoseFS{6,5}(0, 1, 2, 3, 0)\n\njulia> BoseFS(5, 2 => 1, 3 => 2, 4 => 3)\nBoseFS{6,5}(0, 1, 2, 3, 0)\n\njulia> BoseFS{6,5}(i => i - 1 for i in 2:4)\nBoseFS{6,5}(0, 1, 2, 3, 0)\n\njulia> fs\"|0 1 2 3 0⟩\"\nBoseFS{6,5}(0, 1, 2, 3, 0)\n\njulia> fs\"|b 5: 2 3 3 4 4 4⟩\"\nBoseFS{6,5}(0, 1, 2, 3, 0)\n\nSee also: SingleComponentFockAddress, OccupationNumberFS, FermiFS, CompositeFS, FermiFS2C.\n\n\n\n\n\n","category":"type"},{"location":"addresses.html#Rimu.BitStringAddresses.bose_hubbard_interaction-Union{Tuple{BoseFS{<:Any, <:Any, A}}, Tuple{A}} where A<:BitString","page":"BitString addresses","title":"Rimu.BitStringAddresses.bose_hubbard_interaction","text":"bose_hubbard_interaction(address)\n\nReturn Σ_i n_i (n_i-1) for computing the Bose-Hubbard on-site interaction (without the U prefactor.)\n\nExample\n\njulia> Hamiltonians.bose_hubbard_interaction(BoseFS{4,4}((2,1,1,0)))\n2\njulia> Hamiltonians.bose_hubbard_interaction(BoseFS{4,4}((3,0,1,0)))\n6\n\n\n\n\n\n","category":"method"},{"location":"addresses.html#Rimu.BitStringAddresses.hopnextneighbour-Union{Tuple{A}, Tuple{M}, Tuple{N}, Tuple{BoseFS{N, M, A}, Any}} where {N, M, A<:BitString}","page":"BitString addresses","title":"Rimu.BitStringAddresses.hopnextneighbour","text":"new_address, value = hopnextneighbour(add, chosen, boundary_condition)\n\nCompute the new address of a hopping event for the Hubbard model. Returns the new address and the square root of product of occupation numbers of the involved modes multiplied by a term consistent with boundary condition as the value. The following boundary conditions are supported:\n\n:periodic: hopping over the boundary gives does not change the value.\n:twisted: hopping over the boundary flips the sign of the value.\n:hard_wall: hopping over the boundary gives a value of zero.\nθ <: Number: hopping over the boundary gives a value multiplied by exp(iθ) or exp(iθ) depending on the direction of hopping.\n\nThe off-diagonals are indexed as follows:\n\n(chosen + 1) ÷ 2 selects the hopping site.\nEven chosen indicates a hop to the left.\nOdd chosen indicates a hop to the right.\n\nExample\n\njulia> using Rimu.Hamiltonians: hopnextneighbour\n\njulia> hopnextneighbour(BoseFS(1, 0, 1), 3)\n(BoseFS{2,3}(2, 0, 0), 1.4142135623730951)\n\njulia> hopnextneighbour(BoseFS(1, 0, 1), 4)\n(BoseFS{2,3}(1, 1, 0), 1.0)\n\njulia> hopnextneighbour(BoseFS(1, 0, 1), 3, :twisted)\n(BoseFS{2,3}(2, 0, 0), -1.4142135623730951)\n\njulia> hopnextneighbour(BoseFS(1, 0, 1), 3, :hard_wall)\n(BoseFS{2,3}(2, 0, 0), 0.0)\n\njulia> hopnextneighbour(BoseFS(1, 0, 1), 3, π/4)\n(BoseFS{2,3}(2, 0, 0), 1.0000000000000002 + 1.0im)\n\n\n\n\n\n","category":"method"},{"location":"addresses.html#Rimu.BitStringAddresses.near_uniform-Union{Tuple{Type{<:BoseFS{N, M}}}, Tuple{M}, Tuple{N}} where {N, M}","page":"BitString addresses","title":"Rimu.BitStringAddresses.near_uniform","text":"near_uniform(BoseFS{N,M}) -> BoseFS{N,M}\n\nCreate bosonic Fock state with near uniform occupation number of M modes with a total of N particles.\n\nExamples\n\njulia> near_uniform(BoseFS{7,5})\nBoseFS{7,5}(2, 2, 1, 1, 1)\n\njulia> near_uniform(FermiFS{3,5})\nFermiFS{3,5}(1, 1, 1, 0, 0)\n\n\n\n\n\n","category":"method"},{"location":"addresses.html#Rimu.BitStringAddresses.FermiFS","page":"BitString addresses","title":"Rimu.BitStringAddresses.FermiFS","text":"FermiFS{N,M,S} <: SingleComponentFockAddress\n\nAddress type that represents a Fock state of N fermions of the same spin in M modes by wrapping a BitString, or a SortedParticleList. Which is wrapped is chosen automatically based on the properties of the address.\n\nConstructors\n\nFermiFS{[N,M]}(val::Integer...): Create FermiFS{N,M} from occupation numbers. This is type-stable if the number of modes M and the number of particles N are provided. Otherwise, M and N are inferred from the arguments.\nFermiFS{[N,M]}(onr): Create FermiFS{N,M} from occupation number representation, see onr. This is efficient if N and M are provided, and onr is a statically-sized collection, such as a Tuple{M} or SVector{M}.\nFermiFS{[N,M]}([M, ]pairs...): Provide the number of modes M and pairs of the form mode => 1. If M is provided as a type parameter, it should not be provided as the first argument. Useful for creating sparse addresses. pairs can be multiple arguments or an iterator of pairs.\nFermiFS{N,M,S}(bs::S): Unsafe constructor. Does not check whether the number of particles in bs is equal to N, or whether each mode only contains one particle.\n@fs_str: Addresses are sometimes printed in a compact manner. This representation can also be used as a constructor. See the last example below.\n\nExamples\n\njulia> FermiFS{3,5}(0, 1, 1, 1, 0)\nFermiFS{3,5}(0, 1, 1, 1, 0)\n\njulia> FermiFS([abs(i - 3) ≤ 1 for i in 1:5])\nFermiFS{3,5}(0, 1, 1, 1, 0)\n\njulia> FermiFS(5, 2 => 1, 3 => 1, 4 => 1)\nFermiFS{3,5}(0, 1, 1, 1, 0)\n\njulia> FermiFS{3,5}(i => 1 for i in 2:4)\nFermiFS{3,5}(0, 1, 1, 1, 0)\n\njulia> fs\"|⋅↑↑↑⋅⟩\"\nFermiFS{3,5}(0, 1, 1, 1, 0)\n\njulia> fs\"|f 5: 2 3 4⟩\"\nFermiFS{3,5}(0, 1, 1, 1, 0)\n\nSee also: SingleComponentFockAddress, BoseFS, CompositeFS, FermiFS2C, BitString, OccupationNumberFS.\n\n\n\n\n\n","category":"type"},{"location":"addresses.html#Rimu.BitStringAddresses.CompositeFS","page":"BitString addresses","title":"Rimu.BitStringAddresses.CompositeFS","text":"CompositeFS(addresses::SingleComponentFockAddress...) <: AbstractFockAddress\n\nUsed to encode addresses for multi-component models. All component addresses are expected have the same number of modes.\n\nSee also: BoseFS, FermiFS, SingleComponentFockAddress, num_modes, FermiFS2C, AbstractFockAddress.\n\n\n\n\n\n","category":"type"},{"location":"addresses.html#Rimu.BitStringAddresses.FermiFS2C","page":"BitString addresses","title":"Rimu.BitStringAddresses.FermiFS2C","text":"FermiFS2C <: AbstractFockAddress\nFermiFS2C(onr_a, onr_b)\n\nFock state address with two fermionic (spin) components. Alias for CompositeFS with two FermiFS components. Construct by specifying either two compatible FermiFSs, two onrs, or the number of modes followed by mode => occupation_number pairs, where occupation_number=1 will put a particle in the first component and occupation_number=-1 will put a particle in the second component. See examples below.\n\nExamples\n\njulia> FermiFS2C(FermiFS(1,0,0), FermiFS(0,1,1))\nCompositeFS(\n FermiFS{1,3}(1, 0, 0),\n FermiFS{2,3}(0, 1, 1),\n)\n\njulia> FermiFS2C((1,0,0), (0,1,1))\nCompositeFS(\n FermiFS{1,3}(1, 0, 0),\n FermiFS{2,3}(0, 1, 1),\n)\n\njulia> FermiFS2C(3, 1 => 1, 2 => -1, 3 => -1)\nCompositeFS(\n FermiFS{1,3}(1, 0, 0),\n FermiFS{2,3}(0, 1, 1),\n)\n\njulia> fs\"|↑↓↓⟩\"\nCompositeFS(\n FermiFS{1,3}(1, 0, 0),\n FermiFS{2,3}(0, 1, 1),\n)\n\n\n\n\n\n","category":"type"},{"location":"addresses.html#Rimu.BitStringAddresses.time_reverse-Union{Tuple{CompositeFS{2, N, M, T}}, Tuple{T}, Tuple{M}, Tuple{N}} where {N, M, T<:(Tuple{T, T} where T)}","page":"BitString addresses","title":"Rimu.BitStringAddresses.time_reverse","text":"time_reverse(addr)\n\nApply the time-reversal operation on a two-component Fock address that flips all the spins.\n\nRequires each component address to have the same type.\n\n\n\n\n\n","category":"method"},{"location":"addresses.html#Rimu.BitStringAddresses.OccupationNumberFS","page":"BitString addresses","title":"Rimu.BitStringAddresses.OccupationNumberFS","text":"OccupationNumberFS{M,T} <: SingleComponentFockAddress\n\nAddress type that stores the occupation numbers of a single component bosonic Fock state with M modes. The occupation numbers must fit into the type T <: Unsigned. The number of particles is runtime data, and can be retrieved with num_particles(address).\n\nConstructors\n\nOccupationNumberFS(val::Integer...): Construct from occupation numbers. Must be < 256 to fit into UInt8.\nOccupationNumberFS{[M,T]}(onr): Construct from collection onr with M occupation numbers with type T. If unspecified, the type T of the occupation numbers is inferred from the type of the arguments.\nOccupationNumberFS{M[,T]}(onr): Construct a vacuum state with M modes. If T is unspecified, UInt8 is used.\nOccupationNumberFS(fs::BoseFS): Construct from BoseFS.\nWith shortform macro @fs_str. Specify the number of significant bits in braces. See example below.\n\nExamples\n\njulia> ofs = OccupationNumberFS(1,2,3)\nOccupationNumberFS{3, UInt8}(1, 2, 3)\n\njulia> ofs == fs\"|1 2 3⟩{8}\"\ntrue\n\njulia> num_particles(ofs)\n6\n\njulia> OccupationNumberFS{5}() # vacuum state with 5 modes\nOccupationNumberFS{5, UInt8}(0, 0, 0, 0, 0)\n\n\n\n\n\n","category":"type"},{"location":"addresses.html#Rimu.BitStringAddresses.excitation-Union{Tuple{T}, Tuple{OccupationNumberFS{<:Any, T}, NTuple{var\"#s61\", Int64} where var\"#s61\", NTuple{var\"#s5\", Int64} where var\"#s5\"}} where T","page":"BitString addresses","title":"Rimu.BitStringAddresses.excitation","text":"excitation(addr::OccupationNumberFS, c::NTuple, d::NTuple)\n→ (nadd, α)\n\nGenerate an excitation on an OccupationNumberFS by applying the creation and destruction operators specified by the tuples of mode numbers c and d to the Fock state addr. The modes are indexed by integers (starting at 1), or by indices of type BoseFSIndex. The value of α is given by the square root of the product of mode occupations before destruction and after creation.\n\nThe number of particles may change by this type of excitation.\n\nExample\n\njulia> s = fs\"|1 2 3⟩{8}\"\nOccupationNumberFS{3, UInt8}(1, 2, 3)\n\njulia> num_particles(s)\n6\n\njulia> es, α = excitation(s, (1,1), (3,))\n(OccupationNumberFS{3, UInt8}(3, 2, 2), 4.242640687119285)\n\njulia> num_particles(es)\n7\n\n\n\n\n\n","category":"method"},{"location":"addresses.html#Internal-representations","page":"BitString addresses","title":"Internal representations","text":"","category":"section"},{"location":"addresses.html","page":"BitString addresses","title":"BitString addresses","text":"The atomic addresses, BoseFS and FermiFS, are implemented as either bitstrings or sorted lists of particles. Using these approaches over an occupation number representation makes the addresses much more space-efficient.","category":"page"},{"location":"addresses.html","page":"BitString addresses","title":"BitString addresses","text":"Therewhile OccupationNumberFS internally uses the occupation number representation, which allows it to handle excitation operations that change the particle number. This is fast but requires more storage space.","category":"page"},{"location":"addresses.html#Internal-APIs","page":"BitString addresses","title":"Internal APIs","text":"","category":"section"},{"location":"addresses.html","page":"BitString addresses","title":"BitString addresses","text":"Modules = [BitStringAddresses]\nPages = [\"bitstring.jl\", \"sortedparticlelist.jl\"]\nPrivate = false","category":"page"},{"location":"addresses.html#Rimu.BitStringAddresses.BitString","page":"BitString addresses","title":"Rimu.BitStringAddresses.BitString","text":"BitString{B,N,T<:Unsigned}\n\nType for storing bitstrings of static size. Holds B bits in N chunks, where each chunk is of type T.\n\nN is chosen automatically to accommodate B bits as efficiently as possible.\n\nConstructors\n\nBitString{B,N,T}(::SVector{N,T}): unsafe constructor. Does not check for ghost bits.\nBitString{B,N,T}(i::T): as above, but sets i as the rightmost chunk.\nBitString{B}(::Integer): Convert integer to BitString. Integer is truncated to the correct number of bits.\n\n\n\n\n\n","category":"type"},{"location":"addresses.html#Rimu.BitStringAddresses.SortedParticleList","page":"BitString addresses","title":"Rimu.BitStringAddresses.SortedParticleList","text":"SortedParticleList{N,M,T<:Unsigned}\n\nType for storing sparse Fock states. Stores the mode number of each particle as an entry with only its mode stored. The entries are always kept sorted.\n\nIterating over SortedParticleLists yields occupied modes as a tuple of occupation number, mode number, and position in list.\n\nConstructors\n\nSortedParticleList{N,M,T}(::SVector{N,T}): unsafe constructor. Does not sort input.\nSortedParticleList(arr::AbstractVector): convert ONR to SortedParticleList\n\n\n\n\n\n","category":"type"},{"location":"addresses.html#Index","page":"BitString addresses","title":"Index","text":"","category":"section"},{"location":"addresses.html","page":"BitString addresses","title":"BitString addresses","text":"Pages = [\"addresses.md\"]","category":"page"},{"location":"API.html#API","page":"API","title":"API","text":"","category":"section"},{"location":"API.html#Rimu","page":"API","title":"Rimu","text":"","category":"section"},{"location":"API.html","page":"API","title":"API","text":"Modules = [Rimu]","category":"page"},{"location":"API.html#Rimu.Rimu","page":"API","title":"Rimu.Rimu","text":"Rimu\n\nRandom integrators for many-body quantum systems\n\nWelcome to Rimu version 0.14.0. Read the documentation online.\n\n\n\n\n\n","category":"module"},{"location":"API.html#Rimu.PACKAGE_VERSION","page":"API","title":"Rimu.PACKAGE_VERSION","text":"Rimu.PACKAGE_VERSION\n\nConstant that contains the current VersionNumber of Rimu.\n\n\n\n\n\n","category":"constant"},{"location":"API.html#DataFrames.DataFrame-Tuple{Rimu.Report}","page":"API","title":"DataFrames.DataFrame","text":"DataFrame(report::Report)\n\nConvert the Report to a DataFrame. Metadata is added as metadata to the DataFrame.\n\n\n\n\n\n","category":"method"},{"location":"API.html#Rimu.AllOverlaps","page":"API","title":"Rimu.AllOverlaps","text":"AllOverlaps(n_replicas=2; operator=nothing, transform=nothing, vecnorm=true)\n <: ReplicaStrategy{n_replicas}\n\nRun n_replicas replicas and report overlaps between all pairs of replica vectors. If operator is not nothing, the overlap dot(c1, operator, c2) is reported as well. If operator is a tuple of operators, the overlaps are computed for all operators.\n\nColumn names in the report are of the form c{i}_dot_c{j} for vector-vector overlaps, and c{i}_Op{k}_c{j} for operator overlaps.\n\nSee ProjectorMonteCarloProblem, ReplicaStrategy and AbstractOperator (for an interface for implementing operators).\n\nTransformed Hamiltonians\n\nIf a transformed Hamiltonian G has been passed to ProjectorMonteCarloProblem then overlaps can be calculated by passing the same transformed Hamiltonian to AllOverlaps by setting transform=G. A warning is given if these two Hamiltonians do not match.\n\nImplemented transformations are:\n\nGutzwillerSampling\nGuidingVectorSampling\n\nIn the case of a transformed Hamiltonian the overlaps are defined as follows. For a similarity transformation G of the Hamiltonian (see e.g. GutzwillerSampling.)\n\n hatG = f hatH f^-1\n\nThe expectation value of an operator hatA is\n\n langle hatA rangle = langle psi hatA psi rangle\n = fraclangle phi f^-1 hatA f^-1 phi ranglelangle phi f^-2 phi rangle\n\nwhere\n\n phi rangle = f psi rangle\n\nis the (right) eigenvector of hatG and psi rangle is an eigenvector of hatH.\n\nFor a K-tuple of input operators (hatA_1 hatA_K), overlaps of langle phi f^-1 hatA f^-1 phi rangle are reported as c{i}_Op{k}_c{j}. The correct vector-vector overlap langle phi f^-2 phi rangle is reported last as c{i}_Op{K+1}_c{j}. This is in addition to the bare vector-vector overlap langle phi f^-2 phi rangle that is reported as c{i}_dot_c{j}.\n\nIn either case the c{i}_dot_c{j} overlap can be omitted with the flag vecnorm=false.\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.ConstantTimeStep","page":"API","title":"Rimu.ConstantTimeStep","text":"ConstantTimeStep <: TimeStepStrategy\n\nKeep time_step constant.\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.DefaultShiftParameters","page":"API","title":"Rimu.DefaultShiftParameters","text":"DefaultShiftParameters\n\nDefault mutable struct for storing the shift parameters.\n\nSee ShiftStrategy, initialise_shift_parameters.\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.DontUpdate","page":"API","title":"Rimu.DontUpdate","text":"DontUpdate(; target_walkers = 1_000) <: ShiftStrategy\n\nDon't update the shift. Return when target_walkers is reached.\n\nSee ShiftStrategy, ProjectorMonteCarloProblem.\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.DoubleLogProjected","page":"API","title":"Rimu.DoubleLogProjected","text":"DoubleLogProjected(; target, projector, ζ = 0.08, ξ = ζ^2/4) <: ShiftStrategy\n\nStrategy for updating the shift according to the log formula with damping parameter ζ and ξ after projecting onto projector.\n\nS^n+1 = S^n -fracζdτlnleft(fracPΨ^(n+1)PΨ^(n)right)-fracξdτlnleft(fracPΨ^(n+1)texttargetright)\n\nNote that adjusting the keyword maxlength in ProjectorMonteCarloProblem is advised as the default may not be appropriate.\n\nSee ShiftStrategy, ProjectorMonteCarloProblem.\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.DoubleLogSumUpdate","page":"API","title":"Rimu.DoubleLogSumUpdate","text":"DoubleLogSumUpdate(; target_walkers = 1000, ζ = 0.08, ξ = ζ^2/4, α = 1/2) <: ShiftStrategy\n\nStrategy for updating the shift according to the log formula with damping parameters ζ and ξ.\n\nS^n+1 = S^n -fracζdτlnleft(fracN_mathrmw^n+1N_mathrmw^nright)\n- fracξdτlnleft(fracN_mathrmw^n+1N_mathrmw^texttargetright)\n\nwhere N_mathrmw = (1-α)*walkernumber() + α*UniformProjector()⋅ψ computed with walkernumber() and UniformProjector(). When ξ = ζ^2/4 this corresponds to critical damping with a damping time scale T = 2/ζ.\n\nSee ShiftStrategy, ProjectorMonteCarloProblem.\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.DoubleLogUpdate","page":"API","title":"Rimu.DoubleLogUpdate","text":"DoubleLogUpdate(; target_walkers = 1_000, ζ = 0.08, ξ = ζ^2/4) <: ShiftStrategy\n\nStrategy for updating the shift according to the log formula with damping parameter ζ and ξ.\n\nS^n+1 = S^n -fracζdτlnleft(fracΨ_1^n+1Ψ_1^nright)-fracξdτlnleft(fracΨ_1^n+1Ψ_1^texttargetright)\n\nWhen ξ = ζ^2/4 this corresponds to critical damping with a damping time scale T = 2/ζ.\n\nSee ShiftStrategy, ProjectorMonteCarloProblem.\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.DoubleLogUpdateAfterTargetWalkers","page":"API","title":"Rimu.DoubleLogUpdateAfterTargetWalkers","text":"DoubleLogUpdateAfterTargetWalkers(target_walkers = 1_000, ζ = 0.08, ξ = ζ^2/4) <: ShiftStrategy\n\nStrategy for updating the shift: After target_walkers is reached, update the shift according to the log formula with damping parameter ζ and ξ.\n\nSee DoubleLogUpdate, ShiftStrategy, ProjectorMonteCarloProblem.\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.FCIQMC","page":"API","title":"Rimu.FCIQMC","text":"FCIQMC(; kwargs...) <: PMCAlgorithm\n\nAlgorithm for the full configuration interaction quantum Monte Carlo (FCIQMC) method. The default algorithm for ProjectorMonteCarloProblem.\n\nKeyword arguments and defaults:\n\nshift_strategy = DoubleLogUpdate(; targetwalkers = 1_000, ζ = 0.08, ξ = ζ^2/4): How to update the shift.\ntime_step_strategy = ConstantTimeStep(): Adjust time step or not.\n\nSee also ProjectorMonteCarloProblem, ShiftStrategy, TimeStepStrategy, DoubleLogUpdate, ConstantTimeStep.\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.FciqmcRunStrategy","page":"API","title":"Rimu.FciqmcRunStrategy","text":" FciqmcRunStrategy{T}\n\nAbstract type representing the strategy for running and terminating lomc!(). The type parameter T is relevant for reporting the shift and the norm.\n\nImplemented strategies:\n\nRunTillLastStep\n\nwarning: Warning\nThe use of this strategy is deprecated. Pass the relevant arguments directly to ProjectorMonteCarloProblem or to lomc!() instead.\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.FirstOrderTransitionOperator","page":"API","title":"Rimu.FirstOrderTransitionOperator","text":"FirstOrderTransitionOperator(hamiltonian, shift, time_step) <: AbstractHamiltonian\nFirstOrderTransitionOperator(sp::DefaultShiftParameters, hamiltonian)\n\nFirst order transition operator\n\n𝐓 = 1 + dτ(S - 𝐇)\n\nwhere 𝐇 is the hamiltonian, dτ the time_step and S is the shift.\n\n𝐓 represents the first order expansion of the exponential evolution operator of the imaginary-time Schrödinger equation (Euler step) and repeated application will project out the ground state eigenvector of the hamiltonian. It is the transition operator used in FCIQMC.\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.GramSchmidt","page":"API","title":"Rimu.GramSchmidt","text":"GramSchmidt(S; orthogonalization_interval = 1) <: SpectralStrategy{S}\n\nUse the Gram-Schmidt procedure to orthogonalize the excited states. A total of S spectral states are used in the simulation, and they are orthogonalized every orthogonalization_interval steps.\n\nUse with the keyword argument spectral_strategy in ProjectorMonteCarloProblem.\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.LogUpdate","page":"API","title":"Rimu.LogUpdate","text":"LogUpdate(ζ = 0.08) <: ShiftStrategy\n\nStrategy for updating the shift according to the log formula with damping parameter ζ.\n\nS^n+1 = S^n -fracζdτlnleft(fracΨ_1^n+1Ψ_1^nright)\n\nSee ShiftStrategy, ProjectorMonteCarloProblem.\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.LogUpdateAfterTargetWalkers","page":"API","title":"Rimu.LogUpdateAfterTargetWalkers","text":"LogUpdateAfterTargetWalkers(target_walkers = 1_000, ζ = 0.08) <: ShiftStrategy\n\nStrategy for updating the shift: After target_walkers is reached, update the shift according to the log formula with damping parameter ζ.\n\nSee LogUpdate, ShiftStrategy, ProjectorMonteCarloProblem.\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.MultiScalar","page":"API","title":"Rimu.MultiScalar","text":"MultiScalar\n\nWrapper over a tuple that supports +, *, min, and max. Used with MPI communication because SVectors are treated as arrays by MPI.Allreduce and Tuples do not support scalar operations.\n\nExample\n\nSuppose you want to compute the sum of a vector dv and also get the number of positive elements it has in a single pass. You can use MultiScalar:\n\njulia> dv = DVec(:a => 1, :b => -2, :c => 1);\n\njulia> s, p = mapreduce(+, values(dv)) do v\n Rimu.MultiScalar(v, Int(sign(v) == 1))\nend;\n\njulia> s, p\n(0, 2)\n\nNote that only MultiScalars with the same types can be operated on. This is a feature, as it forces type stability.\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.NoStats","page":"API","title":"Rimu.NoStats","text":"NoStats(N=1) <: ReplicaStrategy{N}\n\nThe default ReplicaStrategy. N replicas are run, but no statistics are collected.\n\nSee also ProjectorMonteCarloProblem.\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.PMCAlgorithm","page":"API","title":"Rimu.PMCAlgorithm","text":"PMCAlgorithm\n\nAbstract type for projector Monte Carlo algorithms.\n\nSee ProjectorMonteCarloProblem, FCIQMC.\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.PMCSimulation","page":"API","title":"Rimu.PMCSimulation","text":"PMCSimulation\n\nHolds the state and the results of a projector quantum Monte Carlo (PMC) simulation. Is returned by init(::ProjectorMonteCarloProblem) and solved with solve!(::PMCSimulation).\n\nObtain the results of a simulation sm as a DataFrame with DataFrame(sm).\n\nFields\n\nproblem::ProjectorMonteCarloProblem: The problem that was solved\nstate::Rimu.ReplicaState: The current state of the simulation\nreport::Rimu.Report: The report of the simulation\nmodified::Bool: Whether the simulation has been modified\naborted::Bool: Whether the simulation has been aborted\nsuccess::Bool: Whether the simulation has been completed successfully\nmessage::String: A message about the simulation status\nelapsed_time::Float64: The time elapsed during the simulation\n\nSee also state_vectors, ProjectorMonteCarloProblem, init, solve!.\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.PostStepStrategy","page":"API","title":"Rimu.PostStepStrategy","text":"PostStepStrategy\n\nSubtypes of PostStepStrategy can be used to perform arbitrary computation on a single state after an FCIQMC step is finished and report the results.\n\nImplemented strategies:\n\nProjectedEnergy\nProjector\nSignCoherence\nWalkerLoneliness\nTimer\n\nNote: A tuple of multiple strategies can be passed to ProjectorMonteCarloProblem. In that case, all reported column names must be distinct.\n\nInterface:\n\nA subtype of this type must implement post_step_action(::PostStepStrategy, ::SingleState, step::Int).\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.ProjectedEnergy","page":"API","title":"Rimu.ProjectedEnergy","text":"ProjectedEnergy(hamiltonian, projector; hproj=:hproj, vproj=:vproj) <: PostStepStrategy\n\nAfter every step, compute hproj = dot(projector, hamiltonian, dv) and vproj = dot(projector, dv), where dv is the instantaneous coefficient vector. projector can be an AbstractDVec, or an AbstractProjector.\n\nReports to columns hproj and vproj, which can be used to compute projective energy, e.g. with projected_energy. The keyword arguments hproj and vproj can be used to change the names of these columns. This can be used to make the names unique when computing projected energies with different projectors in the same run.\n\nSee also projected_energy, ratio_of_means, mixed_estimator, and PostStepStrategy.\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.Projector","page":"API","title":"Rimu.Projector","text":"Projector(name=projector) <: PostStepStrategy\n\nAfter each step, compute dot(projector, dv) and report it in the DataFrame under name. projector can be an AbstractDVec, or an AbstractProjector.\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.ProjectorMonteCarloProblem","page":"API","title":"Rimu.ProjectorMonteCarloProblem","text":"ProjectorMonteCarloProblem(hamiltonian::AbstractHamiltonian; kwargs...)\n\nDefines a problem to be solved by projector quantum Monte Carlo (QMC) methods, such as the the FCIQMC algorithm.\n\nCommon keyword arguments and defaults:\n\ntime_step = 0.01: Initial time step size.\nlast_step = 100: Controls the number of steps.\ntarget_walkers = 1_000: Target for the 1-norm of the coefficient vector.\nstart_at = starting_address(hamiltonian): Define the initial state vector(s). An r s matrix of state vectors can be passed where r is the number of replicas and s the number of spectral states. See also default_starting_vector.\nstyle = IsDynamicSemistochastic(): The StochasticStyle of the simulation.\ninitiator = false: Whether to use initiators. Can be true, false, or a valid InitiatorRule.\nthreading: Default is to use multithreading and/or MPI if available. Set to true to force PDVec for the starting vector, false for serial computation; may be overridden by start_at.\nreporting_strategy = ReportDFAndInfo(): How and when to report results, see ReportingStrategy.\npost_step_strategy = (): Extract observables (e.g. ProjectedEnergy), see PostStepStrategy.\nn_replicas = 1: Number of synchronised independent simulations.\nreplica_strategy = NoStats(n_replicas): Which results to report from replica simulations, see ReplicaStrategy.\nn_spectral = 1: Number of targeted spectral states. Set n_spectral > 1 to find excited states.\nspectral_strategy = GramSchmidt(n_spectral): The SpectralStrategy used for orthogonalizing spectral states.\n\nExample\n\njulia> hamiltonian = HubbardReal1D(BoseFS(1,2,3));\n\njulia> problem = ProjectorMonteCarloProblem(hamiltonian; target_walkers = 500, last_step = 100);\n\njulia> simulation = solve(problem);\n\njulia> simulation.success[]\ntrue\n\njulia> size(DataFrame(simulation))\n(100, 9)\n\nFurther keyword arguments:\n\nstarting_step = 1: Starting step of the simulation.\nwall_time = Inf: Maximum time allowed for the simulation.\nsimulation_plan = SimulationPlan(; starting_step, last_step, wall_time): Defines the duration of the simulation. Takes precedence over last_step and wall_time.\nζ = 0.08: Damping parameter for the shift update.\nξ = ζ^2/4: Forcing parameter for the shift update.\nshift_strategy = DoubleLogUpdate(; target_walkers, ζ, ξ): How to update the shift, see ShiftStrategy.\ntime_step_strategy = ConstantTimeStep(): Adjust time step or not, see TimeStepStrategy.\nalgorithm = FCIQMC(; shift_strategy, time_step_strategy): The algorithm to use. Currenlty only FCIQMC is implemented.\nshift: Initial shift value or collection of shift values. Determined by default from the Hamiltonian and the starting vectors.\ninitial_shift_parameters: Initial shift parameters or collection of initial shift parameters. Overrides shift if provided.\nmax_length = 2 * target_walkers + 100: Maximum length of the vectors.\ndisplay_name = \"PMCSimulation\": Name displayed in progress bar (via ProgressLogging).\nmetadata: User-supplied metadata to be added to the report. Must be an iterable of pairs or a NamedTuple, e.g. metadata = (\"key1\" => \"value1\", \"key2\" => \"value2\"). All metadata is converted to strings.\nrandom_seed = true: Provide and store a seed for the random number generator. If set to true, a new random seed is generated from RandomDevice(). If set to number, this number is used as the seed. This seed is used by solve (and init) to re-seed the default random number generator (consistently on each MPI rank) such that solveing the same ProjectorMonteCarloProblem twice will yield identical results. If set to false, no seed is used and consecutive random numbers are used.\nminimum_size = 2*num_spectral_states(spectral_strategy): The minimum size of the basis used to construct starting vectors for simulations of spectral states, if start_at is not provided.\n\nSee also init, solve.\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.ReplicaState","page":"API","title":"Rimu.ReplicaState","text":"ReplicaState <: AbstractMatrix{SingleState}\n\nHolds information about multiple replicas of SpectralStates. Indexing the ReplicaState state[i, j] returns a SingleState from the ith replica and jth spectral state.\n\nFields\n\nspectral_states: Tuple of SpectralStates\nmax_length::Ref{Int}: Maximum length of the simulation\nstep::Ref{Int}: Current step of the simulation\nsimulation_plan: Simulation plan\nreporting_strategy: Reporting strategy\npost_step_strategy: Post-step strategy\nreplica_strategy: Replica strategy\n\nSee also ReplicaStrategy, Rimu.SpectralState, Rimu.SingleState, Rimu.PMCSimulation.\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.ReplicaStrategy","page":"API","title":"Rimu.ReplicaStrategy","text":"ReplicaStrategy{N}\n\nSupertype for strategies that can be passed to ProjectorMonteCarloProblem and control how many replicas are used, and what information is computed and returned. The number of replicas is N.\n\nConcrete implementations\n\nNoStats: run (possibly one) replica(s), but don't report any additional info.\nAllOverlaps: report overlaps between all pairs of replica vectors.\n\nInterface\n\nA subtype of ReplicaStrategy{N} must implement the following function:\n\nRimu.replica_stats - return a tuple of Strings or Symbols of names for replica statistics and a tuple of the values. These will be reported to the DataFrame returned by ProjectorMonteCarloProblem.\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.Report","page":"API","title":"Rimu.Report","text":"Report()\nReport(df::DataFrame)\n\nInternal structure that holds the temporary reported values as well as metadata. It can be converted to a DataFrame with DataFrame(report::Report).\n\nSee report!, report_metadata!, get_metadata.\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.ReportDFAndInfo","page":"API","title":"Rimu.ReportDFAndInfo","text":"ReportDFAndInfo(; reporting_interval=1, info_interval=100, io=stdout, writeinfo=false) <: ReportingStrategy\n\nThe default ReportingStrategy for ProjectorMonteCarloProblem. Report every reporting_intervalth step to a DataFrame and write info message to io every info_intervalth reported step (unless writeinfo == false). The flag writeinfo is useful for controlling info messages in MPI codes, e.g. by setting writeinfo =is_mpi_root().\n\nSee also ProjectorMonteCarloProblem, ReportToFile.\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.ReportToFile","page":"API","title":"Rimu.ReportToFile","text":"ReportToFile(; kwargs...) <: ReportingStrategy\n\nReportingStrategy for ProjectorMonteCarloProblem that writes the report directly to a file in the Arrow format. Useful when dealing with long jobs or large numbers of replicas, when the report can incur a significant memory cost.\n\nThe arrow file can be read back in with load_df(filename) or using Arrow; Arrow.Table(filename).\n\nKeyword arguments\n\nfilename = \"out.arrow\": the file to report to. If the file already exists, a new file is created.\nreporting_interval = 1: interval between simulation steps that are reported.\nchunk_size = 1000: the size of each chunk that is written to the file. A DataFrame of this size is collected in memory and written to disk. When saving, an info message is also printed to io.\nsave_if =is_mpi_root(): if this value is true, save the report, otherwise ignore it.\nreturn_df = false: if this value is true, read the file and return the data frame at the end of computation. Otherwise, an empty DataFrame is returned.\nio = stdout: The IO to print messages to. Set to devnull if you don't want to see messages printed out.\ncompress = :zstd: compression algorithm to use. Can be :zstd, :lz4 or nothing.\n\nSee also load_df, save_df, ReportDFAndInfo, and ProjectorMonteCarloProblem.\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.ReportingStrategy","page":"API","title":"Rimu.ReportingStrategy","text":"ReportingStrategy\n\nAbstract type for strategies for reporting data during a simulation of a ProjectorMonteCarloProblem.\n\nImplemented strategies:\n\nReportDFAndInfo\nReportToFile\n\nExtended help\n\nInterface:\n\nA ReportingStrategy can define any of the following:\n\nRimu.refine_reporting_strategy\nRimu.report!\nRimu.report_after_step!\nRimu.finalize_report!\nRimu.reporting_interval\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.RunTillLastStep","page":"API","title":"Rimu.RunTillLastStep","text":"RunTillLastStep(step::Int = 0 # number of current/starting timestep\n laststep::Int = 100 # number of final timestep\n shiftMode::Bool = false # whether to adjust shift\n shift = 0.0 # starting/current value of shift\n dτ::Float64 = 0.01 # current value of time step\n) <: FciqmcRunStrategy\n\nParameters for running lomc!() for a fixed number of time steps. For alternative strategies, see FciqmcRunStrategy.\n\nwarning: Warning\nThe use of this strategy is deprecated. Pass the relevant arguments directly to ProjectorMonteCarloProblem or to lomc!() instead.\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.ShiftStrategy","page":"API","title":"Rimu.ShiftStrategy","text":"ShiftStrategy\n\nAbstract type for defining the strategy for controlling the norm, potentially by updating the shift. Passed as a parameter to ProjectorMonteCarloProblem or to FCIQMC.\n\nImplemented strategies:\n\nDontUpdate\nDoubleLogUpdate - default in ProjectorMonteCarloProblem()\nLogUpdate\nLogUpdateAfterTargetWalkers - FCIQMC standard\nDoubleLogUpdateAfterTargetWalkers\n\nExtended help\n\nInternally To implement a custom strategy, define a new subtype of Rimu.ShiftStrategy and implement methods for:\n\nRimu.update_shift_parameters! - to update the shift_parameters\nRimu.initialise_shift_parameters - (optional) to initialise and construct a custom implementation of the shift_parameters. The default implementation is Rimu.DefaultShiftParameters.\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.SignCoherence","page":"API","title":"Rimu.SignCoherence","text":"SignCoherence(reference[; name=:coherence]) <: PostStepStrategy\n\nAfter each step, compute the proportion of configurations that have the same sign as they do in the reference_dvec. Reports to a column named name, which defaults to coherence.\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.SimulationPlan","page":"API","title":"Rimu.SimulationPlan","text":"SimulationPlan(; starting_step = 1, last_step = 100, wall_time = Inf)\n\nDefines the duration of the simulation. The simulation ends when the last_step is reached or the wall_time is exceeded.\n\nSee ProjectorMonteCarloProblem, PMCSimulation.\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.SingleParticleDensity","page":"API","title":"Rimu.SingleParticleDensity","text":"SingleParticleDensity(; save_every=1, component) <: PostStepStrategy\n\nPostStepStrategy to compute the diagonal single_particle_density. It records a Tuple with the same eltype as the vector.\n\nComputing the density at every time step can be expensive. This cost can be reduced by setting the save_every argument to a higher value. If the value is set, a vector of zeros is recorded when the saving is skipped.\n\nIf the address type has multiple components, the component argument can be used to compute the density on a per-component basis.\n\nThe density is not normalized, and must be divided by the vector norm(⋅,2) squared.\n\nSee also\n\nsingle_particle_density\nDensityMatrixDiagonal\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.SingleState","page":"API","title":"Rimu.SingleState","text":"SingleState(hamiltonian, algorithm, v, wm, pnorm, params, id)\n\nStruct that holds a single state vector and all information needed for an independent run of the algorithm. Can be advanced a step forward with Rimu.advance!.\n\nFields\n\nhamiltonian: Hamiltonian\nalgorithm: Algorithm\nv: Vector\npv: Previous vector\nwm: Working memory\nshift_parameters: Shift parameters\nid::String: id is appended to column names\n\nSee also SpectralStrategy, ReplicaStrategy, Rimu.SpectralState, Rimu.ReplicaState, Rimu.replica_stats, Rimu.PMCSimulation.\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.SpectralState","page":"API","title":"Rimu.SpectralState","text":"SpectralState <: AbstractVector{SingleState}\n\nHolds one or several Rimu.SingleStates representing the ground state and excited states of a single replica. Indexing the SpectralState state[i] returns the ith SingleState.\n\nFields\n\nsingle_states: Tuple of SingleStates\nspectral_strategy: Strategy for computing the spectral states\nid::String: Identifies the replica\n\nSee also SpectralStrategy, Rimu.ReplicaState, Rimu.SingleState, Rimu.PMCSimulation.\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.SpectralStrategy","page":"API","title":"Rimu.SpectralStrategy","text":"SpectralStrategy{S}\n\nAbstract type for spectral strategies. The spectral strategy is used to control the number of spectral states used in the simulation.\n\nImplemented Strategies\n\nGramSchmidt: Orthogonalize the spectral states using the Gram-Schmidt procedure.\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.StateVectors","page":"API","title":"Rimu.StateVectors","text":"StateVectors <: AbstractMatrix{V}\n\nRepresents a matrix of configuration vectors from the state. Construct this object with state_vectors.\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.TimeStepStrategy","page":"API","title":"Rimu.TimeStepStrategy","text":"TimeStepStrategy\n\nAbstract type for strategies for updating the time step with update_time_step(). Implemented strategies:\n\nConstantTimeStep\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.Timer","page":"API","title":"Rimu.Timer","text":"Timer <: PostStepStrategy\n\nRecord current time after every step. See Base.Libc.time for information on what time is recorded.\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.WalkerLoneliness","page":"API","title":"Rimu.WalkerLoneliness","text":"WalkerLoneliness(threshold=1) <: PostStepStrategy\n\nAfter each step, compute the proportion of configurations that are occupied by at most threshold walkers. Reports to a column named loneliness.\n\n\n\n\n\n","category":"type"},{"location":"API.html#CommonSolve.init-Tuple{ProjectorMonteCarloProblem}","page":"API","title":"CommonSolve.init","text":"init(problem::ProjectorMonteCarloProblem; copy_vectors=true)::PMCSimulation\n\nInitialise a Rimu.PMCSimulation.\n\nSee also ProjectorMonteCarloProblem, solve!, solve, step!, Rimu.PMCSimulation.\n\n\n\n\n\n","category":"method"},{"location":"API.html#CommonSolve.solve","page":"API","title":"CommonSolve.solve","text":"solve(::ProjectorMonteCarloProblem)::PMCSimulation\n\nInitialize and solve a ProjectorMonteCarloProblem until the last step is completed or the wall time limit is reached.\n\nSee also init, solve!, step!, Rimu.PMCSimulation, and solve(::ExactDiagonalizationProblem).\n\n\n\n\n\n","category":"function"},{"location":"API.html#CommonSolve.solve!-Tuple{Rimu.PMCSimulation}","page":"API","title":"CommonSolve.solve!","text":"solve!(sm::PMCSimulation; kwargs...)::PMCSimulation\n\nSolve a Rimu.PMCSimulation until the last step is completed or the wall time limit is reached.\n\nTo continue a previously completed simulation, set a new last_step or wall_time using the keyword arguments. Optionally, changes can be made to the replica_strategy, the post_step_strategy, or the reporting_strategy.\n\nOptional keyword arguments:\n\nlast_step = nothing: Set the last step to a new value and continue the simulation.\nwall_time = nothing: Set the allowed wall time to a new value and continue the simulation.\nreset_time = false: Reset the elapsed_time counter and continue the simulation.\nempty_report = false: Empty the report before continuing the simulation.\nreplica_strategy = nothing: Change the replica strategy. Requires the number of replicas to match the number of replicas in the simulation sm. Implies empty_report = true.\npost_step_strategy = nothing: Change the post-step strategy. Implies empty_report = true.\nreporting_strategy = nothing: Change the reporting strategy. Implies empty_report = true.\nmetadata = nothing: Add metadata to the report.\n\nSee also ProjectorMonteCarloProblem, init, solve, step!, Rimu.PMCSimulation.\n\n\n\n\n\n","category":"method"},{"location":"API.html#CommonSolve.step!-Tuple{Rimu.PMCSimulation}","page":"API","title":"CommonSolve.step!","text":"step!(sm::PMCSimulation)::PMCSimulation\n\nAdvance the simulation by one step.\n\nCalling solve! will advance the simulation until the last step or the wall time is exceeded. When completing the simulation without calling solve!, the simulation report needs to be finalised by calling Rimu.finalize_report!.\n\nSee also ProjectorMonteCarloProblem, init, solve!, solve, Rimu.PMCSimulation.\n\n\n\n\n\n","category":"method"},{"location":"API.html#Rimu.advance!-Tuple{FCIQMC, Any, Rimu.ReplicaState, Rimu.SingleState}","page":"API","title":"Rimu.advance!","text":"advance!(algorithm::PMCAlgorithm, report::Report, state::ReplicaState, s_state::SingleState)\n\nAdvance the s_state by one step according to the algorithm. The state is used only to access the various strategies involved. Steps, stats, and computed quantities are written to the report.\n\nReturns true if the step was successful and calculation should proceed, false when it should terminate.\n\nSee also solve!, step!.\n\n\n\n\n\n","category":"method"},{"location":"API.html#Rimu.all_overlaps-Union{Tuple{B}, Tuple{N}, Tuple{Union{Tuple, Vector}, NTuple{N, AbstractDVec}, Any, Val{B}}} where {N, B}","page":"API","title":"Rimu.all_overlaps","text":"all_overlaps(operators, vectors, working_memories, vecnorm=true)\n\nGet all overlaps between vectors and operators. The flag vecnorm can disable the vector-vector overlap c{i}_dot_c{j}.\n\n\n\n\n\n","category":"method"},{"location":"API.html#Rimu.check_transform-Tuple{AllOverlaps, AbstractHamiltonian}","page":"API","title":"Rimu.check_transform","text":"check_transform(r::AllOverlaps, ham)\n\nCheck that the transformation provided to r::AllOverlaps matches the given Hamiltonian ham. Used as a sanity check before starting main ProjectorMonteCarloProblem loop.\n\n\n\n\n\n","category":"method"},{"location":"API.html#Rimu.clean_and_warn_if_others_present-Union{Tuple{names}, Tuple{NamedTuple{names}, Any}} where names","page":"API","title":"Rimu.clean_and_warn_if_others_present","text":"clean_and_warn_if_others_present(nt::NamedTuple{names}, keys) where {names}\n\nRemove keys from a NamedTuple that are not in keys and issue a warning if they are present.\n\n\n\n\n\n","category":"method"},{"location":"API.html#Rimu.default_logger-Tuple","page":"API","title":"Rimu.default_logger","text":"default_logger(args...)\n\nReset the global_logger to Logging.ConsoleLogger. Undoes the effect of smart_logger. Arguments are passed on to Logging.ConsoleLogger.\n\n\n\n\n\n","category":"method"},{"location":"API.html#Rimu.default_starting_vector-Tuple{AbstractHamiltonian}","page":"API","title":"Rimu.default_starting_vector","text":"default_starting_vector(hamiltonian::AbstractHamiltonian; kwargs...)\ndefault_starting_vector(\n address=starting_address(hamiltonian);\n style=IsDynamicSemistochastic(),\n initiator=NonInitiator(),\n threading=nothing,\n population=10\n)\n\nReturn a default starting vector for ProjectorMonteCarloProblem. The default choice for the starting vector is\n\nv = PDVec(address => population; style, initiator)\n\nif threading is available, or otherwise\n\nv = DVec(address => population; style)\n\nif initiator == NonInitiator(), and\n\nv = InitiatorDVec(address => population; style, initiator)\n\nif not. See PDVec, DVec, InitiatorDVec, StochasticStyle, and InitiatorRule.\n\n\n\n\n\n","category":"method"},{"location":"API.html#Rimu.delete_and_warn_if_present-Union{Tuple{names}, Tuple{NamedTuple{names}, Any}} where names","page":"API","title":"Rimu.delete_and_warn_if_present","text":"delete_and_warn_if_present(nt::NamedTuple, keys)\n\nDelete keys from a NamedTuple and issue a warning if they are present. This is useful for removing unused keyword arguments.\n\n\n\n\n\n","category":"method"},{"location":"API.html#Rimu.finalize_report!-Tuple{ReportingStrategy, Any}","page":"API","title":"Rimu.finalize_report!","text":"finalize_report!(::ReportingStrategy, report)\n\nFinalize the report. This function is called after all steps in solve! have finished.\n\n\n\n\n\n","category":"method"},{"location":"API.html#Rimu.get_metadata-Tuple{Rimu.Report, Any}","page":"API","title":"Rimu.get_metadata","text":"get_metadata(report::Report, key)\n\nGet metadata key from report. key is converted to a String.\n\nSee also report_metadata!, Report, report!.\n\n\n\n\n\n","category":"method"},{"location":"API.html#Rimu.initialise_shift_parameters","page":"API","title":"Rimu.initialise_shift_parameters","text":"initialise_shift_parameters(s::ShiftStrategy, shift, norm, time_step, counter=0, shift_mode=false)\n\nInitiatlise a struct to store the shift parameters.\n\nSee ShiftStrategy, update_shift_parameters!, DefaultShiftParameters.\n\n\n\n\n\n","category":"function"},{"location":"API.html#Rimu.is_mpi_root","page":"API","title":"Rimu.is_mpi_root","text":"is_mpi_root(root = mpi_root)\n\nReturns true if called from the root rank\n\n\n\n\n\n","category":"function"},{"location":"API.html#Rimu.lomc!-Tuple{Any, Any}","page":"API","title":"Rimu.lomc!","text":"lomc!(ham::AbstractHamiltonian, [v]; kwargs...) -> df, state\nlomc!(state::ReplicaState, [df]; kwargs...) -> df, state\n\nLinear operator Monte Carlo: Perform a projector quantum Monte Carlo simulation for determining the lowest eigenvalue of ham. The details of the simulation are controlled by the optional keyword arguments and by the type of the optional starting vector v. Alternatively, a ReplicaState can be passed in to continue a previous simulation.\n\nCommon keyword arguments and defaults:\n\nlaststep = 100 - controls the number of steps.\ndτ = 0.01 - time step.\ntargetwalkers = 1000 - target for the 1-norm of the coefficient vector.\naddress = starting_address(ham) - set starting address for default v and shift.\nstyle = IsStochasticInteger() - set StochasticStyle for default v; unused if v is specified.\ninitiator = NonInitiator() - set InitiatorRule for default v; unused if v is specified.\nthreading - default is to use multithreading and MPI if multiple threads are available. Set to true to force PDVec for the starting vector, false for serial computation; unused if v is specified.\nshift = diagonal_element(ham, address) - initial value of shift.\npost_step_strategy::NTuple{N,<:PostStepStrategy} = () - extract observables (e.g. ProjectedEnergy), see PostStepStrategy. (Deprecated: post_step is accepted as an alias for post_step_strategy.)\nreplica_strategy::ReplicaStrategy = NoStats(1) - run several synchronised simulations, see ReplicaStrategy. (Deprecated: replica is accepted as an alias for replica_strategy.)\nreporting_strategy::ReportingStrategy = ReportDFAndInfo() - how and when to report results, see ReportingStrategy. (Deprecated: r_strat is accepted as an alias for reporting_strategy.)\nname = \"lomc!\" - name displayed in progress bar (via ProgressLogging)\nmetadata - user-supplied metadata to be added to the report df. Must be an iterable of pairs or a NamedTuple, e.g. metadata = (\"key1\" => \"value1\", \"key2\" => \"value2\"). All metadata is converted to strings.\n\nSome metadata is automatically added to the report df including Rimu.PACKAGE_VERSION and data from state.\n\nReturn values\n\nlomc! returns a named tuple with the following fields:\n\ndf: a DataFrame with all statistics being reported.\nstate: a ReplicaState that can be used for continuations.\n\nExample\n\njulia> address = BoseFS(1,2,3);\n\njulia> hamiltonian = HubbardReal1D(address);\n\njulia> df1, state = @suppress lomc!(hamiltonian; targetwalkers=500, laststep=100);\n\njulia> df2, _ = @suppress lomc!(state, df1; laststep=200, metadata=(;info=\"cont\")); # Continuation run\n\njulia> size(df1)\n(100, 9)\n\njulia> size(df2)\n(200, 9)\n\njulia> using DataFrames; metadata(df2, \"info\") # retrieve custom metadata\n\"cont\"\n\njulia> metadata(df2, \"hamiltonian\") # some metadata is automatically added\n\"HubbardReal1D(fs\\\"|1 2 3⟩\\\"; u=1.0, t=1.0)\"\n\nFurther keyword arguments and defaults:\n\nτ_strat::TimeStepStrategy = ConstantTimeStep() - adjust time step or not, see TimeStepStrategy\ns_strat::ShiftStrategy = DoubleLogUpdate(; target_walkers=targetwalkers, ζ = 0.08, ξ = ζ^2/4) - how to update the shift, see ShiftStrategy.\nmaxlength = 2 * s_strat.target_walkers + 100 - upper limit on the length of v; when reached, lomc! will abort\nwm - working memory for re-use in subsequent calculations; is mutated.\ndf = DataFrame() - when called with AbstractHamiltonian argument, a DataFrame can be passed for merging with the report df.\n\nThe default choice for the starting vector is v = default_starting_vector(; address, style, threading, initiator). See default_starting_vector, PDVec, DVec, StochasticStyle, and InitiatorRule.\n\nwarning: Warning\nThe use of this lomc! is deprecated. Use ProjectorMonteCarloProblem and solve instead.\n\n\n\n\n\n","category":"method"},{"location":"API.html#Rimu.mpi_allprintln-Tuple","page":"API","title":"Rimu.mpi_allprintln","text":"mpi_allprintln(args...)\n\nPrint a message to stdout from each rank separately, in order. MPI synchronizing.\n\n\n\n\n\n","category":"method"},{"location":"API.html#Rimu.mpi_barrier","page":"API","title":"Rimu.mpi_barrier","text":"mpi_barrier(comm = mpi_comm())\n\nThe MPI barrier with optional argument. MPI syncronizing.\n\n\n\n\n\n","category":"function"},{"location":"API.html#Rimu.mpi_rank","page":"API","title":"Rimu.mpi_rank","text":"mpi_rank(comm = mpi_comm())\n\nReturn the current MPI rank.\n\n\n\n\n\n","category":"function"},{"location":"API.html#Rimu.mpi_seed!","page":"API","title":"Rimu.mpi_seed!","text":"mpi_seed!(seed = rand(Random.RandomDevice(), UInt))\n\nRe-seed the random number generators in an MPI-safe way. If seed is provided, the random numbers from rand will follow a deterministic sequence.\n\nIndependence of the random number generators on different MPI ranks is achieved by adding hash(mpi_rank()) to seed.\n\n\n\n\n\n","category":"function"},{"location":"API.html#Rimu.mpi_size","page":"API","title":"Rimu.mpi_size","text":"mpi_size(comm = mpi_comm())\n\nSize of MPI communicator.\n\n\n\n\n\n","category":"function"},{"location":"API.html#Rimu.num_replicas-Union{Tuple{ReplicaStrategy{N}}, Tuple{N}} where N","page":"API","title":"Rimu.num_replicas","text":"num_replicas(state_or_strategy)\n\nReturn the number of replicas used in the simulation.\n\n\n\n\n\n","category":"method"},{"location":"API.html#Rimu.num_spectral_states-Union{Tuple{Rimu.SpectralStrategy{S}}, Tuple{S}} where S","page":"API","title":"Rimu.num_spectral_states","text":"num_spectral_states(state_or_strategy)\n\nReturn the number of spectral states used in the simulation.\n\n\n\n\n\n","category":"method"},{"location":"API.html#Rimu.post_step_action","page":"API","title":"Rimu.post_step_action","text":"post_step_action(::PostStepStrategy, ::SingleState, step) -> kvpairs\n\nCompute statistics after FCIQMC step. Should return a tuple of :key => value pairs. This function is only called every reporting_interval steps, as defined by the ReportingStrategy.\n\nSee also PostStepStrategy, ReportingStrategy.\n\n\n\n\n\n","category":"function"},{"location":"API.html#Rimu.refine_reporting_strategy-Tuple{ReportingStrategy}","page":"API","title":"Rimu.refine_reporting_strategy","text":"refine_reporting_strategy(reporting_strategy::ReportingStrategy) -> reporting_strategy\n\nInitialize the reporting strategy. This can be used to set up filenames or other attributes that need to be unique for a run of FCIQMC.\n\n\n\n\n\n","category":"method"},{"location":"API.html#Rimu.replace_keys-Tuple{NamedTuple, Any}","page":"API","title":"Rimu.replace_keys","text":"replace_keys(nt::NamedTuple, (:old1 => :new1, :old2 => :new2, ...))\n\nReplace keys in a NamedTuple with new keys. This is useful for renaming fields in a NamedTuple. Ignores keys that are not present in the NamedTuple.\n\n\n\n\n\n","category":"method"},{"location":"API.html#Rimu.replica_stats","page":"API","title":"Rimu.replica_stats","text":"replica_stats(RS::ReplicaStrategy{N}, spectral_states::NTuple{N,SingleState}) -> (names, values)\n\nReturn the names and values of statistics related to N replica states consistent with the ReplicaStrategy RS. names should be a tuple of Symbols or Strings and values should be a tuple of the same length. This function will be called every reporting_interval steps from ProjectorMonteCarloProblem, or once per time step if reporting_interval is not defined.\n\nPart of the ReplicaStrategy interface. See also SingleState.\n\n\n\n\n\n","category":"function"},{"location":"API.html#Rimu.report!-Tuple{ReportingStrategy, Any, Vararg{Any}}","page":"API","title":"Rimu.report!","text":" report!(::ReportingStrategy, step, report::Report, keys, values, id=\"\")\n report!(::ReportingStrategy, step, report::Report, nt, id=\"\")\n\nReport keys and values to report, which will be converted to a DataFrame before ProjectorMonteCarloProblem exits. Alternatively, a nt::NamedTuple can be passed in place of keys and values. If id is specified, it is appended to all keys. This is used to differentiate between values reported by different replicas.\n\nTo overload this function for a new ReportingStrategy, overload report!(::ReportingStrategy, step, args...) and apply the report by calling report!(args...).\n\n\n\n\n\n","category":"method"},{"location":"API.html#Rimu.report!-Tuple{Rimu.Report, DataFrame}","page":"API","title":"Rimu.report!","text":"report!(report::Report, df::DataFrame)\n\nConvert the DataFrame df to a Report. This function does not copy the data.\n\n\n\n\n\n","category":"method"},{"location":"API.html#Rimu.report!-Tuple{Rimu.Report, Union{AbstractString, Symbol}, Any}","page":"API","title":"Rimu.report!","text":"report!(report, keys, values, id=\"\")\nreport!(report, pairs, id=\"\")\n\nWrite keys, values pairs to report that will be converted to a DataFrame later. Alternatively, a named tuple or a collection of pairs can be passed instead of keys and values.\n\nThe value of id is appended to the name of the column, e.g. report!(report, :key, value, :_1) will report value to a column named :key_1.\n\n\n\n\n\n","category":"method"},{"location":"API.html#Rimu.report_after_step!-Tuple{ReportingStrategy, Any, Any, Vararg{Any}}","page":"API","title":"Rimu.report_after_step!","text":"report_after_step!(::ReportingStrategy, step, report, state) -> report\n\nThis function is called at the very end of a step, after Rimu.reporting_interval steps. It may modify the report.\n\n\n\n\n\n","category":"method"},{"location":"API.html#Rimu.report_metadata!-Tuple{Rimu.Report, Any, Any}","page":"API","title":"Rimu.report_metadata!","text":"report_metadata!(report::Report, key, value)\nreport_metadata!(report::Report, kvpairs)\n\nSet metadata key to value in report. key and value are converted to Strings. Alternatively, an iterable of key-value pairs or a NamedTuple can be passed.\n\nSee also get_metadata, report!, Report.\n\n\n\n\n\n","category":"method"},{"location":"API.html#Rimu.reporting_interval-Tuple{ReportingStrategy}","page":"API","title":"Rimu.reporting_interval","text":"reporting_interval(::ReportingStrategy)\n\nGet the interval between steps for which non-essential statistics are reported. Defaults to 1 if chosen ReportingStrategy does not specify an interval.\n\n\n\n\n\n","category":"method"},{"location":"API.html#Rimu.set_up_initial_shift_parameters-Union{Tuple{S}, Tuple{R}, Tuple{FCIQMC, Any, StaticArraysCore.SMatrix{R, S}, Any, Any}} where {R, S}","page":"API","title":"Rimu.set_up_initial_shift_parameters","text":"set_up_initial_shift_parameters(\n algorithm::FCIQMC, hamiltonian, starting_vectors, shift, time_step, initial_shift_parameters\n)\n\nSet up the initial shift parameters for the FCIQMC algorithm.\n\n\n\n\n\n","category":"method"},{"location":"API.html#Rimu.single_particle_density-Tuple{Any}","page":"API","title":"Rimu.single_particle_density","text":"single_particle_density(dvec; component)\nsingle_particle_density(add; component)\n\nCompute the diagonal single particle density of vector dvec or address add. If the component argument is given, only that component of the addresses is taken into account. The result is always normalized so that sum(result) ≈ num_particles(address).\n\nExamples\n\njulia> v = DVec(fs\"|⋅↑⇅↓⋅⟩\" => 1.0, fs\"|↓↓⋅↑↑⟩\" => 0.5)\nDVec{FermiFS2C{2, 2, 5, 4, FermiFS{2, 5, BitString{5, 1, UInt8}}, FermiFS{2, 5, BitString{5, 1, UInt8}}},Float64} with 2 entries, style = IsDeterministic{Float64}()\n fs\"|↓↓⋅↑↑⟩\" => 0.5\n fs\"|⋅↑⇅↓⋅⟩\" => 1.0\n\njulia> single_particle_density(v)\n(0.2, 1.0, 1.6, 1.0, 0.2)\n\njulia> single_particle_density(v; component=1)\n(0.0, 0.8, 0.8, 0.2, 0.2)\n\nSee also\n\nSingleParticleDensity\n\n\n\n\n\n","category":"method"},{"location":"API.html#Rimu.smart_logger-Tuple","page":"API","title":"Rimu.smart_logger","text":"smart_logger(args...)\n\nEnable terminal progress bar during interactive use (i.e. unless running on CI or HPC). Arguments are passed on to the logger. This is run once during Rimu startup. Undo with default_logger or by setting Base.global_logger().\n\n\n\n\n\n","category":"method"},{"location":"API.html#Rimu.state_vectors-Tuple{R} where R<:Rimu.ReplicaState","page":"API","title":"Rimu.state_vectors","text":"state_vectors(state::ReplicaState)\nstate_vectors(sim::PMCSimulation)\n\nReturn an r×s AbstractMatrix of configuration vectors from the state, or the result of solve(::ProjectorMonteCarloProblem). The vectors can be accessed by indexing the resulting collection, where the row index corresponds to the replica index and the column index corresponds to the spectral state index.\n\nSee also ProjectorMonteCarloProblem, Rimu.PMCSimulation, Rimu.SingleState, Rimu.ReplicaState, Rimu.SpectralState.\n\n\n\n\n\n","category":"method"},{"location":"API.html#Rimu.update_shift_parameters!","page":"API","title":"Rimu.update_shift_parameters!","text":"update_shift_parameters!(\n s <: ShiftStrategy,\n shift_parameters,\n tnorm,\n v_new,\n v_old,\n step,\n report\n) -> shift_stats, proceed\n\nUpdate the shift_parameters according to strategy s. See ShiftStrategy. Returns a named tuple of the shift statistics and a boolean proceed indicating whether the simulation should proceed.\n\nSee initialise_shift_parameters, ShiftStrategy.\n\n\n\n\n\n","category":"function"},{"location":"API.html#Rimu.update_time_step-Tuple{ConstantTimeStep, Any, Vararg{Any}}","page":"API","title":"Rimu.update_time_step","text":"update_time_step(s<:TimeStepStrategy, time_step, tnorm) -> new_time_step\n\nUpdate the time step according to the strategy s.\n\n\n\n\n\n","category":"method"},{"location":"API.html#Rimu.@mpi_root-Tuple","page":"API","title":"Rimu.@mpi_root","text":"@mpi_root expr\n\nEvaluate expression only on the root rank. Extra care needs to be taken as expr must not contain any code that involves syncronising MPI operations, i.e. actions that would require syncronous action of all MPI ranks.\n\nExample:\n\nwn = walkernumber(dv) # an MPI syncronising function call that gathers\n # information from all MPI ranks\n@mpi_root @info \"The current walker number is\" wn # print info message on root only\n\n\n\n\n\n","category":"macro"},{"location":"API.html#Reexported-Submodules","page":"API","title":"Reexported Submodules","text":"","category":"section"},{"location":"API.html#ExactDiagonalization","page":"API","title":"ExactDiagonalization","text":"","category":"section"},{"location":"API.html","page":"API","title":"API","text":"See Exact Diagonalization","category":"page"},{"location":"API.html#Interfaces","page":"API","title":"Interfaces","text":"","category":"section"},{"location":"API.html","page":"API","title":"API","text":"See Module Interfaces","category":"page"},{"location":"API.html#StochasticStyles","page":"API","title":"StochasticStyles","text":"","category":"section"},{"location":"API.html","page":"API","title":"API","text":"See Module StochasticStyles","category":"page"},{"location":"API.html#Hamiltonians","page":"API","title":"Hamiltonians","text":"","category":"section"},{"location":"API.html","page":"API","title":"API","text":"See Module Hamiltonians","category":"page"},{"location":"API.html#BitStringAddresses","page":"API","title":"BitStringAddresses","text":"","category":"section"},{"location":"API.html","page":"API","title":"API","text":"See Module BitStringAddresses","category":"page"},{"location":"API.html#DictVectors","page":"API","title":"DictVectors","text":"","category":"section"},{"location":"API.html","page":"API","title":"API","text":"See Module DictVectors","category":"page"},{"location":"API.html#StatsTools","page":"API","title":"StatsTools","text":"","category":"section"},{"location":"API.html","page":"API","title":"API","text":"See Module StatsTools","category":"page"},{"location":"API.html#Index","page":"API","title":"Index","text":"","category":"section"},{"location":"API.html","page":"API","title":"API","text":"","category":"page"},{"location":"stochasticstyles.html#Module-StochasticStyles","page":"Stochastic styles","title":"Module StochasticStyles","text":"","category":"section"},{"location":"stochasticstyles.html","page":"Stochastic styles","title":"Stochastic styles","text":"StochasticStyles","category":"page"},{"location":"stochasticstyles.html#Rimu.StochasticStyles","page":"Stochastic styles","title":"Rimu.StochasticStyles","text":"This module provides concrete implementations of StochasticStyles, which specify the algorithm used by ProjectorMonteCarloProblem when performing stochastic matrix-vector multiplication.\n\nImplemented stochastic styles:\n\nStochasticStyle: abstract type for stochastic styles\nIsStochasticInteger\nIsDeterministic\nIsStochasticWithThreshold\nIsDynamicSemistochastic\nStyleUnknown\n\nThe offdiagonal spawning is defined in spawning.jl and is controlled by setting a SpawningStrategy.\n\nThe vector compression strategies are defined in compression.jl and are controlled by setting a CompressionStrategy.\n\n\n\n\n\n","category":"module"},{"location":"stochasticstyles.html#Available-StochasticStyles","page":"Stochastic styles","title":"Available StochasticStyles","text":"","category":"section"},{"location":"stochasticstyles.html","page":"Stochastic styles","title":"Stochastic styles","text":"StyleUnknown","category":"page"},{"location":"stochasticstyles.html#Rimu.Interfaces.StyleUnknown","page":"Stochastic styles","title":"Rimu.Interfaces.StyleUnknown","text":"StyleUnknown{T}() <: StochasticStyle\n\nTrait for value types not (currently) compatible with FCIQMC. This style makes it possible to construct dict vectors with unsupported valtypes.\n\nSee also StochasticStyle.\n\n\n\n\n\n","category":"type"},{"location":"stochasticstyles.html","page":"Stochastic styles","title":"Stochastic styles","text":"Modules = [StochasticStyles]\nPages = [\"styles.jl\"]","category":"page"},{"location":"stochasticstyles.html#Rimu.StochasticStyles.IsDeterministic","page":"Stochastic styles","title":"Rimu.StochasticStyles.IsDeterministic","text":"IsDeterministic{T=Float64}(compression=NoCompression()) <: StochasticStyle{T}\n\nPropagate with deterministic vector matrix multiplications. Stochastic compression of the resultant vector (after annihilations) can be triggered by setting the optional compression argument to a relevant CompressionStrategy.\n\nSee also StochasticStyle.\n\n\n\n\n\n","category":"type"},{"location":"stochasticstyles.html#Rimu.StochasticStyles.IsDynamicSemistochastic","page":"Stochastic styles","title":"Rimu.StochasticStyles.IsDynamicSemistochastic","text":"IsDynamicSemistochastic{T=Float64}(; kwargs...) <: StochasticStyle{T}\n\nQMC propagation with floating-point walker numbers and reduced noise. All possible spawns (offdiagonal elements in vector-matrix multiplication) are performed deterministically when number of walkers in a configuration is high, as controlled by the rel_spawning_threshold and abs_spawning_threshold keywords. Stochastic selection of spawns is controlled by the spawning keyword.\n\nBy default, a stochastic vector compression is applied after annihilations are completed. This behaviour can be changed to on-the-fly projection (as in IsStochasticInteger or IsStochasticWithThreshold) by setting late_compression=false, or modifying spawning and compression. See parameters below for a more detailed explanation.\n\nParameters:\n\nthreshold = 1.0: Values below this number are stochastically projected to this value or zero. See also ThresholdCompression.\nlate_compression = true: If this is set to true, stochastic vector compression is performed after all the spawns are performed. If it is set to false, values are stochastically projected as they are being spawned. late_compression=true is equivalent to setting compression=ThresholdCompression(threshold) and spawning=WithReplacement(). late_compression=false is equivalent to compression=NoCompression() and spawning=WithReplacement(threshold).\nrel_spawning_threshold = 1.0: If the walker number on a configuration times this threshold is greater than the number of offdiagonals, spawning is done deterministically. Should be set to 1 or more for best performance.\nabs_spawning_threshold = Inf: If the walker number on a configuration is greater than this value, spawning is done deterministically. Can be set to e.g. abs_spawning_threshold = 0.1 * target_walkers.\nspawning = WithReplacement(): SpawningStrategy to use for the non-exact spawns.\ncompression = ThresholdCompression(threshold): CompressionStrategy used to compress the vector after a step. Overrides threshold.\n\nSee also StochasticStyle.\n\n\n\n\n\n","category":"type"},{"location":"stochasticstyles.html#Rimu.StochasticStyles.IsStochastic2Pop","page":"Stochastic styles","title":"Rimu.StochasticStyles.IsStochastic2Pop","text":"IsStochastic2Pop{T=Complex{Int}}() <: StochasticStyle{T}\n\nStochastic propagation with complex walker numbers representing two populations of integer walkers.\n\nWhen using this style, make sure to set a complex number as target walkers in the ShiftStrategy!\n\nThis style is experimental.\n\nSee also StochasticStyle.\n\n\n\n\n\n","category":"type"},{"location":"stochasticstyles.html#Rimu.StochasticStyles.IsStochasticInteger","page":"Stochastic styles","title":"Rimu.StochasticStyles.IsStochasticInteger","text":"IsStochasticInteger{T=Int}() <: StochasticStyle{T}\n\nFCIQMC algorithm with integer walkers as in Booth et al. (2009). During the vector matrix product each individual diagonal and spawning step is rounded stochastically to a nearby integer value.\n\nSee also StochasticStyle.\n\n\n\n\n\n","category":"type"},{"location":"stochasticstyles.html#Rimu.StochasticStyles.IsStochasticWithThreshold","page":"Stochastic styles","title":"Rimu.StochasticStyles.IsStochasticWithThreshold","text":"IsStochasticWithThreshold{T=Float64}(threshold=1.0) <: StochasticStyle{T}\n\nStochastic propagation with floating point walker numbers. During the vector matrix product each individual diagonal and spawning result is rounded stochastically if smaller than threshold (before annihilations). For a more customizable stochastic style, see IsDynamicSemistochastic.\n\nSee also StochasticStyle.\n\n\n\n\n\n","category":"type"},{"location":"stochasticstyles.html#The-StochasticStyle-interface","page":"Stochastic styles","title":"The StochasticStyle interface","text":"","category":"section"},{"location":"stochasticstyles.html","page":"Stochastic styles","title":"Stochastic styles","text":"StochasticStyle\nstep_stats\napply_column!\ndefault_style","category":"page"},{"location":"stochasticstyles.html#Rimu.Interfaces.StochasticStyle","page":"Stochastic styles","title":"Rimu.Interfaces.StochasticStyle","text":"StochasticStyle(v)\n\nAbstract type. When called as a function it returns the native style of the generalised vector v that determines how simulations are to proceed.\n\nUsage\n\nConcrete StochasticStyles can be used for the style keyword argument of ProjectorMonteCarloProblem, DVec and PDVec. The following styles are available:\n\nIsStochasticInteger\nIsDeterministic\nIsStochasticWithThreshold\nIsDynamicSemistochastic\nStyleUnknown\n\nExtended Help\n\nInterface\n\nWhen defining a new StochasticStyle, subtype it as MyStyle<:StochasticStyle{T} where T is the concrete value type the style is designed to work with.\n\nFor it to work with ProjectorMonteCarloProblem, a StochasticStyle must define the following:\n\napply_column!(::StochasticStyle, w, H, address, value)\nstep_stats(::StochasticStyle)\n\nand optionally\n\nCompressionStrategy(::StochasticStyle) for vector compression after annihilations,\n\nSee also StochasticStyles, Interfaces.\n\n\n\n\n\n","category":"type"},{"location":"stochasticstyles.html#Rimu.Interfaces.step_stats","page":"Stochastic styles","title":"Rimu.Interfaces.step_stats","text":"step_stats(::StochasticStyle)\nstep_stats(::CompressionStrategy)\n\nReturn a tuple of stat names (Symbol or String) and a tuple of zeros of the same length. These will be reported as columns in the DataFrame returned by ProjectorMonteCarloProblem.\n\n\n\n\n\n","category":"function"},{"location":"stochasticstyles.html#Rimu.Interfaces.apply_column!","page":"Stochastic styles","title":"Rimu.Interfaces.apply_column!","text":"apply_column!(v, op, addr, num, boost=1) -> stats::Tuple\n\nApply the product of column addr of the operator op and the scalar num to the vector v according to the StochasticStyle of v. By expectation value this should be equivalent to\n\nv .+= op[:, add] .* num\n\nThis is used to perform the spawning step in FCIQMC and to implement operator-vector multiplications. Mutates v and reports spawning statistics.\n\nThe boost argument multiplicatively increases the number of spawns to be performed without affecting the expectation value of the procedure.\n\n\n\n\n\n","category":"function"},{"location":"stochasticstyles.html#Rimu.Interfaces.default_style","page":"Stochastic styles","title":"Rimu.Interfaces.default_style","text":"default_style(::Type)\n\nPick a StochasticStyle based on the value type. Returns StyleUnknown if no known default style is set.\n\n\n\n\n\n","category":"function"},{"location":"stochasticstyles.html#Compression-strategies","page":"Stochastic styles","title":"Compression strategies","text":"","category":"section"},{"location":"stochasticstyles.html","page":"Stochastic styles","title":"Stochastic styles","text":"CompressionStrategy\nNoCompression\nStochasticStyles.ThresholdCompression\ncompress!","category":"page"},{"location":"stochasticstyles.html#Rimu.Interfaces.CompressionStrategy","page":"Stochastic styles","title":"Rimu.Interfaces.CompressionStrategy","text":"CompressionStrategy\n\nThe CompressionStrategy controls how a vector is compressed after a step.\n\nDefault implementation:\n\nNoCompression: no vector compression\n\nUsage\n\nA subtype of CompressionStrategy can be passed as a keyword argument to the constructors for some StochasticStyles. Calling CompressionStrategy(s::StochasticStyle) returns a relevant subtype. The default is NoCompression.\n\nInterface\n\nWhen defining a new CompressionStrategy, subtype it as MyCompressionStrategy <: CompressionStrategy and define these methods:\n\ncompress!(s::CompressionStrategy, v)\ncompress!(s::CompressionStrategy, w, v)\nstep_stats(s::CompressionStrategy)\n\n\n\n\n\n","category":"type"},{"location":"stochasticstyles.html#Rimu.Interfaces.NoCompression","page":"Stochastic styles","title":"Rimu.Interfaces.NoCompression","text":"NoCompression <: CompressionStrategy end\n\nDefault CompressionStrategy. Leaves the vector intact.\n\n\n\n\n\n","category":"type"},{"location":"stochasticstyles.html#Rimu.StochasticStyles.ThresholdCompression","page":"Stochastic styles","title":"Rimu.StochasticStyles.ThresholdCompression","text":"ThresholdCompression(threshold=1) <: CompressionStrategy\n\nCompressionStrategy that compresses a vector by threshold projection. Every entry in the vector with a value below the threshold is either set to zero, or increased to the threshold. The probabilty of setting it to zero is equal to abs(value) / threshold.\n\n\n\n\n\n","category":"type"},{"location":"stochasticstyles.html#Rimu.Interfaces.compress!","page":"Stochastic styles","title":"Rimu.Interfaces.compress!","text":"compress!([::CompressionStrategy,] v) -> ::NTuple{N,::Symbol}, ::NTuple{N}\ncompress!([::CompressionStrategy,] w, v) -> ::NTuple{N,::Symbol}, ::NTuple{N}\n\nCompress the vector v. The one-argument version compresses the vector in-place. The two-argument vector stores the result in w. The CompressionStrategy associated with the StochasticStyle of v is used to determine the type of compression.\n\nReturns two tuples, containing the names and values of statistics that are to be reported.\n\n\n\n\n\n","category":"function"},{"location":"stochasticstyles.html#Spawning-strategies-and-convenience-functions","page":"Stochastic styles","title":"Spawning strategies and convenience functions","text":"","category":"section"},{"location":"stochasticstyles.html","page":"Stochastic styles","title":"Stochastic styles","text":"The following functions and types are unexported, but are useful when defining new styles.","category":"page"},{"location":"stochasticstyles.html","page":"Stochastic styles","title":"Stochastic styles","text":"Modules = [StochasticStyles]\nPages = [\"spawning.jl\"]\nOrder = [:function,:method,:type]","category":"page"},{"location":"stochasticstyles.html#Rimu.StochasticStyles.diagonal_step!","page":"Stochastic styles","title":"Rimu.StochasticStyles.diagonal_step!","text":"diagonal_step!(w, op, add, val, threshold=0) -> (clones, deaths, zombies)\n\nPerform diagonal step on a walker add => val. Optional argument threshold sets the projection threshold. If eltype(w) is an Integer, the val is rounded to the nearest integer stochastically.\n\n\n\n\n\n","category":"function"},{"location":"stochasticstyles.html#Rimu.StochasticStyles.projected_deposit!","page":"Stochastic styles","title":"Rimu.StochasticStyles.projected_deposit!","text":"projected_deposit!(w, add, val, parent, threshold=0)\n\nLike deposit!, but performs threshold projection before spawning. If eltype(w) is an Integer, values are stochastically rounded.\n\nReturns the value deposited.\n\n\n\n\n\n","category":"function"},{"location":"stochasticstyles.html#Rimu.StochasticStyles.spawn!","page":"Stochastic styles","title":"Rimu.StochasticStyles.spawn!","text":"spawn!(s::SpawningStrategy, w, op::AbstractHamiltonian, add, val, boost)\nspawn!(s::SpawningStrategy, w, offdiags::AbstractOffdiagonals, add, val, boost)\n\nPerform stochastic spawns to w from address add with val walkers. val * boost controls the number of spawns performed.\n\nThis function should be overloaded in the second form, with offdiags as an argument.\n\nSee SpawningStrategy.\n\n\n\n\n\n","category":"function"},{"location":"stochasticstyles.html#Rimu.StochasticStyles.Bernoulli","page":"Stochastic styles","title":"Rimu.StochasticStyles.Bernoulli","text":"Bernoulli(threshold=0.0) <: SpawningStrategy\n\nPerform Bernoulli sampling. A spawn is attempted on each offdiagonal element with a probability that results in an expected number of spawns equal to the number of walkers on the spawning configuration. This is significantly less efficient than WithReplacement.\n\nIf the number of spawn attempts is greater than the number of offdiagonals, this functions like Exact, but is less efficient. For best performance, this strategy is to be used as a substrategy of DynamicSemistochastic.\n\nParameters\n\nthreshold sets the projection threshold.\n\nspawn! with this strategy returns the number of spawn attempts and the number of spawns.\n\n\n\n\n\n","category":"type"},{"location":"stochasticstyles.html#Rimu.StochasticStyles.DynamicSemistochastic","page":"Stochastic styles","title":"Rimu.StochasticStyles.DynamicSemistochastic","text":"DynamicSemistochastic(; strat, rel_threshold, abs_threshold) <: SpawningStrategy\n\nSpawningStrategy that behaves like strat when the number of walkers is low, but performs exact steps when it is high. What \"high\" means is controlled by the two thresholds described below.\n\nParameters\n\nstrat = WithReplacement(): a SpawningStrategy to use when the multiplication is not performed exactly. If the strat has a threshold different from zero, all spawns will be projected to that threshold.\nrel_threshold = 1.0: When deciding on whether to perform an exact spawn, this value is multiplied to the number of walkers. Should be set to 1 or more for best performance. This threshold is affected by the boost argument to spawn!.\nabs_threshold = Inf: When deciding on whether to perform an exact spawn, min(abs_threshold, num_offdiagonals) is used. This threshold is not affected by the boost argument to spawn!.\n\nSee e.g. WithoutReplacement for a description of the strat.threshold parameter.\n\nspawn! with this strategy returns the numbers of exact and inexact spawns, the number of spawn attempts and the number of spawns.\n\n\n\n\n\n","category":"type"},{"location":"stochasticstyles.html#Rimu.StochasticStyles.Exact","page":"Stochastic styles","title":"Rimu.StochasticStyles.Exact","text":"Exact(threshold=0.0) <: SpawningStrategy\n\nPerform an exact spawning step.\n\nParameters\n\nthreshold sets the projection threshold. If set to zero, no projection is performed.\n\nspawn! with this strategy returns the number of spawn attempts and the number of spawns.\n\n\n\n\n\n","category":"type"},{"location":"stochasticstyles.html#Rimu.StochasticStyles.SingleSpawn","page":"Stochastic styles","title":"Rimu.StochasticStyles.SingleSpawn","text":"SingleSpawn(threshold=0.0) <: SpawningStrategy\n\nPerform a single spawn. Useful as a building block for other stochastic styles.\n\nParameters\n\nthreshold sets the projection threshold. If set to zero, no projection is performed.\n\nspawn! with this strategy returns the number of spawn attempts (always 1) and the number of spawns.\n\n\n\n\n\n","category":"type"},{"location":"stochasticstyles.html#Rimu.StochasticStyles.SpawningStrategy","page":"Stochastic styles","title":"Rimu.StochasticStyles.SpawningStrategy","text":"SpawningStrategy\n\nA SpawningStrategy is used to control how spawns (multiplies with off-diagonal part of the column vector) are performed and can be passed to some of the StochasticStyles as keyword arguments.\n\nThe following concrete implementations are provided:\n\nExact: Perform exact spawns. Used by IsDeterministic.\nWithReplacement: The default stochastic spawning strategy. Spawns are chosen with replacement.\nDynamicSemistochastic: Behave like Exact when the number of spawns performed is high, and like a different substrategy otherwise. Used by IsDynamicSemistochastic.\nSingleSpawn: Perform a single spawn only. Used as a building block for other strategies.\nWithoutReplacement: Similar to WithReplacement, but ensures each spawn is only performed once. Only to be used as a substrategy of DynamicSemistochastic.\nBernoulli: Each spawn is attempted with a fixed probability. Only to be used as a substrategy of DynamicSemistochastic.\n\nInterface\n\nIn order to implement a new SpawningStrategy, define a method for spawn!.\n\n\n\n\n\n","category":"type"},{"location":"stochasticstyles.html#Rimu.StochasticStyles.WithReplacement","page":"Stochastic styles","title":"Rimu.StochasticStyles.WithReplacement","text":"WithReplacement(threshold=0.0) <: SpawningStrategy\n\nSpawningStrategy where spawn targets are sampled with replacement. This is the default spawning strategy for most of the StochasticStyles.\n\nParameters\n\nthreshold sets the projection threshold. If set to zero, no projection is performed.\n\nspawn! with this strategy returns the number of spawn attempts and the number of spawns.\n\n\n\n\n\n","category":"type"},{"location":"stochasticstyles.html#Rimu.StochasticStyles.WithoutReplacement","page":"Stochastic styles","title":"Rimu.StochasticStyles.WithoutReplacement","text":"WithoutReplacement(threshold=0.0) <: SpawningStrategy\n\nSpawningStrategy where spawn targets are sampled without replacement. This strategy needs to allocate a temporary array during spawning, which makes it significantly less efficient than WithReplacement.\n\nIf the number of spawn attempts is greater than the number of offdiagonals, this functions like Exact, but is less efficient. For best performance, this strategy is to be used as a substrategy of DynamicSemistochastic.\n\nParameters\n\nthreshold sets the projection threshold. If set to zero, no projection is performed.\n\nspawn! with this strategy returns the number of spawn attempts and the number of spawns.\n\n\n\n\n\n","category":"type"},{"location":"stochasticstyles.html#Index","page":"Stochastic styles","title":"Index","text":"","category":"section"},{"location":"stochasticstyles.html","page":"Stochastic styles","title":"Stochastic styles","text":"Pages = [\"stochasticstyles.md\"]","category":"page"},{"location":"generated/BHM-example-mpi.html","page":"Rimu with MPI","title":"Rimu with MPI","text":"EditURL = \"../../../scripts/BHM-example-mpi.jl\"","category":"page"},{"location":"generated/BHM-example-mpi.html#Example-2:-Rimu-with-MPI","page":"Rimu with MPI","title":"Example 2: Rimu with MPI","text":"","category":"section"},{"location":"generated/BHM-example-mpi.html","page":"Rimu with MPI","title":"Rimu with MPI","text":"In this example, we will demonstrate using Rimu with MPI. MPI is a standard for parallel and distributed computing, and it is widely used in high-performance computing. Rimu provides support for MPI to enable parallel computations on multiple nodes.","category":"page"},{"location":"generated/BHM-example-mpi.html","page":"Rimu with MPI","title":"Rimu with MPI","text":"A runnable script for this example is located here. Run it with 2 MPI ranks with mpirun -n 2 julia BHM-example-mpi.jl.","category":"page"},{"location":"generated/BHM-example-mpi.html","page":"Rimu with MPI","title":"Rimu with MPI","text":"We start by importing Rimu.","category":"page"},{"location":"generated/BHM-example-mpi.html","page":"Rimu with MPI","title":"Rimu with MPI","text":"using Rimu","category":"page"},{"location":"generated/BHM-example-mpi.html","page":"Rimu with MPI","title":"Rimu with MPI","text":"Note that it is not necessary to initialise the MPI library, as this is already done automatically when Rimu is loaded.","category":"page"},{"location":"generated/BHM-example-mpi.html","page":"Rimu with MPI","title":"Rimu with MPI","text":"We will compute the ground state of a Bose-Hubbard model in momentum space with 10 particles in 10 sites.","category":"page"},{"location":"generated/BHM-example-mpi.html","page":"Rimu with MPI","title":"Rimu with MPI","text":"First, we define the Hamiltonian. We want to start from an address with zero momentum, which is located at mode 5 in the momentum grid. We put all 10 particles, all in the zero momentum mode.","category":"page"},{"location":"generated/BHM-example-mpi.html","page":"Rimu with MPI","title":"Rimu with MPI","text":"address = BoseFS(10, 5 => 10)","category":"page"},{"location":"generated/BHM-example-mpi.html","page":"Rimu with MPI","title":"Rimu with MPI","text":"BoseFS{10,10}(0, 0, 0, 0, 10, 0, 0, 0, 0, 0)","category":"page"},{"location":"generated/BHM-example-mpi.html","page":"Rimu with MPI","title":"Rimu with MPI","text":"We will set the interaction strength u to 6.0. The hopping strength t defaults to 1.0.","category":"page"},{"location":"generated/BHM-example-mpi.html","page":"Rimu with MPI","title":"Rimu with MPI","text":"H = HubbardMom1D(address; u=6.0)","category":"page"},{"location":"generated/BHM-example-mpi.html","page":"Rimu with MPI","title":"Rimu with MPI","text":"HubbardMom1D(fs\"|0 0 0 0 10 0 0 0 0 0⟩\"; u=6.0, t=1.0)","category":"page"},{"location":"generated/BHM-example-mpi.html","page":"Rimu with MPI","title":"Rimu with MPI","text":"We set a reporting strategy. We will use ReportToFile, which writes the reports directly to a file. This is useful for MPI calculations, as they will typically run non-interactively. The reports will be written to disk and can be inspected later. This has the additional benefit of reducing memory use in long-running jobs, as we don't need to keep the results in memory. It also allows us to inspect the results before the computation finishes and recover some data if it fails.","category":"page"},{"location":"generated/BHM-example-mpi.html","page":"Rimu with MPI","title":"Rimu with MPI","text":"The default settings will ensure that only the root MPI rank will write to the file, which is reasonable, and that data is saved in chunks of 1000 time steps. We choose to suppress progress messages with setting io=devnull.","category":"page"},{"location":"generated/BHM-example-mpi.html","page":"Rimu with MPI","title":"Rimu with MPI","text":"reporting_strategy = ReportToFile(\n filename=\"result.arrow\",\n io=devnull\n)","category":"page"},{"location":"generated/BHM-example-mpi.html","page":"Rimu with MPI","title":"Rimu with MPI","text":"ReportToFile{Symbol}(\"result.arrow\", 1, 1000, true, false, Base.DevNull(), :zstd, nothing)","category":"page"},{"location":"generated/BHM-example-mpi.html","page":"Rimu with MPI","title":"Rimu with MPI","text":"For running parallel computations with MPI, it is important that a compatible state vector is used. Here we explicitly set up an MPI-enabled state vector, PDVec, which is automatically MPI-distributed over the available number of MPI ranks. In addition, threading will be used with all threads available to Julia.","category":"page"},{"location":"generated/BHM-example-mpi.html","page":"Rimu with MPI","title":"Rimu with MPI","text":"initial_vector = PDVec(address => 1.0; style=IsDynamicSemistochastic())","category":"page"},{"location":"generated/BHM-example-mpi.html","page":"Rimu with MPI","title":"Rimu with MPI","text":"1-element PDVec: style = IsDynamicSemistochastic{Float64,ThresholdCompression,DynamicSemistochastic}()\n fs\"|0 0 0 0 10 0 0 0 0 0⟩\" => 1.0","category":"page"},{"location":"generated/BHM-example-mpi.html","page":"Rimu with MPI","title":"Rimu with MPI","text":"Now, we can set other parameters as usual. We will perform the computation with 10000 walkers and for 10000 time steps. We will also compute the projected energy by passing a ProjectedEnergy object as a post_step_strategy.","category":"page"},{"location":"generated/BHM-example-mpi.html","page":"Rimu with MPI","title":"Rimu with MPI","text":"problem = ProjectorMonteCarloProblem(H;\n start_at=initial_vector,\n reporting_strategy,\n post_step_strategy=ProjectedEnergy(H, initial_vector),\n target_walkers=10_000,\n time_step=1e-4,\n last_step=10_000\n);","category":"page"},{"location":"generated/BHM-example-mpi.html","page":"Rimu with MPI","title":"Rimu with MPI","text":"The @mpi_root macro performs an action on the root rank only, which is useful for printing.","category":"page"},{"location":"generated/BHM-example-mpi.html","page":"Rimu with MPI","title":"Rimu with MPI","text":"@mpi_root println(\"Running FCIQMC with \", mpi_size(), \" rank(s).\")","category":"page"},{"location":"generated/BHM-example-mpi.html","page":"Rimu with MPI","title":"Rimu with MPI","text":"Running FCIQMC with 1 rank(s).\n","category":"page"},{"location":"generated/BHM-example-mpi.html","page":"Rimu with MPI","title":"Rimu with MPI","text":"Finally, we can run the computation.","category":"page"},{"location":"generated/BHM-example-mpi.html","page":"Rimu with MPI","title":"Rimu with MPI","text":"simulation = solve(problem);\n\n@mpi_root println(\"Simulation success = \", simulation.success)","category":"page"},{"location":"generated/BHM-example-mpi.html","page":"Rimu with MPI","title":"Rimu with MPI","text":"Simulation success = true\n","category":"page"},{"location":"generated/BHM-example-mpi.html","page":"Rimu with MPI","title":"Rimu with MPI","text":"Once the calculation is done, the results are available in the arrow file on disk.","category":"page"},{"location":"generated/BHM-example-mpi.html","page":"Rimu with MPI","title":"Rimu with MPI","text":"In a typical workflow, the simulation results would be loaded from disk and analysed in the REPL or with a separate script. The arrow file can be loaded into a DataFrame with metadata using the load_df function.","category":"page"},{"location":"generated/BHM-example-mpi.html","page":"Rimu with MPI","title":"Rimu with MPI","text":"","category":"page"},{"location":"generated/BHM-example-mpi.html","page":"Rimu with MPI","title":"Rimu with MPI","text":"This page was generated using Literate.jl.","category":"page"},{"location":"index.html#Rimu.jl-Package-Guide","page":"Guide","title":"Rimu.jl Package Guide","text":"","category":"section"},{"location":"index.html","page":"Guide","title":"Guide","text":"Random Integrators for many-body quantum systems","category":"page"},{"location":"index.html","page":"Guide","title":"Guide","text":"The grand aim is to develop a toolbox for many-body quantum systems that can be represented by a Hamiltonian in second quantisation language. Currently supported features include:","category":"page"},{"location":"index.html#Interacting-with-quantum-many-body-models","page":"Guide","title":"Interacting with quantum many-body models","text":"","category":"section"},{"location":"index.html","page":"Guide","title":"Guide","text":"Full configuration interaction quantum Monte Carlo (FCIQMC), a flavour of projector quantum Monte Carlo for stochastically solving the time-independent Schrödinger equation. See References.\nMatrix-free exact diagonalisation of quantum Hamiltonians (with external package KrylovKit.jl).\nSparse matrix representation of quantum Hamiltonians for exact diagonalisation with sparse linear algebra package of your choice (fastest for small systems).","category":"page"},{"location":"index.html#Representing-quantum-many-body-models","page":"Guide","title":"Representing quantum many-body models","text":"","category":"section"},{"location":"index.html","page":"Guide","title":"Guide","text":"A composable and efficient type system for representing single- and multi-component Fock states of bosons, fermions, and mixtures thereof, to be used as a basis for representing Hamiltonians.\nAn interface for defining many-body Hamiltonians.\nPre-defined models include:\nHubbard model in real space for bosons and fermions and mixtures in 1, 2, and 3 spatial dimensions.\nHubbard and related lattice models in momentum space for bosons and fermions in one spatial dimension.\nTranscorrelated Hamiltonian for contact interactions in one dimension for fermions, as described in Jeszenski et al. arXiv:1806.11268.","category":"page"},{"location":"index.html#Statistical-analysis-of-Monte-Carlo-data","page":"Guide","title":"Statistical analysis of Monte Carlo data","text":"","category":"section"},{"location":"index.html","page":"Guide","title":"Guide","text":"Blocking analysis following Flyvberg & Peterson JCP (1989), and automated with hypothesis testing by Jonsson","category":"page"},{"location":"index.html","page":"Guide","title":"Guide","text":"PRE (2018).","category":"page"},{"location":"index.html","page":"Guide","title":"Guide","text":"Unbiased estimators for the ground state energy by re-reweighting following Nightingale & Blöte PRB (1986) and Umrigar et al. JCP (1993).","category":"page"},{"location":"index.html","page":"Guide","title":"Guide","text":"The code supports parallelisation with MPI (harnessing MPI.jl) as well as native Julia threading (experimental). In the future, we may add tools to solve the time-dependent Schrödinger equation and Master equations for open system time evolution.","category":"page"},{"location":"index.html","page":"Guide","title":"Guide","text":"Concept: Joachim Brand and Elke Pahl.","category":"page"},{"location":"index.html","page":"Guide","title":"Guide","text":"Contributors: Joachim Brand, Elke Pahl, Mingrui Yang, Matija Čufar, Chris Bradly.","category":"page"},{"location":"index.html","page":"Guide","title":"Guide","text":"Discussions, help, and additional contributions are acknowledged by Ali Alavi, Didier Adrien, Chris Scott (NeSI), Alexander Pletzer (NeSI).","category":"page"},{"location":"index.html#Installation","page":"Guide","title":"Installation","text":"","category":"section"},{"location":"index.html#Installing-Rimu-for-usage","page":"Guide","title":"Installing Rimu for usage","text":"","category":"section"},{"location":"index.html","page":"Guide","title":"Guide","text":"Rimu is a registered package and can be installed with the package manager. Hit the ] key at the Julia REPL to get into Pkg mode and type","category":"page"},{"location":"index.html","page":"Guide","title":"Guide","text":"pkg> add Rimu","category":"page"},{"location":"index.html","page":"Guide","title":"Guide","text":"Alternatively, use","category":"page"},{"location":"index.html","page":"Guide","title":"Guide","text":"julia> using Pkg; Pkg.add(name=\"Rimu\")","category":"page"},{"location":"index.html","page":"Guide","title":"Guide","text":"in order to install Rimu from a script.","category":"page"},{"location":"index.html#Installing-Rimu-for-development","page":"Guide","title":"Installing Rimu for development","text":"","category":"section"},{"location":"index.html","page":"Guide","title":"Guide","text":"In order to be able to edit the source code, push changes, change and make new git branches, etc., clone the git repository with git clone to a convenient location, e.g. ~/mygitpackagefolder/. Then hit the ] key at the Julia REPL to get into Pkg mode and type","category":"page"},{"location":"index.html","page":"Guide","title":"Guide","text":"pkg> develop ~/mygitpackagefolder/rimu.jl","category":"page"},{"location":"index.html","page":"Guide","title":"Guide","text":"where the file path has to be adjusted to the location of the cloned git repository.","category":"page"},{"location":"index.html#Usage","page":"Guide","title":"Usage","text":"","category":"section"},{"location":"index.html","page":"Guide","title":"Guide","text":"The package is now installed and can be imported with","category":"page"},{"location":"index.html","page":"Guide","title":"Guide","text":"julia> using Rimu","category":"page"},{"location":"index.html","page":"Guide","title":"Guide","text":"When planning to edit the code of the package it is advisable to use the Revise package by issuing","category":"page"},{"location":"index.html","page":"Guide","title":"Guide","text":"julia> using Revise","category":"page"},{"location":"index.html","page":"Guide","title":"Guide","text":"before using Rimu. This will track any changes made to the source code of Rimu and the changed package will be available after saving the source code (hopefully, and most of the time, without restarting the Julia REPL).","category":"page"},{"location":"index.html","page":"Guide","title":"Guide","text":"Rimu offers a number of tools for representing Hamiltonians (see Hamiltonians) and state vectors / wave functions (see DictVectors) as well as algorithms to find the ground state, e.g. ProjectorMonteCarloProblem, ExactDiagonalizationProblem.","category":"page"},{"location":"index.html#Scripts","page":"Guide","title":"Scripts","text":"","category":"section"},{"location":"index.html","page":"Guide","title":"Guide","text":"Rimu is written as a Julia package to be imported with using Rimu as described above. It supplies useful functions and types. Performing actual calculations and analysing the results is done with scripts. The folder scripts/ contains a collections of scripts that are either examples for use of the Rimu package or useful scripts for data analysis. In particular:","category":"page"},{"location":"index.html","page":"Guide","title":"Guide","text":"scripts/BHM-example.jl is an example script that runs fciqmc on the 1D Bose-Hubbard model. A data frame with results is written to the file fciqmcdata.arrow.\nscripts/BHM-example-mpi.jl demonstrates basic usage of Rimu with MPI.","category":"page"},{"location":"index.html#MPI","page":"Guide","title":"MPI","text":"","category":"section"},{"location":"index.html","page":"Guide","title":"Guide","text":"The Rimu package can run in parallel on different processes or node and distribute work by making use of MPI, or \"message passing interface\". For example, running","category":"page"},{"location":"index.html","page":"Guide","title":"Guide","text":"> julia scripts/BHM-example.jl","category":"page"},{"location":"index.html","page":"Guide","title":"Guide","text":"will run on one processor with the main computation (i.e. after package loading and compilation) completing in 2.69 seconds.","category":"page"},{"location":"index.html","page":"Guide","title":"Guide","text":"Running","category":"page"},{"location":"index.html","page":"Guide","title":"Guide","text":"> mpirun -np 4 julia scripts/BHM-example-mpi.jl","category":"page"},{"location":"index.html","page":"Guide","title":"Guide","text":"on the same hardware makes use of 4 cores and the main part completes in 1.04 seconds, a speedup factor of 2.6. This seems reasonable, given that extra work needs to be done for communicating between different processes.","category":"page"},{"location":"index.html","page":"Guide","title":"Guide","text":"Using MPI parallelism with Rimu is easy. Enabling MPI enabled automatically if PDVec is used to store a vector. In that case, data will be stored in a distributed fashion among the MPI ranks and only communicated between ranks when necessary.","category":"page"},{"location":"index.html#Compatibility","page":"Guide","title":"Compatibility","text":"","category":"section"},{"location":"index.html","page":"Guide","title":"Guide","text":"We recommend using Rimu with the latest Julia release version. Rimu requires at least julia v1.9.","category":"page"},{"location":"index.html#References","page":"Guide","title":"References","text":"","category":"section"},{"location":"index.html","page":"Guide","title":"Guide","text":"The code implements the FCIQMC algorithm originally described in","category":"page"},{"location":"index.html","page":"Guide","title":"Guide","text":"\"Fermion Monte Carlo without fixed nodes: A game of life, death, and annihilation in Slater determinant space\", G. H. Booth, A. J. W. Thom, A. Alavi, J. Chem. Phys. 131, 054106 (2009).\n\"Communications: Survival of the fittest: accelerating convergence in full configuration-interaction quantum Monte Carlo.\", D. Cleland, G. H. Booth, A. Alavi, J. Chem. Phys. 132, 041103 (2010).","category":"page"},{"location":"index.html","page":"Guide","title":"Guide","text":"Scientific papers describing additional features implemented in Rimu:","category":"page"},{"location":"index.html","page":"Guide","title":"Guide","text":"\"Improved walker population control for full configuration interaction quantum Monte Carlo\", M. Yang, E. Pahl, J. Brand, J. Chem. Phys. 153, 170143 (2020); arXiv:2008.01927.\n\"Stochastic differential equation approach to understanding the population control bias in full configuration interaction quantum Monte Carlo\", J. Brand, M. Yang, E. Pahl, arXiv:2103.07800 (2021).","category":"page"},{"location":"index.html","page":"Guide","title":"Guide","text":"Papers discussing results obtained with Rimu:","category":"page"},{"location":"index.html","page":"Guide","title":"Guide","text":"\"Polaron-Depleton Transition in the Yrast Excitations of a One-Dimensional Bose Gas with a Mobile Impurity\", M. Yang, M. Čufar, E. Pahl, J. Brand, Condens. Matter 7, 15 (2022).\n\"Magnetic impurity in a one-dimensional few-fermion system\", L. Rammelmüller, D. Huber, M. Čufar, J. Brand, A. Volosniev, arXiv:2204.01606 (2022).","category":"page"},{"location":"dictvectors.html#Module-DictVectors","page":"Dict vectors","title":"Module DictVectors","text":"","category":"section"},{"location":"dictvectors.html","page":"Dict vectors","title":"Dict vectors","text":"DictVectors\nAbstractDVec","category":"page"},{"location":"dictvectors.html#Rimu.DictVectors","page":"Dict vectors","title":"Rimu.DictVectors","text":"Module that provides concrete implementations of the AbstractDVec interface.\n\nDVec: basic AbstractDVec\nPDVec: parallel AbstractDVec with MPI and initiator support\nInitiatorDVec: allows storing information about initiator status\n\nSee Interfaces.\n\n\n\n\n\n","category":"module"},{"location":"dictvectors.html#Rimu.Interfaces.AbstractDVec","page":"Dict vectors","title":"Rimu.Interfaces.AbstractDVec","text":"AbstractDVec{K,V}\n\nAbstract data type for vector-like data structures with sparse storage. While conceptually AbstractDVecs represent elements of a vector space over a scalar type V, they are indexed by an arbitrary type K (could be non-integers) similar to dictionaries. They support the interface from VectorInterface.jl and are designed to work well for quantum Monte Carlo with ProjectorMonteCarloProblem and for matrix-free linear algebra with KrylovKit.\n\nConcrete implementations are available as PDVec, DVec, and InitiatorDVec.\n\nAbstractDVecs have a StochasticStyle which selects the spawning algorithm in FCIQMC. Looking up an element that is not stored in the AbstractDVec should return a zero, and setting a value to zero should remove it from the vector. To iterate over an AbstractDVec, use keys, pairs, or values. When possible, use reduction functions such as sum or mapreduce.\n\nInterface\n\nThe interface is similar to the AbstractDict interface, but with the changed behaviour as noted above. Implement what would be needed for the AbstractDict interface (pairs, keys, values, setindex!, getindex, delete!, length, empty, empty!) and, in addition:\n\nStochasticStyle\nstorage returns an AbstractDict storing the raw data with possibly different valtype than V.\ndeposit!\n\nA default implementation for the VectorInterface.jl interface is provided through the above functions.\n\nSee also DictVectors, Interfaces.\n\n\n\n\n\n","category":"type"},{"location":"dictvectors.html#Concrete-implementations","page":"Dict vectors","title":"Concrete implementations","text":"","category":"section"},{"location":"dictvectors.html","page":"Dict vectors","title":"Dict vectors","text":"DVec\nInitiatorDVec\nPDVec","category":"page"},{"location":"dictvectors.html#Rimu.DictVectors.DVec","page":"Dict vectors","title":"Rimu.DictVectors.DVec","text":"DVec{K,V,D<:AbstractDict{K,V},S}\n\nDictionary-based vector-like data structure for use with FCIQMC and KrylovKit. While mostly behaving like a Dict, it supports various linear algebra operations such as norm and dot. It has a StochasticStyle that is used to select an appropriate spawning strategy in the FCIQMC algorithm.\n\nSee also: AbstractDVec, InitiatorDVec, PDVec.\n\nConstructors\n\nDVec(dict::AbstractDict[; style, capacity]): create a DVec with dict for storage. Note that the data may or may not be copied.\nDVec(args...[; style, capacity]): args... are passed to the Dict constructor. The Dict is used for storage.\nDVec{K,V}([; style, capacity]): create an empty DVec{K,V}.\nDVec(dv::AbstractDVec[; style, capacity]): create a DVec with the same contents as adv. The style is inherited from dv by default.\n\nThe default style is selected based on the DVec's valtype (see default_style). If a style is given and the valtype does not match the style's eltype, the values are converted to an appropriate type.\n\nThe capacity argument is optional and sets the initial size of the DVec via Base.sizehint!.\n\nExamples\n\njulia> dv = DVec(:a => 1)\nDVec{Symbol,Int64} with 1 entry, style = IsStochasticInteger{Int64}()\n :a => 1\n\njulia> dv = DVec(:a => 2, :b => 3; style=IsDeterministic())\nDVec{Symbol,Float64} with 2 entries, style = IsDeterministic{Float64}()\n :a => 2.0\n :b => 3.0\n\n\n\n\n\n","category":"type"},{"location":"dictvectors.html#Rimu.DictVectors.InitiatorDVec","page":"Dict vectors","title":"Rimu.DictVectors.InitiatorDVec","text":"InitiatorDVec{K,V} <: AbstractDVec{K,V}\n\nDictionary-based vector-like data structure for use with ProjectorMonteCarloProblem and KrylovKit.jl. See AbstractDVec. Functionally identical to DVec, but contains InitiatorValues internally in order to facilitate initiator methods. Initiator methods for controlling the Monte Carlo sign problem were first introduced in J. Chem. Phys. 132, 041103 (2010). How the initiators are handled is controlled by specifying an InitiatorRule with the initiator keyword argument (see below).\n\nSee also: AbstractDVec, DVec, PDVec.\n\nConstructors\n\nInitiatorDVec(dict::AbstractDict[; style, initiator, capacity]): create an InitiatorDVec with dict for storage. Note that the data may or may not be copied.\nInitiatorDVec(args...[; style, initiator, capacity]): args... are passed to the Dict constructor. The Dict is used for storage.\nInitiatorDVec{K,V}([; style, initiator, capacity]): create an empty InitiatorDVec{K,V}.\nInitiatorDVec(dv::AbstractDVec[; style, initiator, capacity]): create an InitiatorDVec with the same contents as dv. The style is inherited from dv by default.\n\nKeyword arguments\n\nstyle: A valid StochasticStyle. The default is selected based on the InitiatorDVec's valtype (see default_style). If a style is given and the valtype does not match the style's eltype, the values are converted to an appropriate type.\ninitiator = Initiator(1): A valid InitiatorRule. See Initiator.\ncapacity: Indicative size as Int. Optional. Sets the initial size of the InitiatorDVec via Base.sizehint!.\n\n\n\n\n\n","category":"type"},{"location":"dictvectors.html#Rimu.DictVectors.PDVec","page":"Dict vectors","title":"Rimu.DictVectors.PDVec","text":"PDVec{K,V}(; kwargs...)\nPDVec(iter; kwargs...)\nPDVec(pairs...; kwargs...)\n\nDictionary-based vector-like data structure for use with FCIQMC and KrylovKit.jl. While mostly behaving like a Dict, it supports various linear algebra operations such as norm and dot, and the interface defined in VectorInterface.\n\nThe P in PDVec stands for parallel. PDVecs perform mapreduce, foreach, and various linear algebra operations in a threaded manner. If MPI is available, these operations are automatically distributed as well. As such it is not recommended to iterate over pairs, keys, or values directly unless explicitly performing them on the localpart of the vector.\n\nSee also: AbstractDVec, DVec, InitiatorDVec.\n\nKeyword arguments\n\nstyle =default_style(V): A StochasticStyle that is used to select the spawning strategy in the FCIQMC algorithm.\ninitiator =NonInitiator(): An InitiatorRule, used in FCIQMC to remove the sign problem.\ncommunicator: A Communicator that controls how operations are performed when using MPI. The defaults are NotDistributed when not using MPI and AllToAll when using MPI.\n\nExtended Help\n\nSegmentation\n\nThe vector is split into Threads.nthreads() subdictionaries called segments. Which dictionary a key-value pair is mapped to is determined by the hash of the key. The purpose of this segmentation is to allow parallel processing - functions such as mapreduce, add! or dot (full list below) process each subdictionary on a separate thread.\n\nSee also PDWorkingMemory.\n\nExample\n\njulia> add = FermiFS2C((1,1,0,0), (0,0,1,1));\n\njulia> op = HubbardMom1D(add; t=4/π^2, u=4);\n\njulia> pv = PDVec(add => 1.0)\n1-element PDVec: style = IsDeterministic{Float64}()\n fs\"|↑↑↓↓⟩\" => 1.0\n\njulia> pv = op * pv\n7-element PDVec: style = IsDeterministic{Float64}()\n fs\"|↑↓↑↓⟩\" => 1.0\n fs\"|↑↑↓↓⟩\" => 4.0\n fs\"|↓↑↓↑⟩\" => 1.0\n fs\"|↓↑↑↓⟩\" => -1.0\n fs\"|⇅⋅⋅⇅⟩\" => 1.0\n fs\"|↑↓↓↑⟩\" => -1.0\n fs\"|⋅⇅⇅⋅⟩\" => 1.0\n\njulia> scale!(pv, -1); pv\n7-element PDVec: style = IsDeterministic{Float64}()\n fs\"|↑↓↑↓⟩\" => -1.0\n fs\"|↑↑↓↓⟩\" => -4.0\n fs\"|↓↑↓↑⟩\" => -1.0\n fs\"|↓↑↑↓⟩\" => 1.0\n fs\"|⇅⋅⋅⇅⟩\" => -1.0\n fs\"|↑↓↓↑⟩\" => 1.0\n fs\"|⋅⇅⇅⋅⟩\" => -1.0\n\njulia> dest = similar(pv)\n0-element PDVec: style = IsDeterministic{Float64}()\n\njulia> map!(x -> x + 2, dest, values(pv))\n7-element PDVec: style = IsDeterministic{Float64}()\n fs\"|↑↓↑↓⟩\" => 1.0\n fs\"|↑↑↓↓⟩\" => -2.0\n fs\"|↓↑↓↑⟩\" => 1.0\n fs\"|↓↑↑↓⟩\" => 3.0\n fs\"|⇅⋅⋅⇅⟩\" => 1.0\n fs\"|↑↓↓↑⟩\" => 3.0\n fs\"|⋅⇅⇅⋅⟩\" => 1.0\n\njulia> sum(values(pv))\n-6.0\n\njulia> dot(dest, pv)\n10.0\n\njulia> dot(dest, op, pv)\n44.0\n\nMPI\n\nWhen MPI is active, all parallel reductions are automatically reduced across MPI ranks with a call to MPI.Allreduce!.\n\nIn a distributed setting, PDVec does not support iteration without first making it explicit the iteration is only to be performed on the local segments of the vector. This is done with localpart. In general, even when not using MPI, it is best practice to use localpart when explicit iteration is required.\n\nUse with KrylovKit\n\nPDVec is compatible with eigsolve from KrylovKit.jl. When used, the diagonalisation is performed in a threaded and distributed manner. Using multiple MPI ranks with this method does not distribute the memory load effectively, but does result in significant speedups.\n\nExample\n\njulia> using KrylovKit\n\njulia> add = BoseFS((0,0,5,0,0));\n\njulia> op = HubbardMom1D(add; u=6.0);\n\njulia> pv = PDVec(add => 1.0);\n\njulia> results = eigsolve(op, pv, 4, :SR);\n\njulia> results[1][1:4]\n4-element Vector{Float64}:\n -3.4311156892322234\n 1.1821748602612363\n 3.7377753753082823\n 6.996390417443125\n\nParallel functionality\n\nThe following functions are threaded and MPI-compatible:\n\nFrom Base: mapreduce and derivatives (sum, prod, reduce...), all, any,map! (on values only), +, -, *\nFrom LinearAlgebra: rmul!, lmul!, mul!, axpy!, axpby!, dot, norm, normalize, normalize!\nThe full interface defined in VectorInterface.jl\n\n\n\n\n\n","category":"type"},{"location":"dictvectors.html#Interface-functions","page":"Dict vectors","title":"Interface functions","text":"","category":"section"},{"location":"dictvectors.html","page":"Dict vectors","title":"Dict vectors","text":"deposit!\nstorage\nfreeze\nlocalpart\napply_operator!\nsort_into_targets!\nworking_memory\nmapreduce\nsum_mutating!","category":"page"},{"location":"dictvectors.html#Rimu.Interfaces.deposit!","page":"Dict vectors","title":"Rimu.Interfaces.deposit!","text":"deposit!(w::InitiatorDVec, add, val, p_add=>p_val)\n\nAdd val into w at address add as an AbstractInitiatorValue.\n\n\n\n\n\ndeposit!(w::AbstractDVec, add, val, parent::Pair)\n\nAdd val into w at address add, taking into account initiator rules if applicable. parent contains the address => value pair from which the pair add => val was created. InitiatorDVec can intercept this and add its own functionality.\n\n\n\n\n\n","category":"function"},{"location":"dictvectors.html#Rimu.Interfaces.storage","page":"Dict vectors","title":"Rimu.Interfaces.storage","text":"storage(dvec) -> AbstractDict\n\nReturn the raw storage associated with dvec as an AbstractDict. Used in MPI communication.\n\n\n\n\n\n","category":"function"},{"location":"dictvectors.html#OrderedCollections.freeze","page":"Dict vectors","title":"OrderedCollections.freeze","text":"freeze(dv)\n\nCreate a \"frozen\" version of dv which can no longer be modified or used in the conventional manner, but supports faster dot products.\n\n\n\n\n\n","category":"function"},{"location":"dictvectors.html#Rimu.Interfaces.localpart","page":"Dict vectors","title":"Rimu.Interfaces.localpart","text":"localpart(dv) -> AbstractDVec\n\nGet the part of dv that is located on this MPI rank. Returns dv itself for vectors that can't be MPI distributed (DVecs and InitiatorDVecs).\n\n\n\n\n\n","category":"function"},{"location":"dictvectors.html#Rimu.Interfaces.apply_operator!","page":"Dict vectors","title":"Rimu.Interfaces.apply_operator!","text":"apply_operator!(working_memory, target, source, operator, boost=1, compress=Val(true)) ->\n stat_names, stats, working_memory, target\n\nPerform a single matrix(/operator)-vector multiplication:\n\nv^(n + 1) = hatT v^(n) \n\nwhere hatT is the operator, v^(n+1) is the target and v^(n) is the source. The working_memory can be used as temporary storage.\n\nThe boost argument is passed to apply_column! and increases the number of spawns performed. For the operator to be applied without compressing the vector after, set compress to Val(false).\n\nWhether the operation is performed in a stochastic, semistochastic, or determistic way is controlled by the trait StochasticStyle(target). See StochasticStyle.\n\nReturns the step stats generated by the StochasticStyle, the working memory and the target vector. target and working_memory may be mutated and/or swapped.\n\n\n\n\n\n","category":"function"},{"location":"dictvectors.html#Rimu.Interfaces.sort_into_targets!","page":"Dict vectors","title":"Rimu.Interfaces.sort_into_targets!","text":"sort_into_targets!(target, source, stats) -> target, source, agg_stats\n\nAggregate coefficients from source to target and from stats to agg_stats according to thread- or MPI-level parallelism.\n\nReturns the new target and source, as the sorting process may involve swapping them.\n\n\n\n\n\n","category":"function"},{"location":"dictvectors.html#Rimu.Interfaces.working_memory","page":"Dict vectors","title":"Rimu.Interfaces.working_memory","text":"working_memory(dv::AbstractDVec)\n\nCreate a working memory instance compatible with dv. The working memory must be compatible with sort_into_targets! and apply_operator!.\n\n\n\n\n\n","category":"function"},{"location":"dictvectors.html#Base.mapreduce","page":"Dict vectors","title":"Base.mapreduce","text":"mapreduce(f, op, keys(::PDVec); [init])\nmapreduce(f, op, values(::PDVec); [init])\nmapreduce(f, op, pairs(::PDVec); [init])\n\nPerform a parallel reduction operation on PDVecs. MPI-compatible. Is used in the definition of various functions from Base such as reduce, sum, prod, etc.\n\ninit, if provided, must be a neutral element for op.\n\n\n\n\n\n","category":"function"},{"location":"dictvectors.html#Rimu.Interfaces.sum_mutating!","page":"Dict vectors","title":"Rimu.Interfaces.sum_mutating!","text":"sum_mutating!(accumulator, [f! = add!], keys(::PDVec); [init])\nsum_mutating!(accumulator, [f! = add!], values(::PDVec); [init])\nsum_mutating!(accumulator, [f! = add!], pairs(::PDVec); [init])\n\nPerform a parallel sum on PDVecs for vector-valued results while minimizing allocations. The result of the sum will be added to accumulator and stored in accumulator. MPI-compatible. If f! is provided, it must accept two arguments, the first being the accumulator and the second the element of the iterator. Otherwise,add! is used.\n\nIf provided, init must be a neutral element for + and of the same type as accumulator.\n\nSee also mapreduce.\n\n\n\n\n\nsum_mutating!(accumulator, [f! = add!], iterator)\n\nAdd the sum of elements in iterator to accumulator, storing the result in accumulator. If f! is provided, it must accept two arguments, the first being the accumulator and the second the element of the iterator. Otherwise, add! is used.\n\nSee also mapreduce.\n\n\n\n\n\n","category":"function"},{"location":"dictvectors.html#Supported-operations","page":"Dict vectors","title":"Supported operations","text":"","category":"section"},{"location":"dictvectors.html","page":"Dict vectors","title":"Dict vectors","text":"AbstractDVecs generally support most operations that are defined on Vectors and Dicts. This includes the interface from VectorInterface.jl, and many functions from the LinearAlgebra standard library.","category":"page"},{"location":"dictvectors.html","page":"Dict vectors","title":"Dict vectors","text":"A significant difference between AbstractDVecs, Vectors, and Dicts, is that iteration on them is disabled by default. Iteration must be explicitly performed on keys, values, or pairs, however, it is highly recommended you use mapreduce, reduce, or similar functions when performing reductions, as that will make the operations compatible with MPI.","category":"page"},{"location":"dictvectors.html","page":"Dict vectors","title":"Dict vectors","text":"In addition, Rimu defines the following function.","category":"page"},{"location":"dictvectors.html","page":"Dict vectors","title":"Dict vectors","text":"walkernumber\nwalkernumber_and_length\ndot_from_right","category":"page"},{"location":"dictvectors.html#Rimu.DictVectors.walkernumber","page":"Dict vectors","title":"Rimu.DictVectors.walkernumber","text":"walkernumber(v)\n\nCompute the number of walkers in v. It is used for updating the shift. Overload this function for modifying population control.\n\nIn most cases walkernumber(v) is identical to norm(v, 1). For AbstractDVecs with complex coefficients it reports the one norm separately for the real and the imaginary part as a ComplexF64. See Norm1ProjectorPPop.\n\n\n\n\n\n","category":"function"},{"location":"dictvectors.html#Rimu.DictVectors.walkernumber_and_length","page":"Dict vectors","title":"Rimu.DictVectors.walkernumber_and_length","text":"walkernumber_and_length(v)\n\nCompute walkernumber and length at the same time. When MPI is used, this is more efficient than calling them separately.\n\n\n\n\n\n","category":"function"},{"location":"dictvectors.html#Rimu.Interfaces.dot_from_right","page":"Dict vectors","title":"Rimu.Interfaces.dot_from_right","text":"dot_from_right(w, op::AbstractObservable, v)\n\nInternal function evaluates the 3-argument dot() function in order from right to left.\n\n\n\n\n\n","category":"function"},{"location":"dictvectors.html#Projectors","page":"Dict vectors","title":"Projectors","text":"","category":"section"},{"location":"dictvectors.html","page":"Dict vectors","title":"Dict vectors","text":"AbstractProjector\nNormProjector\nNorm2Projector\nUniformProjector\nNorm1ProjectorPPop\nRimu.DictVectors.FrozenDVec\nRimu.DictVectors.FrozenPDVec","category":"page"},{"location":"dictvectors.html#Rimu.DictVectors.AbstractProjector","page":"Dict vectors","title":"Rimu.DictVectors.AbstractProjector","text":"Abstract supertype for projectors to be used in in lieu of DVecs or Vectors in dot products. Implemented subtypes:\n\nUniformProjector\nNormProjector\nNorm2Projector\nNorm1ProjectorPPop\n\nSee also PostStepStrategy for use of projectors in ProjectorMonteCarloProblem.\n\nInterface\n\nDefine a method for LinearAlgebra.dot(projector, v).\n\n\n\n\n\n","category":"type"},{"location":"dictvectors.html#Rimu.DictVectors.NormProjector","page":"Dict vectors","title":"Rimu.DictVectors.NormProjector","text":"NormProjector() <: AbstractProjector\n\nResults in computing the one-norm when used in dot(). E.g.\n\ndot(NormProjector(),x)\n-> norm(x,1)\n\nNormProjector() thus represents the vector sign.(x).\n\nSee also PostStepStrategy, and AbstractProjector for use of projectors in ProjectorMonteCarloProblem.\n\n\n\n\n\n","category":"type"},{"location":"dictvectors.html#Rimu.DictVectors.Norm2Projector","page":"Dict vectors","title":"Rimu.DictVectors.Norm2Projector","text":"Norm2Projector() <: AbstractProjector\n\nResults in computing the two-norm when used in dot(). E.g.\n\ndot(NormProjector(),x)\n-> norm(x,2) # with type Float64\n\nSee also PostStepStrategy, and AbstractProjector for use of projectors in ProjectorMonteCarloProblem.\n\n\n\n\n\n","category":"type"},{"location":"dictvectors.html#Rimu.DictVectors.UniformProjector","page":"Dict vectors","title":"Rimu.DictVectors.UniformProjector","text":"UniformProjector() <: AbstractProjector\n\nRepresents a vector with all elements 1. To be used with dot(). Minimizes memory allocations.\n\nUniformProjector()⋅v == sum(v)\ndot(UniformProjector(), LO, v) == sum(LO*v)\n\nSee also PostStepStrategy, and AbstractProjector for use of projectors in ProjectorMonteCarloProblem.\n\n\n\n\n\n","category":"type"},{"location":"dictvectors.html#Rimu.DictVectors.Norm1ProjectorPPop","page":"Dict vectors","title":"Rimu.DictVectors.Norm1ProjectorPPop","text":"Norm1ProjectorPPop() <: AbstractProjector\n\nResults in computing the one-norm per population when used in dot(). E.g.\n\ndot(Norm1ProjectorPPop(),x)\n-> norm(real.(x),1) + im*norm(imag.(x),1)\n\nSee also PostStepStrategy, and AbstractProjector for use of projectors in ProjectorMonteCarloProblem.\n\n\n\n\n\n","category":"type"},{"location":"dictvectors.html#Rimu.DictVectors.FrozenDVec","page":"Dict vectors","title":"Rimu.DictVectors.FrozenDVec","text":"FrozenDVec\n\nA frozen DVec(s) can't be modified or used in the conventional manner, but support faster dot products. See: freeze.\n\n\n\n\n\n","category":"type"},{"location":"dictvectors.html#Rimu.DictVectors.FrozenPDVec","page":"Dict vectors","title":"Rimu.DictVectors.FrozenPDVec","text":"FrozenPDVec\n\nParallel version of FrozenDVec. See: freeze, PDVec.\n\n\n\n\n\n","category":"type"},{"location":"dictvectors.html#Initiator-rules","page":"Dict vectors","title":"Initiator rules","text":"","category":"section"},{"location":"dictvectors.html","page":"Dict vectors","title":"Dict vectors","text":"Rimu.DictVectors.InitiatorRule\nRimu.DictVectors.AbstractInitiatorValue\nRimu.DictVectors.InitiatorValue\nRimu.DictVectors.initiator_valtype\nRimu.DictVectors.to_initiator_value\nRimu.DictVectors.from_initiator_value\nRimu.DictVectors.Initiator\nRimu.DictVectors.SimpleInitiator\nRimu.DictVectors.CoherentInitiator\nRimu.DictVectors.NonInitiator\nRimu.DictVectors.NonInitiatorValue","category":"page"},{"location":"dictvectors.html#Rimu.DictVectors.InitiatorRule","page":"Dict vectors","title":"Rimu.DictVectors.InitiatorRule","text":"InitiatorRule{V}\n\nAbstract type for defining initiator rules for InitiatorDVec. Concrete implementations:\n\nInitiator\nSimpleInitiator\nCoherentInitiator\nNonInitiator\n\nExtended Help\n\nInitiatorRules define how to store and retrieve data from associated AbstractInitiatorValues. When defining a new InitiatorRule, also define the following:\n\ninitiator_valtype\nfrom_initiator_value\nto_initiator_value\n\n\n\n\n\n","category":"type"},{"location":"dictvectors.html#Rimu.DictVectors.AbstractInitiatorValue","page":"Dict vectors","title":"Rimu.DictVectors.AbstractInitiatorValue","text":"abstract type AbstractInitiatorValue{V}\n\nA value equipped with additional information that enables a variation of the initiator approximation. To be used with PDVec, InitiatorDVec and InitiatorRules.\n\nMust define:\n\nBase.zero, Base.:+, Base.:-, Base.:*\nfrom_initiator_value and to_initiator_value\n\n\n\n\n\n","category":"type"},{"location":"dictvectors.html#Rimu.DictVectors.InitiatorValue","page":"Dict vectors","title":"Rimu.DictVectors.InitiatorValue","text":"InitiatorValue{V}(; safe::V, unsafe::V, initiator::V) where V\n\nComposite \"walker\" with three fields. For use with InitiatorDVecs.\n\n\n\n\n\n","category":"type"},{"location":"dictvectors.html#Rimu.DictVectors.initiator_valtype","page":"Dict vectors","title":"Rimu.DictVectors.initiator_valtype","text":"initiator_valtype(rule::InitiatorRule, T)\n\nReturn the AbstractInitiatorValue{T} that is employed by the rule.\n\n\n\n\n\n","category":"function"},{"location":"dictvectors.html#Rimu.DictVectors.to_initiator_value","page":"Dict vectors","title":"Rimu.DictVectors.to_initiator_value","text":"to_initiator_value(::InitiatorRule, k::K, v::V, parent)\n\nConvert v to an AbstractInitiatorValue, taking the initiator rule and the parent that spawned it into account.\n\n\n\n\n\n","category":"function"},{"location":"dictvectors.html#Rimu.DictVectors.from_initiator_value","page":"Dict vectors","title":"Rimu.DictVectors.from_initiator_value","text":"from_initiator_value(i::InitiatorRule, v::AbstractInitiatorValue)\n\nConvert the AbstractInitiatorValue v into a scalar value according to the InitiatorRule i.\n\n\n\n\n\n","category":"function"},{"location":"dictvectors.html#Rimu.DictVectors.Initiator","page":"Dict vectors","title":"Rimu.DictVectors.Initiator","text":"Initiator(threshold = 1.0) <: InitiatorRule\n\nInitiator rule to be passed to PDVec or InitiatorDVec. An initiator is a configuration add with a coefficient with magnitude abs(v[add]) > threshold. The threshold can be passed as a keyword argument. Rules:\n\nInitiators can spawn anywhere.\nNon-initiators can spawn to initiators.\n\nSee InitiatorRule.\n\n\n\n\n\n","category":"type"},{"location":"dictvectors.html#Rimu.DictVectors.SimpleInitiator","page":"Dict vectors","title":"Rimu.DictVectors.SimpleInitiator","text":"SimpleInitiator(threshold = 1.0) <: InitiatorRule\n\nInitiator rule to be passed to PDVec or InitiatorDVec. An initiator is a configuration add with a coefficient with magnitude abs(v[add]) > threshold. The threshold can be passed as a keyword argument. Rules:\n\nInitiators can spawn anywhere.\nNon-initiators cannot spawn.\n\nSee InitiatorRule.\n\n\n\n\n\n","category":"type"},{"location":"dictvectors.html#Rimu.DictVectors.CoherentInitiator","page":"Dict vectors","title":"Rimu.DictVectors.CoherentInitiator","text":"CoherentInitiator(threshold = 1.0) <: InitiatorRule\n\nInitiator rule to be passed to PDVec or InitiatorDVec. An initiator is a configuration add with a coefficient with magnitude abs(v[add]) > threshold. The threshold can be passed as a keyword argument. Rules:\n\nInitiators can spawn anywhere.\nNon-initiators can spawn to initiators.\nMultiple non-initiators can spawn to a single non-initiator if their contributions add up to a value greater than the initiator threshold.\n\nSee InitiatorRule.\n\n\n\n\n\n","category":"type"},{"location":"dictvectors.html#Rimu.DictVectors.NonInitiator","page":"Dict vectors","title":"Rimu.DictVectors.NonInitiator","text":"NonInitiator() <: InitiatorRule\n\nInitiator rule that disables the approximation. This is the default setting for PDVec.\n\nSee InitiatorRule.\n\n\n\n\n\n","category":"type"},{"location":"dictvectors.html#Rimu.DictVectors.NonInitiatorValue","page":"Dict vectors","title":"Rimu.DictVectors.NonInitiatorValue","text":"NonInitiatorValue{V}\n\nValue that does not contain any additional information - used with NonInitiator, the default initiator rule for PDVec.\n\n\n\n\n\n","category":"type"},{"location":"dictvectors.html#PDVec-internals","page":"Dict vectors","title":"PDVec internals","text":"","category":"section"},{"location":"dictvectors.html#Working-memory","page":"Dict vectors","title":"Working memory","text":"","category":"section"},{"location":"dictvectors.html","page":"Dict vectors","title":"Dict vectors","text":"Modules = [DictVectors]\nPages = [\"pdworkingmemory.jl\"]","category":"page"},{"location":"dictvectors.html#Rimu.DictVectors.FirstColumnIterator","page":"Dict vectors","title":"Rimu.DictVectors.FirstColumnIterator","text":"FirstColumnIterator{W,D} <: AbstractVector{D}\n\nIterates segments in the first column of a working memory that belong to a specified rank.\n\nSee PDWorkingMemory, remote_segments and local_segments.\n\n\n\n\n\n","category":"type"},{"location":"dictvectors.html#Rimu.DictVectors.PDWorkingMemory","page":"Dict vectors","title":"Rimu.DictVectors.PDWorkingMemory","text":"PDWorkingMemory(t::PDVec)\n\nThe working memory that handles threading and MPI distribution for operations that involve operators, such as FCIQMC propagation, operator-vector multiplication and three-way dot products with PDVecs.\n\nThe working memory is structured as a two-dimensional array of segments, which themselves are Dicts (see PDVec). The number of rows in this array is equal to the number of segments across all MPI ranks (covering the entire address space), while the number of columns corresponds to the number of segments in the current MPI rank (i.e. column corresponds to the part of the address space that is local to the current rank).\n\nThe purpose of this organisation is to allow spawning in parallel without using locks or atomic operations. The spawning is performed by applying the following sequence of operations:\n\nperform_spawns!: each segment in the PDVec is multiplied by the operator independently, with the results being stored in a column of the working memory.\ncollect_local!: the rows of the working memory are summed to the first column.\nsynchronize_remote!: the segments corresponding to other MPI ranks are distributed and transferred to the first column.\nmove_and_compress!: the results are stochastically compressed and moved to the result PDVec\n\nWhen used with three-argument dot products, a full copy of the left-hand side vector is materialized in the first column of the working memory on all ranks.\n\n\n\n\n\n","category":"type"},{"location":"dictvectors.html#Rimu.DictVectors.PDWorkingMemoryColumn","page":"Dict vectors","title":"Rimu.DictVectors.PDWorkingMemoryColumn","text":"PDWorkingMemoryColumn\n\nA column in PDWorkingMemory. Supports getindex, deposit! and StochasticStyle and acts as a target for spawning. Can be used as a target in a three-way dot-product.\n\n\n\n\n\n","category":"type"},{"location":"dictvectors.html#Rimu.DictVectors.collect_local!-Tuple{PDWorkingMemory}","page":"Dict vectors","title":"Rimu.DictVectors.collect_local!","text":"collect_local!(w::PDWorkingMemory)\n\nSum each row in w and store the result in the first column. This step must be performed before using local_segments or remote_segments to move the values elsewhere.\n\nSee PDWorkingMemory.\n\n\n\n\n\n","category":"method"},{"location":"dictvectors.html#Rimu.DictVectors.first_column-Union{Tuple{PDWorkingMemory{K, V, W, S}}, Tuple{S}, Tuple{W}, Tuple{V}, Tuple{K}} where {K, V, W, S}","page":"Dict vectors","title":"Rimu.DictVectors.first_column","text":"first_column(::PDWorkingMemory)\n\nReturn the first column of the working memory. This is where the vectors are collected with collect_local!, synchronize_remote!, copy_to_local!.\n\nSee PDWorkingMemory.\n\n\n\n\n\n","category":"method"},{"location":"dictvectors.html#Rimu.DictVectors.local_segments-Tuple{PDWorkingMemory}","page":"Dict vectors","title":"Rimu.DictVectors.local_segments","text":"local_segments(w::PDWorkingMemory)\n\nReturns iterator over the segments in the first column of w on the current rank. Iterates Dicts.\n\nSee PDWorkingMemory.\n\n\n\n\n\n","category":"method"},{"location":"dictvectors.html#Rimu.DictVectors.move_and_compress!-Tuple{PDVec, PDWorkingMemory}","page":"Dict vectors","title":"Rimu.DictVectors.move_and_compress!","text":"move_and_compress!(dst::PDVec, src::PDWorkingMemory)\nmove_and_compress!(::CompressionStrategy, dst::PDVec, src::PDWorkingMemory)\n\nMove the values in src to dst, compressing the according to the CompressionStrategy on the way. This step can only be performed after collect_local! and synchronize_remote!.\n\nSee PDWorkingMemory.\n\n\n\n\n\n","category":"method"},{"location":"dictvectors.html#Rimu.DictVectors.num_columns-Tuple{PDWorkingMemory}","page":"Dict vectors","title":"Rimu.DictVectors.num_columns","text":"num_columns(w::PDWorkingMemory) -> Int\n\nNumber of columns in the working memory. The number of rows is equal to the number of segments in the local MPI rank.\n\nSee PDWorkingMemory.\n\n\n\n\n\n","category":"method"},{"location":"dictvectors.html#Rimu.DictVectors.num_rows-Tuple{PDWorkingMemory}","page":"Dict vectors","title":"Rimu.DictVectors.num_rows","text":"num_rows(w::PDWorkingMemory) -> Int\n\nNumber of rows in the working memory. The number of rows is equal to the number of segments accross all MPI ranks.\n\nSee PDWorkingMemory.\n\n\n\n\n\n","category":"method"},{"location":"dictvectors.html#Rimu.DictVectors.perform_spawns!-Tuple{PDWorkingMemory, PDVec, Any, Any}","page":"Dict vectors","title":"Rimu.DictVectors.perform_spawns!","text":"perform_spawns!(w::PDWorkingMemory, v::PDVec, ham, boost)\n\nPerform spawns from v through ham to w. boost increases the number of spawns without affecting the expectation value of the process.\n\nSee PDVec and PDWorkingMemory.\n\n\n\n\n\n","category":"method"},{"location":"dictvectors.html#Rimu.DictVectors.remote_segments-Tuple{PDWorkingMemory, Any}","page":"Dict vectors","title":"Rimu.DictVectors.remote_segments","text":"remote_segments(w::PDWorkingMemory, rank_id)\n\nReturns iterator over the segments in the first column of w that belong to rank rank_id. Iterates Dicts.\n\nSee PDWorkingMemory.\n\n\n\n\n\n","category":"method"},{"location":"dictvectors.html#Rimu.DictVectors.synchronize_remote!-Tuple{PDWorkingMemory}","page":"Dict vectors","title":"Rimu.DictVectors.synchronize_remote!","text":"synchronize_remote!([::Communicator,] w::PDWorkingMemory) -> names, values\n\nSynchronize non-local segments across MPI and add the results to the first column. Controlled by the Communicator. This can only be perfomed after collect_local!.\n\nShould return a Tuple of names and a Tuple of values to report.\n\nSee PDWorkingMemory.\n\n\n\n\n\n","category":"method"},{"location":"dictvectors.html#Communicators","page":"Dict vectors","title":"Communicators","text":"","category":"section"},{"location":"dictvectors.html","page":"Dict vectors","title":"Dict vectors","text":"Modules = [DictVectors]\nPages = [\"communicators.jl\"]","category":"page"},{"location":"dictvectors.html#Rimu.DictVectors.AllToAll","page":"Dict vectors","title":"Rimu.DictVectors.AllToAll","text":"AllToAll{K,V}(; mpi_comm, n_segments, report) <: Communicator\n\nCommunicator that uses collective communication using MPI.Alltoall[v]!.\n\nKeyword arguments\n\nmpi_comm=MPI.COMM_WORLD: the MPI communicator to use.\nn_segments=Threads.nthreads(): the number of segments per rank to use. Should match the PDVec the communicator is used with.\nreport=false: if set to true, report MPI communication times during a projector Monte Carlo run.\n\nSee also: Communicator.\n\n\n\n\n\n","category":"type"},{"location":"dictvectors.html#Rimu.DictVectors.Communicator","page":"Dict vectors","title":"Rimu.DictVectors.Communicator","text":"abstract type Communicator\n\nCommunicators are used to handle MPI communication when using PDVecs. Currently, three implementations are provided, NotDistributed, AllToAll and PointToPoint. The communicator is picked automatically according to the number of MPI ranks available.\n\nWhen implementing a communicator, use local_segments and remote_segments.\n\nInterface\n\nsynchronize_remote!\nmpi_rank\nmpi_size\nmpi_comm\n\nOptional interface\n\nis_distributed: defaults to returning true.\nmerge_remote_reductions: defaults to using MPI.Allreduce.\ntotal_num_segments: defaults to n * mpi_size.\ntarget_segment: defaults to selecting using fastrange to pick the segment.\n\nSee also: PDVec, PDWorkingMemory.\n\n\n\n\n\n","category":"type"},{"location":"dictvectors.html#Rimu.DictVectors.LocalPart","page":"Dict vectors","title":"Rimu.DictVectors.LocalPart","text":"LocalPart <: Communicator\n\nWhen localpart is used, the vector's Communicator is replaced with this. This allows iteration and local reductions.\n\n\n\n\n\n","category":"type"},{"location":"dictvectors.html#Rimu.DictVectors.NestedSegmentedBuffer","page":"Dict vectors","title":"Rimu.DictVectors.NestedSegmentedBuffer","text":"NestedSegmentedBuffer{T}(nrows) <: AbstractMatrix{AbstractVector{T}}\n\nMatrix of vectors stored in a single buffer with collective MPI communication support. The number of rows in the matrix is fixed to nrows.\n\nUsed in the AllToAll communication strategy, where each column corresponds to an MPI rank and each row corresponds to a segment in the PDVec.\n\nSupported operations\n\nappend_collections!: add a column to the matrix.\nappend_empty_column!: add an empty column to the matrix.\nmpi_exchange_alltoall!: each rank sends the i-th column of the matrix to the (i-1)-st rank.\nmpi_exchange_allgather!: each rank sends the 1-st column of the matrix to all ranks.\n\nSee also: SegmentedBuffer.\n\n\n\n\n\n","category":"type"},{"location":"dictvectors.html#Rimu.DictVectors.NotDistributed","page":"Dict vectors","title":"Rimu.DictVectors.NotDistributed","text":"NotDistributed <: Communicator\n\nThis Communicator is used when MPI is not available.\n\n\n\n\n\n","category":"type"},{"location":"dictvectors.html#Rimu.DictVectors.PointToPoint","page":"Dict vectors","title":"Rimu.DictVectors.PointToPoint","text":"PointToPoint{K,V}(; mpi_comm, report) <: Communicator\n\nMPI Communicator that uses circular communication using MPI.Isend and MPI.Recv!.\n\nKeyword arguments\n\nmpi_comm=MPI.COMM_WORLD: the MPI communicator to use.\nreport=false: if set to true, report MPI communication times during a projector Monte Carlo run.\n\n\n\n\n\n","category":"type"},{"location":"dictvectors.html#Rimu.DictVectors.SegmentedBuffer","page":"Dict vectors","title":"Rimu.DictVectors.SegmentedBuffer","text":"SegmentedBuffer{T}() <: AbstractVector{AbstractVector{T}}\n\nBehaves like a vector of vectors, but is stored in a single buffer. It can be sent/received over MPI keeping its structure intact. Used in the PointToPoint communication strategy.\n\nSupported operations\n\nreplace_collections!: insert data into the buffers\nmpi_send: send the contents of a buffer to a given rank\nmpi_recv_any!: receive a message sent by mpi_send from any rank, storing the contents in this buffer\n\nSee also: NestedSegmentedBuffer.\n\n\n\n\n\n","category":"type"},{"location":"dictvectors.html#Rimu.DictVectors.append_collections!-Tuple{Rimu.DictVectors.NestedSegmentedBuffer, Any}","page":"Dict vectors","title":"Rimu.DictVectors.append_collections!","text":"append_collections!(buf::NestedSegmentedBuffer, iters)\n\nAdd a column to buf. The length of iters should match buf.nrows.\n\nSee also: NestedSegmentedBuffer, append_empty_column!.\n\n\n\n\n\n","category":"method"},{"location":"dictvectors.html#Rimu.DictVectors.append_empty_column!-Tuple{Rimu.DictVectors.NestedSegmentedBuffer}","page":"Dict vectors","title":"Rimu.DictVectors.append_empty_column!","text":"append_empty_column!(buf::NestedSegmentedBuffer)\n\nLike append_collections!, but adds an empty column.\n\nSee also: NestedSegmentedBuffer, append_collections!.\n\n\n\n\n\n","category":"method"},{"location":"dictvectors.html#Rimu.DictVectors.copy_to_local!","page":"Dict vectors","title":"Rimu.DictVectors.copy_to_local!","text":"copy_to_local!([::Communicator,] w::PDWorkingMemory, t::PDVec) -> PDVec\n\nCopy pairs in t from all ranks and return them as a (possibly) new PDVec, possibly using the PDWorkingMemory as temporary storage.\n\nSee also: PDVec, PDWorkingMemory, Communicator.\n\n\n\n\n\n","category":"function"},{"location":"dictvectors.html#Rimu.DictVectors.is_distributed-Tuple{Rimu.DictVectors.Communicator}","page":"Dict vectors","title":"Rimu.DictVectors.is_distributed","text":"is_distributed(::Communicator)\n\nReturn true if Communicator operates over MPI.\n\n\n\n\n\n","category":"method"},{"location":"dictvectors.html#Rimu.DictVectors.merge_remote_reductions-Tuple{Rimu.DictVectors.Communicator, Any, Any}","page":"Dict vectors","title":"Rimu.DictVectors.merge_remote_reductions","text":"merge_remote_reductions(c::Communicator, op, x)\n\nMerge the results of reductions over MPI. By default, it uses MPI.Allreduce.\n\nSee also: Communicator.\n\n\n\n\n\n","category":"method"},{"location":"dictvectors.html#Rimu.DictVectors.mpi_exchange_allgather!-Tuple{Rimu.DictVectors.NestedSegmentedBuffer, Rimu.DictVectors.NestedSegmentedBuffer, Any}","page":"Dict vectors","title":"Rimu.DictVectors.mpi_exchange_allgather!","text":"mpi_exchange_allgather!(src::NestedSegmentedBuffer, dst::NestedSegmentedBuffer, comm)\n\nThe first and only column in src will be sent to all ranks. The data from all ranks will be gethered in dst. After this operation, dst will contain the same data on all ranks.\n\nSee also NestedSegmentedBuffer, mpi_exchange_alltoall!.\n\n\n\n\n\n","category":"method"},{"location":"dictvectors.html#Rimu.DictVectors.mpi_exchange_alltoall!-Tuple{Rimu.DictVectors.NestedSegmentedBuffer, Rimu.DictVectors.NestedSegmentedBuffer, Any}","page":"Dict vectors","title":"Rimu.DictVectors.mpi_exchange_alltoall!","text":"mpi_exchange_alltoall!(src::NestedSegmentedBuffer, dst::NestedSegmentedBuffer, comm)\n\nThe n-th column from src will be sent to rank n-1. The data sent from rank r will be stored in the (r+1)-st column of dst.\n\nSee also: NestedSegmentedBuffer, mpi_exchange_allgather!.\n\n\n\n\n\n","category":"method"},{"location":"dictvectors.html#Rimu.DictVectors.mpi_recv_any!-Tuple{Rimu.DictVectors.SegmentedBuffer, Any}","page":"Dict vectors","title":"Rimu.DictVectors.mpi_recv_any!","text":"mpi_recv_any!(buf::SegmentedBuffer, comm::MPI_Comm) -> Int\n\nFind a source that is ready to send a buffer and receive from it. Return the rank ID of the sender.\n\n\n\n\n\n","category":"method"},{"location":"dictvectors.html#Rimu.DictVectors.mpi_send-Tuple{Rimu.DictVectors.SegmentedBuffer, Any, Any}","page":"Dict vectors","title":"Rimu.DictVectors.mpi_send","text":"mpi_send(buf::SegmentedBuffer, dest, comm::MPI.Comm)\n\nSend the buffer to rank with id dest.\n\n\n\n\n\n","category":"method"},{"location":"dictvectors.html#Rimu.DictVectors.replace_collections!-Tuple{Rimu.DictVectors.SegmentedBuffer, Any}","page":"Dict vectors","title":"Rimu.DictVectors.replace_collections!","text":"replace_collections!(buf::SegmentedBuffer, iters)\n\nInsert collections in iters into a SegmentedBuffer.\n\njulia> using Rimu.DictVectors: SegmentedBuffer\n\njulia> buf = SegmentedBuffer{Int}()\n0-element SegmentedBuffer{Int64}\n\njulia> Rimu.DictVectors.replace_collections!(buf, [[1,2,3], [4,5]])\n2-element SegmentedBuffer{Int64}:\n [1, 2, 3]\n [4, 5]\n\njulia> Rimu.DictVectors.replace_collections!(buf, [[1], [2,3], [4]])\n3-element SegmentedBuffer{Int64}:\n [1]\n [2, 3]\n [4]\n\n\n\n\n\n","category":"method"},{"location":"dictvectors.html#Rimu.DictVectors.target_segment-Tuple{Rimu.DictVectors.Communicator, Any, Any}","page":"Dict vectors","title":"Rimu.DictVectors.target_segment","text":"target_segment(c::Communicator, k, num_segments) -> target, is_local\n\nThis function is used to determine where in the PDVec a key should be stored. If the key is local (stored on the same MPI rank), return its segment index and true. If the key is non-local, return any value and false.\n\nSee also: PDVec, Communicator.\n\n\n\n\n\n","category":"method"},{"location":"dictvectors.html#Rimu.DictVectors.total_num_segments-Tuple{Rimu.DictVectors.Communicator, Any}","page":"Dict vectors","title":"Rimu.DictVectors.total_num_segments","text":"total_num_segments(c::Communicator, n) -> Int\n\nReturn the total number of segments, including the remote ones, where n is number of local segments.\n\nSee also: PDVec, Communicator.\n\n\n\n\n\n","category":"method"},{"location":"dictvectors.html#Rimu.mpi_comm","page":"Dict vectors","title":"Rimu.mpi_comm","text":"mpi_comm(::Communicator) -> MPI.Comm\n\nReturn the MPI.Comm that the Communicator operates on.\n\n\n\n\n\n","category":"function"},{"location":"dictvectors.html#Rimu.mpi_rank","page":"Dict vectors","title":"Rimu.mpi_rank","text":"mpi_rank(::Communicator) -> Int\n\nReturn the MPI rank of the Communicator.\n\n\n\n\n\n","category":"function"},{"location":"dictvectors.html#Rimu.mpi_size","page":"Dict vectors","title":"Rimu.mpi_size","text":"mpi_size(::Communicator) -> Int\n\nReturn the total number of MPI ranks in the Communicator.\n\n\n\n\n\n","category":"function"},{"location":"dictvectors.html#Index","page":"Dict vectors","title":"Index","text":"","category":"section"},{"location":"dictvectors.html","page":"Dict vectors","title":"Dict vectors","text":"Pages = [\"dictvectors.md\"]","category":"page"},{"location":"custom_hamiltonians.html#Advanced-operator-usage-and-custom-Hamiltonians","page":"Custom Hamiltonians","title":"Advanced operator usage and custom Hamiltonians","text":"","category":"section"},{"location":"custom_hamiltonians.html","page":"Custom Hamiltonians","title":"Custom Hamiltonians","text":"Rimu can be used to work with custom Hamiltonians and observables that are user-defined and not part of the Rimu.jl package. To make this possible and reliable, Rimu exposes a number of interfaces and provides helper functions to test compliance with the interfaces through the submodule Rimu.InterfaceTests, see Interface tests. This section covers the relevant interfaces, the interface functions as well as potentially useful helper functions.","category":"page"},{"location":"custom_hamiltonians.html","page":"Custom Hamiltonians","title":"Custom Hamiltonians","text":"In order to define custom Hamiltonians or observables it is useful to know how the operator type hierarchy works in Rimu. For an example of how to implement custom Hamiltonians that are not part of the Rimu.jl package, see RimuLegacyHamiltonians.jl.","category":"page"},{"location":"custom_hamiltonians.html#Operator-type-hierarchy","page":"Custom Hamiltonians","title":"Operator type hierarchy","text":"","category":"section"},{"location":"custom_hamiltonians.html","page":"Custom Hamiltonians","title":"Custom Hamiltonians","text":"Rimu offers a hierarchy of abstract types that define interfaces with different requirements for operators:","category":"page"},{"location":"custom_hamiltonians.html","page":"Custom Hamiltonians","title":"Custom Hamiltonians","text":"AbstractHamiltonian <: AbstractOperator <: AbstractObservable","category":"page"},{"location":"custom_hamiltonians.html","page":"Custom Hamiltonians","title":"Custom Hamiltonians","text":"The different abstract types have different requirements and are meant to be used for different purposes. ","category":"page"},{"location":"custom_hamiltonians.html","page":"Custom Hamiltonians","title":"Custom Hamiltonians","text":"AbstractHamiltonians are fully featured models that define a Hilbert space and a linear operator over a scalar field. They can be passed as a Hamiltonian into ProjectorMonteCarloProblem or ExactDiagonalizationProblem.\nAbstractOperator and AbstractObservable are supertypes of AbstractHamiltonian with less stringent conditions. They are useful for defining observables that can be used in a three-way dot product, or passed as observables into a ReplicaStrategy that can be inserted with the keyword replica_strategy into a ProjectorMonteCarloProblem.","category":"page"},{"location":"custom_hamiltonians.html#Hamiltonians-interface","page":"Custom Hamiltonians","title":"Hamiltonians interface","text":"","category":"section"},{"location":"custom_hamiltonians.html","page":"Custom Hamiltonians","title":"Custom Hamiltonians","text":"Behind the implementation of a particular model is a more abstract interface for defining Hamiltonians. If you want to define a new model you should make use of this interface. A new model Hamiltonian should subtype to AbstractHamiltonian and implement the relevant methods.","category":"page"},{"location":"custom_hamiltonians.html","page":"Custom Hamiltonians","title":"Custom Hamiltonians","text":"AbstractHamiltonian\noffdiagonals\ndiagonal_element\nstarting_address","category":"page"},{"location":"custom_hamiltonians.html#Rimu.Interfaces.AbstractHamiltonian","page":"Custom Hamiltonians","title":"Rimu.Interfaces.AbstractHamiltonian","text":"AbstractHamiltonian{T} <: AbstractOperator{T}\n\nSupertype that provides an interface for linear operators over a linear space with scalar type T that are suitable for FCIQMC (with ProjectorMonteCarloProblem). Indexing is done with addresses (typically not integers) from an address space that may be large (and will not need to be completely generated).\n\nAbstractHamiltonian instances operate on vectors of type AbstractDVec from the module DictVectors and work well with addresses of type AbstractFockAddress from the module BitStringAddresses. The type works well with the external package KrylovKit.jl.\n\nFor available implementations see Hamiltonians.\n\nInterface\n\nBasic interface methods to implement:\n\nstarting_address(::AbstractHamiltonian)\ndiagonal_element(::AbstractHamiltonian, address)\nnum_offdiagonals(::AbstractHamiltonian, address)\nget_offdiagonal(::AbstractHamiltonian, address, chosen::Integer) (optional, see below)\n\nOptional additional methods to implement:\n\nLOStructure(::Type{typeof(lo)}): defaults to AdjointUnknown\ndimension(::AbstractHamiltonian, addr): defaults to dimension of address space\nallows_address_type(h::AbstractHamiltonian, type): defaults to type :< typeof(starting_address(h))\nmomentum(::AbstractHamiltonian): no default\n\nProvides the following functions and methods:\n\noffdiagonals: iterator over reachable off-diagonal matrix elements\nrandom_offdiagonal: function to generate random off-diagonal matrix element\n*(H, v): deterministic matrix-vector multiply (allocating)\nH(v): equivalent to H * v.\nmul!(w, H, v): mutating matrix-vector multiply.\ndot(x, H, v): compute x⋅(H*v) minimizing allocations.\nH[address1, address2]: indexing with getindex() - mostly for testing purposes (slow!)\nBasisSetRepresentation: construct a basis set repesentation\nsparse, Matrix: construct a (sparse) matrix representation\n\nAlternatively to the above, offdiagonals can be implemented instead of get_offdiagonal. Sometimes this can be done efficiently. In this case num_offdiagonals should provide an upper bound on the number of elements obtained when iterating offdiagonals.\n\nSee also Hamiltonians, Interfaces, AbstractOperator, AbstractObservable.\n\n\n\n\n\n","category":"type"},{"location":"custom_hamiltonians.html#Rimu.Interfaces.offdiagonals","page":"Custom Hamiltonians","title":"Rimu.Interfaces.offdiagonals","text":"offdiagonals(h::AbstractHamiltonian, address)\n\nReturn an iterator over nonzero off-diagonal matrix elements of h in the same column as address. Will iterate over pairs (newaddress, matrixelement).\n\nExample\n\njulia> address = BoseFS(3,2,1);\n\n\njulia> H = HubbardReal1D(address);\n\n\njulia> h = offdiagonals(H, address)\n6-element Rimu.Hamiltonians.Offdiagonals{BoseFS{6, 3, BitString{8, 1, UInt8}}, Float64, HubbardReal1D{Float64, BoseFS{6, 3, BitString{8, 1, UInt8}}, 1.0, 1.0}}:\n (fs\"|2 3 1⟩\", -3.0)\n (fs\"|2 2 2⟩\", -2.449489742783178)\n (fs\"|3 1 2⟩\", -2.0)\n (fs\"|4 1 1⟩\", -2.8284271247461903)\n (fs\"|4 2 0⟩\", -2.0)\n (fs\"|3 3 0⟩\", -1.7320508075688772)\n\nPart of the AbstractHamiltonian interface.\n\nExtemded help\n\noffdiagonals return and iterator of type <:AbstractOffdiagonals. It defaults to returning Offdiagonals(h, a)\n\nSee also Offdiagonals, AbstractOffdiagonals.\n\n\n\n\n\n","category":"function"},{"location":"custom_hamiltonians.html#Rimu.Interfaces.diagonal_element","page":"Custom Hamiltonians","title":"Rimu.Interfaces.diagonal_element","text":"diagonal_element(ham, address)\n\nCompute the diagonal matrix element of the linear operator ham at address address.\n\nExample\n\njulia> address = BoseFS((3, 2, 1));\n\n\njulia> H = HubbardMom1D(address);\n\n\njulia> diagonal_element(H, address)\n8.666666666666664\n\nPart of the AbstractHamiltonian interface.\n\n\n\n\n\n","category":"function"},{"location":"custom_hamiltonians.html#Rimu.Interfaces.starting_address","page":"Custom Hamiltonians","title":"Rimu.Interfaces.starting_address","text":"starting_address(h)\n\nReturn the starting address for Hamiltonian h. When called on an AbstractMatrix, starting_address returns the index of the lowest diagonal element.\n\nExample\n\njulia> address = BoseFS((3, 2, 1));\n\n\njulia> H = HubbardMom1D(address);\n\n\njulia> address == starting_address(H)\ntrue\n\nPart of the AbstractHamiltonian interface.\n\n\n\n\n\n","category":"function"},{"location":"custom_hamiltonians.html","page":"Custom Hamiltonians","title":"Custom Hamiltonians","text":"The following functions may be implemented instead of offdiagonals.","category":"page"},{"location":"custom_hamiltonians.html","page":"Custom Hamiltonians","title":"Custom Hamiltonians","text":"num_offdiagonals\nget_offdiagonal","category":"page"},{"location":"custom_hamiltonians.html#Rimu.Interfaces.num_offdiagonals","page":"Custom Hamiltonians","title":"Rimu.Interfaces.num_offdiagonals","text":"num_offdiagonals(ham, address)\n\nCompute the number of number of reachable configurations from address address.\n\nExample\n\njulia> address = BoseFS((3, 2, 1));\n\n\njulia> H = HubbardMom1D(address);\n\n\njulia> num_offdiagonals(H, address)\n10\n\nPart of the AbstractHamiltonian interface.\n\n\n\n\n\n","category":"function"},{"location":"custom_hamiltonians.html#Rimu.Interfaces.get_offdiagonal","page":"Custom Hamiltonians","title":"Rimu.Interfaces.get_offdiagonal","text":"newadd, me = get_offdiagonal(ham, address, chosen)\n\nCompute value me and new address newadd of a single (off-diagonal) matrix element in a Hamiltonian ham. The off-diagonal element is in the same column as address address and is indexed by integer index chosen.\n\nExample\n\njulia> addr = BoseFS(3, 2, 1);\n\njulia> H = HubbardMom1D(addr);\n\njulia> get_offdiagonal(H, addr, 3)\n(BoseFS{6,3}(2, 1, 3), 1.0)\n\nPart of the AbstractHamiltonian interface.\n\n\n\n\n\n","category":"function"},{"location":"custom_hamiltonians.html","page":"Custom Hamiltonians","title":"Custom Hamiltonians","text":"The following functions come with default implementations, but may be customized.","category":"page"},{"location":"custom_hamiltonians.html","page":"Custom Hamiltonians","title":"Custom Hamiltonians","text":"random_offdiagonal\nHamiltonians.LOStructure\ndimension\nhas_adjoint\nallows_address_type\nBase.eltype\nVectorInterface.scalartype\nmul!","category":"page"},{"location":"custom_hamiltonians.html#Rimu.Interfaces.random_offdiagonal","page":"Custom Hamiltonians","title":"Rimu.Interfaces.random_offdiagonal","text":"random_offdiagonal(offdiagonals::AbstractOffdiagonals)\nrandom_offdiagonal(ham::AbstractHamiltonian, address)\n-> newaddress, probability, matrixelement\n\nGenerate a single random excitation, i.e. choose from one of the accessible off-diagonal elements in the column corresponding to address in the Hamiltonian matrix represented by ham. Alternatively, pass as argument an iterator over the accessible matrix elements.\n\nPart of the AbstractHamiltonian interface.\n\n\n\n\n\n","category":"function"},{"location":"custom_hamiltonians.html#Rimu.Interfaces.LOStructure","page":"Custom Hamiltonians","title":"Rimu.Interfaces.LOStructure","text":"LOStructure(op::AbstractHamiltonian)\nLOStructure(typeof(op))\n\nReturn information about the structure of the linear operator op. LOStructure is used as a trait to speficy symmetries or other properties of the linear operator op that may simplify or speed up calculations. Implemented instances are:\n\nIsDiagonal(): The operator is diagonal.\nIsHermitian(): The operator is complex and Hermitian or real and symmetric.\nAdjointKnown(): The operator is not Hermitian, but its adjoint is implemented.\nAdjointUnknown(): adjoint for this operator is not implemented.\n\nPart of the AbstractHamiltonian interface.\n\nIn order to define this trait for a new linear operator type, define a method for LOStructure(::Type{<:MyNewLOType}) = ….\n\n\n\n\n\n","category":"type"},{"location":"custom_hamiltonians.html#Rimu.Hamiltonians.dimension","page":"Custom Hamiltonians","title":"Rimu.Hamiltonians.dimension","text":"dimension(h::AbstractHamiltonian, addr=starting_address(h))\ndimension(h::AbstractObservable, addr)\ndimension(addr::AbstractFockAddress)\ndimension(::Type{<:AbstractFockAddress})\n\nReturn the estimated dimension of Hilbert space. May return a BigInt number.\n\nWhen called on an address or address type, the dimension of the linear space spanned by the address type is returned. When called on an AbstractHamiltonian, an upper bound on the dimension of the matrix representing the Hamiltonian is returned.\n\nExamples\n\njulia> dimension(OccupationNumberFS(1,2,3))\n16777216\n\njulia> dimension(HubbardReal1D(OccupationNumberFS(1,2,3)))\n28\n\njulia> dimension(BoseFS{200,100})\n1386083821086188248261127842108801860093488668581216236221011219101585442774669540\n\njulia> Float64(ans)\n1.3860838210861882e81\n\nPart of the AbstractHamiltonian interface. See also BasisSetRepresentation.\n\nExtended Help\n\nThe default fallback for dimension called on an AbstractHamiltonian is to return the dimension of the address space, which provides an upper bound. For new Hamiltonians a tighter bound can be provided by defining a custom method.\n\nWhen extending AbstractHamiltonian, define a method for the two-argument form dimension(h::MyNewHamiltonian, addr). For number-conserving Hamiltonians, the function Hamiltonians.number_conserving_dimension may be useful.\n\nWhen extending AbstractFockAddress, define a method for dimension(::Type{MyNewFockAddress}).\n\n\n\n\n\n","category":"function"},{"location":"custom_hamiltonians.html#Rimu.Interfaces.has_adjoint","page":"Custom Hamiltonians","title":"Rimu.Interfaces.has_adjoint","text":"has_adjoint(op)\n\nReturn true if adjoint is defined on op.\n\nPart of the AbstractHamiltonian interface.\n\nSee also LOStructure.\n\n\n\n\n\n","category":"function"},{"location":"custom_hamiltonians.html#Rimu.Interfaces.allows_address_type","page":"Custom Hamiltonians","title":"Rimu.Interfaces.allows_address_type","text":"allows_address_type(operator, addr_or_type)\n\nReturns true if addr_or_type is a valid address for operator. Otherwise, returns false.\n\nPart of the AbstractHamiltonian interface.\n\nExtended help\n\nDefaults to addr_or_type <: typeof(starting_address(operator)). Overload this function if the operator can be used with addresses of different types.\n\n\n\n\n\n","category":"function"},{"location":"custom_hamiltonians.html#Base.eltype","page":"Custom Hamiltonians","title":"Base.eltype","text":"eltype(op::AbstractObservable)\n\nReturn the type of the elements of the operator. This can be a vector value. For the underlying scalar type use scalartype.\n\nPart of the AbstractObservable interface.\n\nnote: Note\nNew types do not have to implement this method explicitly. An implementation is provided based on the AbstractObservable's type parameter.\n\n\n\n\n\n","category":"function"},{"location":"custom_hamiltonians.html#VectorInterface.scalartype","page":"Custom Hamiltonians","title":"VectorInterface.scalartype","text":"scalartype(op::AbstractObservable)\n\nReturn the type of the underlying scalar field of the operator. This may be different from the element type of the operator returned by eltype, which can be a vector value.\n\nPart of the AbstractObservable interface.\n\nnote: Note\nNew types do not have to implement this method explicitly. An implementation is provided based on the AbstractObservable's type parameter.\n\n\n\n\n\n","category":"function"},{"location":"custom_hamiltonians.html#LinearAlgebra.mul!","page":"Custom Hamiltonians","title":"LinearAlgebra.mul!","text":"LinearAlgebra.mul!(w::AbstractDVec, op::AbstractOperator, v::AbstractDVec)\n\nIn place multiplication of op with v and storing the result in w. The result is returned. Note that w needs to have a valtype that can hold a product of instances of eltype(op) and valtype(v). Moreover, the StochasticStyle of w needs to be <:IsDeterministic.\n\nPart of the AbstractOperator interface.\n\nThe default implementation relies of diagonal_element and offdiagonals to access the elements of the operator. The function can be overloaded for custom operators.\n\n\n\n\n\n","category":"function"},{"location":"custom_hamiltonians.html","page":"Custom Hamiltonians","title":"Custom Hamiltonians","text":"This interface relies on unexported functionality, including","category":"page"},{"location":"custom_hamiltonians.html","page":"Custom Hamiltonians","title":"Custom Hamiltonians","text":"Hamiltonians.adjoint\nHamiltonians.dot\nHamiltonians.AbstractOffdiagonals\nHamiltonians.Offdiagonals\nHamiltonians.check_address_type\nHamiltonians.number_conserving_dimension\nHamiltonians.number_conserving_bose_dimension\nHamiltonians.number_conserving_fermi_dimension","category":"page"},{"location":"custom_hamiltonians.html#Base.adjoint","page":"Custom Hamiltonians","title":"Base.adjoint","text":"adjoint(::LOStructure, op::AbstractObservable)\n\nRepresent the adjoint of an AbstractObservable. Extend this method to define custom adjoints.\n\n\n\n\n\n","category":"function"},{"location":"custom_hamiltonians.html#LinearAlgebra.dot","page":"Custom Hamiltonians","title":"LinearAlgebra.dot","text":"dot(w, op::AbstractObservable, v)\n\nEvaluate w⋅op(v) minimizing memory allocations.\n\n\n\n\n\n","category":"function"},{"location":"custom_hamiltonians.html#Rimu.Hamiltonians.AbstractOffdiagonals","page":"Custom Hamiltonians","title":"Rimu.Hamiltonians.AbstractOffdiagonals","text":"AbstractOffdiagonals{A,T}<:AbstractVector{Tuple{A,T}}\n\nIterator over new address and matrix elements for reachable off-diagonal matrix elements of a linear operator.\n\nSee Offdiagonals for a default implementation.\n\nMethods to define\n\noffdiagonals(h, a)::AbstractOffdiagonals: This function is used to construct the correct type of offdiagonals for a given combination of Hamiltonian h and Fock address a.\nBase.getindex(::AbstractOffdiagonals, i): should be equivalent to get_offdiagonal(h, a, i).\nBase.size(::AbstractOffdiagonals): should be equivalent to num_offdiagonals(h, a).\n\nSee also offdiagonals, AbstractHamiltonian, AbstractOperator.\n\n\n\n\n\n","category":"type"},{"location":"custom_hamiltonians.html#Rimu.Hamiltonians.Offdiagonals","page":"Custom Hamiltonians","title":"Rimu.Hamiltonians.Offdiagonals","text":"Offdiagonals(h, address) <: AbstractOffdiagonals\n\nIterator over new address and matrix element for reachable off-diagonal matrix elements of linear operator h from address address. Represents an abstract vector containing the non-zero off-diagonal matrix elements of the column of h indexed by address. To construct this iterator use offdiagonals.\n\nThis is the default implementation of AbstractOffdiagonals defined in terms of num_offdiagonals and get_offdiagonal.\n\nSee also offdiagonals, AbstractHamiltonian, AbstractOperator.\n\n\n\n\n\n","category":"type"},{"location":"custom_hamiltonians.html#Rimu.Hamiltonians.check_address_type","page":"Custom Hamiltonians","title":"Rimu.Hamiltonians.check_address_type","text":"check_address_type(h::AbstractObservable, addr_or_type)\n\nThrow an ArgumentError if addr_or_type is not compatible with h, otherwise return true. Acceptable arguments are either an address or an address type, or a tuple or array thereof.\n\nSee also allows_address_type.\n\n\n\n\n\n","category":"function"},{"location":"custom_hamiltonians.html#Rimu.Hamiltonians.number_conserving_dimension","page":"Custom Hamiltonians","title":"Rimu.Hamiltonians.number_conserving_dimension","text":"number_conserving_dimension(address <: AbstractFockAddress)\n\nReturn the dimension of the Fock space spanned by the address type assuming particle number conservation.\n\nSee also number_conserving_bose_dimension, number_conserving_fermi_dimension, dimension.\n\n\n\n\n\n","category":"function"},{"location":"custom_hamiltonians.html#Rimu.Hamiltonians.number_conserving_bose_dimension","page":"Custom Hamiltonians","title":"Rimu.Hamiltonians.number_conserving_bose_dimension","text":"number_conserving_bose_dimension(n, m)\n\nReturn the dimension of the number-conserving Fock space for n bosons in m modes: binomial(n + m - 1, n).\n\nSee also number_conserving_fermi_dimension, number_conserving_dimension.\n\n\n\n\n\n","category":"function"},{"location":"custom_hamiltonians.html#Rimu.Hamiltonians.number_conserving_fermi_dimension","page":"Custom Hamiltonians","title":"Rimu.Hamiltonians.number_conserving_fermi_dimension","text":"number_conserving_fermi_dimension(n, m)\n\nReturn the dimension of the number-conserving Fock space for n fermions in m modes: binomial(m, n).\n\nSee also number_conserving_bose_dimension, number_conserving_dimension.\n\n\n\n\n\n","category":"function"},{"location":"custom_hamiltonians.html#Operator-and-observable-interface","page":"Custom Hamiltonians","title":"Operator and observable interface","text":"","category":"section"},{"location":"custom_hamiltonians.html","page":"Custom Hamiltonians","title":"Custom Hamiltonians","text":"AbstractObservable\nAbstractOperator","category":"page"},{"location":"custom_hamiltonians.html#Rimu.Interfaces.AbstractObservable","page":"Custom Hamiltonians","title":"Rimu.Interfaces.AbstractObservable","text":"AbstractObservable{T}\n\nMost permissive supertype for operators in the type hierarchy:\n\nAbstractHamiltonian{T} <: AbstractOperator{T} <: AbstractObservable{T}\n\nAbstractObservable provides an interface for operators that can appear in a three-way dot product dot(x, op, y) with two vectors of type AbstractDVec. The result is a value of type T, which is also returned by the eltype function. This may be a vector type associated with a scalar type returned by the scalartype function.\n\nThe AbstractObservable type is useful for defining observables that can be calculated in the context of a ProjectorMonteCarloProblem using AllOverlaps.\n\nInterface\n\nBasic interface methods to implement:\n\nInterfaces.dot_from_right(x, op, y)\nallows_address_type(op, type)\n\nOptional additional methods to implement:\n\nVectorInterface.scalartype(op): defaults to eltype(eltype(op))\nLOStructure(::Type{typeof(op)}): defaults to AdjointUnknown\n\nSee also AbstractOperator, AbstractHamiltonian, Interfaces.\n\n\n\n\n\n","category":"type"},{"location":"custom_hamiltonians.html#Rimu.Interfaces.AbstractOperator","page":"Custom Hamiltonians","title":"Rimu.Interfaces.AbstractOperator","text":"AbstractOperator{T} <: AbstractObservable{T}\n\nSupertype that provides an interface for linear operators over a linear space with elements of type T (returned by eltype) and general (custom type) indices called 'addresses'.\n\nAbstractOperator instances operate on vectors of type AbstractDVec from the module DictVectors and work well with addresses of type AbstractFockAddress from the module BitStringAddresses.\n\nThe defining feature of an AbstractOperator is that it can be applied to a vector with mul!(y, op, x) and that three-way dot products can be calculated with dot(x, op, y).\n\nThe AbstractOperator type is useful for defining operators that are not necessarily Hamiltonians, but that can be used in the context of a ProjectorMonteCarloProblem as observable operators in a ReplicaStrategy, e.g. for defining correlation functions. In contrast to AbstractHamiltonians, AbstractOperators do not need to have a starting_address. Moreover, the eltype of an AbstractOperator can be a vector value whereas AbstractHamiltonians requre a scalar eltype.\n\nAbstractHamiltonian{T} <: AbstractOperator{T} <: AbstractObservable{T}\n\nThe AbstractOperator type is part of the AbstractObservable hierarchy. It is more restrictive than AbstractObservable in that it requires the interface for the generation of diagonal and off-diagonal elements.\n\nFor concrete implementations see Hamiltonians. In order to implement a Hamiltonian for use in ProjectorMonteCarloProblem or ExactDiagonalizationProblem use the type AbstractHamiltonian instead.\n\nInterface\n\nBasic interface methods to implement:\n\nallows_address_type(op, type)\ndiagonal_element(op, address)\nnum_offdiagonals(op, address) and\nget_offdiagonal(op, address, chosen) or offdiagonals\n\nOptional additional methods to implement:\n\nVectorInterface.scalartype(op): defaults to eltype(eltype(op))\nLOStructure(::Type{typeof(op)}): defaults to AdjointUnknown\ndimension(op, addr): defaults to dimension of address space\n\nIn order to calculate observables efficiently, it may make sense to implement custom methods for Interfaces.dot_from_right(x, op, y) and LinearAlgebra.mul!(y, op, x).\n\nSee also AbstractHamiltonian, Interfaces.\n\n\n\n\n\n","category":"type"},{"location":"custom_hamiltonians.html#Interface-tests","page":"Custom Hamiltonians","title":"Interface tests","text":"","category":"section"},{"location":"custom_hamiltonians.html","page":"Custom Hamiltonians","title":"Custom Hamiltonians","text":"Helper functions that can be used for testing the various interfaces are provided in the (unexported) submodule Rimu.InterfaceTests. ","category":"page"},{"location":"custom_hamiltonians.html","page":"Custom Hamiltonians","title":"Custom Hamiltonians","text":"Rimu.InterfaceTests","category":"page"},{"location":"custom_hamiltonians.html#Rimu.InterfaceTests","page":"Custom Hamiltonians","title":"Rimu.InterfaceTests","text":"The module Rimu.InterfaceTests provides functions to test compliance with the AbstractObservable, AbstractOperator, and AbstractHamiltonian interfaces. Load the module with using Rimu.InterfaceTests.\n\nThe module exports the following functions:\n\ntest_observable_interface\ntest_operator_interface\ntest_hamiltonian_interface\ntest_hamiltonian_structure\n\n\n\n\n\n","category":"module"},{"location":"custom_hamiltonians.html#Testing-functions","page":"Custom Hamiltonians","title":"Testing functions","text":"","category":"section"},{"location":"custom_hamiltonians.html","page":"Custom Hamiltonians","title":"Custom Hamiltonians","text":"Rimu.InterfaceTests.test_hamiltonian_interface\nRimu.InterfaceTests.test_hamiltonian_structure\nRimu.InterfaceTests.test_observable_interface\nRimu.InterfaceTests.test_operator_interface","category":"page"},{"location":"custom_hamiltonians.html#Rimu.InterfaceTests.test_hamiltonian_interface","page":"Custom Hamiltonians","title":"Rimu.InterfaceTests.test_hamiltonian_interface","text":"test_hamiltonian_interface(h, addr=starting_address(h); test_spawning=true)\n\nThe main purpose of this test function is to check that all required methods of the AbstractHamiltonian interface are defined and work as expected.\n\nSet test_spawning=false to skip tests that require offdiagonals to return an AbstractVector.\n\nThis function also tests the following properties of the Hamiltonian:\n\ndimension(h) ≥ dimension(h, addr)\nscalartype(h) === eltype(h)\nHamiltonian action on a vector <: AbstractDVec\nstarting_address returns an allows_address_type address\nLOStructure is one of IsDiagonal, IsHermitian, AdjointKnown\nthe AbstractOperator interface is tested\nthe AbstractObservable interface is tested\n\nExample\n\njulia> using Rimu.InterfaceTests\n\njulia> test_hamiltonian_interface(HubbardRealSpace(BoseFS(2,0,3,1)));\nTest Summary: | Pass Total Time\nObservable interface: HubbardRealSpace | 4 4 0.0s\nTest Summary: | Pass Total Time\nallows_address_type | 1 1 0.0s\nTest Summary: | Pass Total Time\nOperator interface: HubbardRealSpace | 9 9 0.0s\nTest Summary: | Pass Total Time\nallows_address_type | 1 1 0.0s\nTest Summary: | Pass Total Time\nHamiltonians-only tests with HubbardRealSpace | 6 6 0.0s\n\nSee also test_operator_interface, test_observable_interface.\n\n\n\n\n\n","category":"function"},{"location":"custom_hamiltonians.html#Rimu.InterfaceTests.test_hamiltonian_structure","page":"Custom Hamiltonians","title":"Rimu.InterfaceTests.test_hamiltonian_structure","text":"test_hamiltonian_structure(h::AbstractHamiltonian; sizelim=20)\n\nTest the LOStructure of a small Hamiltonian h by instantiating it as a sparse matrix and checking whether the structure of the matrix is constistent with the result of LOStructure(h) and the eltype is consistent with eltype(h).\n\nThis function is intended to be used in automated test for small Hamiltonians where instantiating the matrix is quick. A warning will print if the dimension of the Hamiltonian is larger than 20.\n\nExample\n\njulia> using Rimu.InterfaceTests\n\njulia> test_hamiltonian_structure(HubbardRealSpace(BoseFS(2,0,1)));\nTest Summary: | Pass Total Time\nstructure | 4 4 0.0s\n\n\n\n\n\n","category":"function"},{"location":"custom_hamiltonians.html#Rimu.InterfaceTests.test_observable_interface","page":"Custom Hamiltonians","title":"Rimu.InterfaceTests.test_observable_interface","text":"test_observable_interface(obs, addr)\n\nThis function tests compliance with the AbstractObservable interface for an observable obs at address addr (typically <: AbstractFockAddress) by checking that all required methods are defined.\n\nThe following properties are tested:\n\ndot(v, obs, v) returns a value of the same type as the eltype of the observable\nLOStructure is set consistently\n\nExample\n\njulia> using Rimu.InterfaceTests\n\njulia> test_observable_interface(ReducedDensityMatrix(2), FermiFS(1,0,1,1));\nTest Summary: | Pass Total Time\nObservable interface: ReducedDensityMatrix | 4 4 0.0s\n\nSee also AbstractObservable, test_operator_interface, test_hamiltonian_interface.\n\n\n\n\n\n","category":"function"},{"location":"custom_hamiltonians.html#Rimu.InterfaceTests.test_operator_interface","page":"Custom Hamiltonians","title":"Rimu.InterfaceTests.test_operator_interface","text":"test_operator_interface(op, addr; test_spawning=true)\n\nThis function tests compliance with the AbstractOperator interface for an operator op at address addr (typically <: AbstractFockAddress) by checking that all required methods are defined.\n\nIf test_spawning is true, tests are performed that require offdiagonals to return an Hamiltonians.AbstractOffDiagonals, which is a prerequisite for using the spawn! function. Otherwise, the spawning tests are skipped.\n\nThe following properties are tested:\n\ndiagonal_element returns a value of the same type as the eltype of the operator\noffdiagonals behaves like an AbstractVector\nnum_offdiagonals returns the correct number of offdiagonals\nrandom_offdiagonal returns a tuple with the correct types\nmul! and dot work as expected\ndimension returns a consistent value\nthe AbstractObservable interface is tested\n\nExample\n\njulia> using Rimu.InterfaceTests\n\njulia> test_operator_interface(SuperfluidCorrelator(3), BoseFS(1, 2, 3, 1));\nTest Summary: | Pass Total Time\nObservable interface: SuperfluidCorrelator | 4 4 0.0s\nTest Summary: | Pass Total Time\nallows_address_type | 1 1 0.0s\nTest Summary: | Pass Total Time\nOperator interface: SuperfluidCorrelator | 9 9 0.0s\n\nSee also AbstractOperator, test_observable_interface, test_hamiltonian_interface.\n\n\n\n\n\n","category":"function"},{"location":"custom_hamiltonians.html#Utilities-for-harmonic-oscillator-models","page":"Custom Hamiltonians","title":"Utilities for harmonic oscillator models","text":"","category":"section"},{"location":"custom_hamiltonians.html","page":"Custom Hamiltonians","title":"Custom Hamiltonians","text":"Useful utilities for harmonic oscillator in Cartesian basis, see HOCartesianContactInteractions and HOCartesianEnergyConservedPerDim.","category":"page"},{"location":"custom_hamiltonians.html","page":"Custom Hamiltonians","title":"Custom Hamiltonians","text":"get_all_blocks\nfock_to_cart","category":"page"},{"location":"custom_hamiltonians.html#Rimu.Hamiltonians.get_all_blocks","page":"Custom Hamiltonians","title":"Rimu.Hamiltonians.get_all_blocks","text":"get_all_blocks(h::Union{HOCartesianContactInteractions,HOCartesianEnergyConservedPerDim};\n target_energy = nothing,\n max_energy = nothing,\n max_blocks = nothing,\n method = :vertices,\n kwargs...) -> df\n\nFind all distinct blocks of h. Returns a DataFrame with columns\n\nblock_id: index of block in order found\nblock_E0: noninteracting energy of all elements in the block\nblock_size: number of elements in the block\naddr: first address that generates the block with e.g. BasisSetRepresentation\nindices: tuple of mode indices that allow recreation of the generating address addr; in this case use e.g. BoseFS(M; indices .=> 1) This is useful when the DataFrame is loaded from file since Arrow.jl converts custom types to NamedTuples.\nt_basis: time to generate the basis for each block\n\nKeyword arguments:\n\ntarget_energy: only blocks with this noninteracting energy are found\nmax_energy: only blocks with noninteracting energy less than this are found\nmax_blocks: exit after finding this many blocks\nmethod: Choose between :vertices and :comb for method of enumerating tuples of quantum numbers\nsave_to_file=nothing: if set then the DataFrame recording blocks is saved after each new block is found\nadditional kwargs: passed to isapprox for comparing block energies. Useful for anisotropic traps\n\nNote: If h was constructed with option block_by_level = false then the block seeds addr are determined by parity. In this case the blocks are not generated; t_basis will be zero, and block_size will be an estimate. Pass the seed addresses to BasisSetRepresentation with an appropriate filter to generate the blocks.\n\n\n\n\n\n","category":"function"},{"location":"custom_hamiltonians.html#Rimu.Hamiltonians.fock_to_cart","page":"Custom Hamiltonians","title":"Rimu.Hamiltonians.fock_to_cart","text":"fock_to_cart(addr, S; zero_index = true)\n\nConvert a Fock state address addr to Cartesian harmonic oscillator basis indices n_xn_yldots. These indices are bounded by S which is a tuple of the maximum number of states in each dimension. By default the groundstate in each dimension is indexed by 0, but this can be changed by setting zero_index = false.\n\n\n\n\n\n","category":"function"},{"location":"custom_hamiltonians.html","page":"Custom Hamiltonians","title":"Custom Hamiltonians","text":"Underlying integrals for the interaction matrix elements are implemented in the following unexported functions","category":"page"},{"location":"custom_hamiltonians.html","page":"Custom Hamiltonians","title":"Custom Hamiltonians","text":"Hamiltonians.four_oscillator_integral_general\nHamiltonians.ho_delta_potential\nHamiltonians.log_abs_oscillator_zero","category":"page"},{"location":"custom_hamiltonians.html#Rimu.Hamiltonians.four_oscillator_integral_general","page":"Custom Hamiltonians","title":"Rimu.Hamiltonians.four_oscillator_integral_general","text":"four_oscillator_integral_general(i, j, k, l; max_level = typemax(Int))\n\nIntegral of four one-dimensional harmonic oscillator functions,\n\n mathcalI(ijkl) = int_-infty^infty dx \n phi_i(x) phi_j(x) phi_k(x) phi_l(x)\n\nIndices i,j,k,l start at 0 for the groundstate.\n\nThis integral has a closed form in terms of the hypergeometric _3F_2 function, and is non-zero unless i+j+k+l is odd. See e.g. Titchmarsh (1948). This is a generalisation of the closed form in Papenbrock (2002), which is is the special case where i+j == k+l, but is numerically unstable for large arguments. Used in HOCartesianContactInteractions and HOCartesianEnergyConservedPerDim.\n\n\n\n\n\n","category":"function"},{"location":"custom_hamiltonians.html#Rimu.Hamiltonians.ho_delta_potential","page":"Custom Hamiltonians","title":"Rimu.Hamiltonians.ho_delta_potential","text":"ho_delta_potential(S, i, j; [vals])\n\nReturns the matrix element of a delta potential at the centre of a trap, i.e. the product of two harmonic oscillator functions evaluated at the origin,\n\n v_ij = phi_mathbfn_i(0) phi_mathbfn_j(0)\n\nwhich is only non-zero for even-parity states. The ith single particle state corresponds to a D-tuple of harmonic oscillator indices mathbfn_i. S defines the bounds of Cartesian harmonic oscillator indices for each dimension. The optional keyword argument vals allows passing pre-computed values of phi_i(0) to speed-up the calculation. The values can be calculated with log_abs_oscillator_zero.\n\nSee also HOCartesianCentralImpurity.\n\n\n\n\n\n","category":"function"},{"location":"custom_hamiltonians.html#Rimu.Hamiltonians.log_abs_oscillator_zero","page":"Custom Hamiltonians","title":"Rimu.Hamiltonians.log_abs_oscillator_zero","text":"log_abs_oscillator_zero(n)\n\nCompute the logarithm of the absolute value of the n^mathrmth 1D harmonic oscillator function evaluated at the origin. The overall sign is determined when the matrix element is evaluated in ho_delta_potential.\n\n\n\n\n\n","category":"function"},{"location":"custom_hamiltonians.html#Index","page":"Custom Hamiltonians","title":"Index","text":"","category":"section"},{"location":"custom_hamiltonians.html","page":"Custom Hamiltonians","title":"Custom Hamiltonians","text":"Pages = [\"custom_hamiltonians.md\"]","category":"page"}] +[{"location":"mpi.html#Working-with-MPI","page":"Using MPI","title":"Working with MPI","text":"","category":"section"},{"location":"mpi.html","page":"Using MPI","title":"Using MPI","text":"If you are using PDVecs to store your vectors, working with MPI should be fairly straightforward. Generally, PDVec will work with MPI automatically, as long as MPI is set up correctly and a few common pitfalls are avoided.","category":"page"},{"location":"mpi.html#Configuring-MPI","page":"Using MPI","title":"Configuring MPI","text":"","category":"section"},{"location":"mpi.html","page":"Using MPI","title":"Using MPI","text":"When running on a cluster, ensure that MPI.jl is using the system binary. See the MPI.jl documentation for more information.","category":"page"},{"location":"mpi.html","page":"Using MPI","title":"Using MPI","text":"It is always a good idea to start your script with a quick test that ensures the MPI is set up correctly. One way to do this is to open with","category":"page"},{"location":"mpi.html","page":"Using MPI","title":"Using MPI","text":"mpi_allprintln(\"hello\")","category":"page"},{"location":"mpi.html","page":"Using MPI","title":"Using MPI","text":"which should print something like","category":"page"},{"location":"mpi.html","page":"Using MPI","title":"Using MPI","text":"[ rank 0: hello\n[ rank 1: hello\n[ rank 2: hello\n[ rank 3: hello","category":"page"},{"location":"mpi.html","page":"Using MPI","title":"Using MPI","text":"If it prints rank 0 several times, the code will run, but ranks will not communicate.","category":"page"},{"location":"mpi.html#Using-Slurm","page":"Using MPI","title":"Using Slurm","text":"","category":"section"},{"location":"mpi.html","page":"Using MPI","title":"Using MPI","text":"When using PDVec, the recommended setup is to use threads to parallelise the computation within a node, and to only use MPI for inter-node communication. In a slurm script, this is done as follows:","category":"page"},{"location":"mpi.html","page":"Using MPI","title":"Using MPI","text":"...\n#SBATCH --ntasks-per-node=1\n#SBATCH --nodes=4 # replace 4 with the desired number of nodes\n#SBATCH --cpus-per-task=28 # replace 28 with the number of cores available in a node\n#SBATCH --hint=nomultithread # don't use hyperthreading\n...\n\nsrun julia --project -tauto script.jl","category":"page"},{"location":"mpi.html","page":"Using MPI","title":"Using MPI","text":"On some clusters, additional settings must be used with srun, for example the CTCP cluster requires the following.","category":"page"},{"location":"mpi.html","page":"Using MPI","title":"Using MPI","text":"srun mpi=pmi2 julia --project -tauto script.jl","category":"page"},{"location":"mpi.html#Common-pitfalls-with-reducing-functions","page":"Using MPI","title":"Common pitfalls with reducing functions","text":"","category":"section"},{"location":"mpi.html#Using-@mpi_root","page":"Using MPI","title":"Using @mpi_root","text":"","category":"section"},{"location":"mpi.html","page":"Using MPI","title":"Using MPI","text":"Take care to not use reducing functions (such as length, sum, norm, ...) inside @mpi_root blocks. Doing so will only initiate the distributed reduction on one rank only, which will cause the code to go out of sync and freeze. As an example, to report the current length of a vector, calculate the length before the @mpi_root block:","category":"page"},{"location":"mpi.html","page":"Using MPI","title":"Using MPI","text":"len = length(pdvec)\n@mpi_root println(\"vector length is $len\")","category":"page"},{"location":"mpi.html#Threaded-operations-and-reductions","page":"Using MPI","title":"Threaded operations and reductions","text":"","category":"section"},{"location":"mpi.html","page":"Using MPI","title":"Using MPI","text":"When using functions that take anonymous functions, such as map(!), sum, or mapreduce, it is important that the anonymous functions passed to them do not perform any MPI-reducing operations (length, norm, sum, etc.). These anonymous functions are executed on multiple threads and initiating MPI communication from multiple threads may cause issues.","category":"page"},{"location":"mpi.html","page":"Using MPI","title":"Using MPI","text":"As an example, suppose we want to scale a vector by its length by using map!. The correct way to write this code is as","category":"page"},{"location":"mpi.html","page":"Using MPI","title":"Using MPI","text":"len = length(pdvec)\nmap!(values(pdvec)) do x\n\tx / len\nend","category":"page"},{"location":"mpi.html","page":"Using MPI","title":"Using MPI","text":"Similar to the previous example, len is calculated first and not within the body of map!. In this specific case, an even better option is to use the scale! function from VectorInterface.jl:","category":"page"},{"location":"mpi.html","page":"Using MPI","title":"Using MPI","text":"scale!(pdvec, 1 / length(pdvec))","category":"page"},{"location":"projectormontecarlo.html#Projector-Monte-Carlo-/-FCIQMC","page":"Projector Monte Carlo","title":"Projector Monte Carlo / FCIQMC","text":"","category":"section"},{"location":"projectormontecarlo.html","page":"Projector Monte Carlo","title":"Projector Monte Carlo","text":"The purpose of Projector Monte Carlo is to stochastically sample the ground state, i.e. the eigenvector corresponding to the lowest eigenvalue of a quantum Hamiltonian, or more generally, a very large matrix. Rimu implements a flavor of Projector Monte Carlo called Full Configuration Interaction Quantum Monte Carlo (FCIQMC).","category":"page"},{"location":"projectormontecarlo.html#ProjectorMonteCarloProblem","page":"Projector Monte Carlo","title":"ProjectorMonteCarloProblem","text":"","category":"section"},{"location":"projectormontecarlo.html","page":"Projector Monte Carlo","title":"Projector Monte Carlo","text":"To run a projector Monte Carlo simulation you set up a problem with ProjectorMonteCarloProblem and solve it with solve. Alternatively you can init it with to obtain a PMCSimulation struct, step! through time steps, and solve! it to completion. ","category":"page"},{"location":"projectormontecarlo.html","page":"Projector Monte Carlo","title":"Projector Monte Carlo","text":"ProjectorMonteCarloProblem\ninit\nsolve\nsolve!\nstep!","category":"page"},{"location":"projectormontecarlo.html#Rimu.ProjectorMonteCarloProblem-projectormontecarlo","page":"Projector Monte Carlo","title":"Rimu.ProjectorMonteCarloProblem","text":"ProjectorMonteCarloProblem(hamiltonian::AbstractHamiltonian; kwargs...)\n\nDefines a problem to be solved by projector quantum Monte Carlo (QMC) methods, such as the the FCIQMC algorithm.\n\nCommon keyword arguments and defaults:\n\ntime_step = 0.01: Initial time step size.\nlast_step = 100: Controls the number of steps.\ntarget_walkers = 1_000: Target for the 1-norm of the coefficient vector.\nstart_at = starting_address(hamiltonian): Define the initial state vector(s). An r s matrix of state vectors can be passed where r is the number of replicas and s the number of spectral states. See also default_starting_vector.\nstyle = IsDynamicSemistochastic(): The StochasticStyle of the simulation.\ninitiator = false: Whether to use initiators. Can be true, false, or a valid InitiatorRule.\nthreading: Default is to use multithreading and/or MPI if available. Set to true to force PDVec for the starting vector, false for serial computation; may be overridden by start_at.\nreporting_strategy = ReportDFAndInfo(): How and when to report results, see ReportingStrategy.\npost_step_strategy = (): Extract observables (e.g. ProjectedEnergy), see PostStepStrategy.\nn_replicas = 1: Number of synchronised independent simulations.\nreplica_strategy = NoStats(n_replicas): Which results to report from replica simulations, see ReplicaStrategy.\nn_spectral = 1: Number of targeted spectral states. Set n_spectral > 1 to find excited states.\nspectral_strategy = GramSchmidt(n_spectral): The SpectralStrategy used for orthogonalizing spectral states.\n\nExample\n\njulia> hamiltonian = HubbardReal1D(BoseFS(1,2,3));\n\njulia> problem = ProjectorMonteCarloProblem(hamiltonian; target_walkers = 500, last_step = 100);\n\njulia> simulation = solve(problem);\n\njulia> simulation.success[]\ntrue\n\njulia> size(DataFrame(simulation))\n(100, 9)\n\nFurther keyword arguments:\n\nstarting_step = 1: Starting step of the simulation.\nwall_time = Inf: Maximum time allowed for the simulation.\nsimulation_plan = SimulationPlan(; starting_step, last_step, wall_time): Defines the duration of the simulation. Takes precedence over last_step and wall_time.\nζ = 0.08: Damping parameter for the shift update.\nξ = ζ^2/4: Forcing parameter for the shift update.\nshift_strategy = DoubleLogUpdate(; target_walkers, ζ, ξ): How to update the shift, see ShiftStrategy.\ntime_step_strategy = ConstantTimeStep(): Adjust time step or not, see TimeStepStrategy.\nalgorithm = FCIQMC(; shift_strategy, time_step_strategy): The algorithm to use. Currenlty only FCIQMC is implemented.\nshift: Initial shift value or collection of shift values. Determined by default from the Hamiltonian and the starting vectors.\ninitial_shift_parameters: Initial shift parameters or collection of initial shift parameters. Overrides shift if provided.\nmax_length = 2 * target_walkers + 100: Maximum length of the vectors.\ndisplay_name = \"PMCSimulation\": Name displayed in progress bar (via ProgressLogging).\nmetadata: User-supplied metadata to be added to the report. Must be an iterable of pairs or a NamedTuple, e.g. metadata = (\"key1\" => \"value1\", \"key2\" => \"value2\"). All metadata is converted to strings.\nrandom_seed = true: Provide and store a seed for the random number generator. If set to true, a new random seed is generated from RandomDevice(). If set to number, this number is used as the seed. This seed is used by solve (and init) to re-seed the default random number generator (consistently on each MPI rank) such that solveing the same ProjectorMonteCarloProblem twice will yield identical results. If set to false, no seed is used and consecutive random numbers are used.\nminimum_size = 2*num_spectral_states(spectral_strategy): The minimum size of the basis used to construct starting vectors for simulations of spectral states, if start_at is not provided.\n\nSee also init, solve.\n\n\n\n\n\n","category":"type"},{"location":"projectormontecarlo.html#CommonSolve.init-projectormontecarlo","page":"Projector Monte Carlo","title":"CommonSolve.init","text":"init(p::ExactDiagonalizationProblem, [algorithm]; kwargs...)\n\nInitialize a solver for an ExactDiagonalizationProblem p with an optional algorithm. Returns a solver instance that can be solved with solve.\n\nFor a description of the keyword arguments, see the documentation for ExactDiagonalizationProblem.\n\n\n\n\n\ninit(problem::ProjectorMonteCarloProblem; copy_vectors=true)::PMCSimulation\n\nInitialise a Rimu.PMCSimulation.\n\nSee also ProjectorMonteCarloProblem, solve!, solve, step!, Rimu.PMCSimulation.\n\n\n\n\n\n","category":"function"},{"location":"projectormontecarlo.html#CommonSolve.solve-projectormontecarlo","page":"Projector Monte Carlo","title":"CommonSolve.solve","text":"solve(::ProjectorMonteCarloProblem)::PMCSimulation\n\nInitialize and solve a ProjectorMonteCarloProblem until the last step is completed or the wall time limit is reached.\n\nSee also init, solve!, step!, Rimu.PMCSimulation, and solve(::ExactDiagonalizationProblem).\n\n\n\n\n\n","category":"function"},{"location":"projectormontecarlo.html#CommonSolve.solve!-projectormontecarlo","page":"Projector Monte Carlo","title":"CommonSolve.solve!","text":"solve!(sm::PMCSimulation; kwargs...)::PMCSimulation\n\nSolve a Rimu.PMCSimulation until the last step is completed or the wall time limit is reached.\n\nTo continue a previously completed simulation, set a new last_step or wall_time using the keyword arguments. Optionally, changes can be made to the replica_strategy, the post_step_strategy, or the reporting_strategy.\n\nOptional keyword arguments:\n\nlast_step = nothing: Set the last step to a new value and continue the simulation.\nwall_time = nothing: Set the allowed wall time to a new value and continue the simulation.\nreset_time = false: Reset the elapsed_time counter and continue the simulation.\nempty_report = false: Empty the report before continuing the simulation.\nreplica_strategy = nothing: Change the replica strategy. Requires the number of replicas to match the number of replicas in the simulation sm. Implies empty_report = true.\npost_step_strategy = nothing: Change the post-step strategy. Implies empty_report = true.\nreporting_strategy = nothing: Change the reporting strategy. Implies empty_report = true.\nmetadata = nothing: Add metadata to the report.\n\nSee also ProjectorMonteCarloProblem, init, solve, step!, Rimu.PMCSimulation.\n\n\n\n\n\n","category":"function"},{"location":"projectormontecarlo.html#CommonSolve.step!-projectormontecarlo","page":"Projector Monte Carlo","title":"CommonSolve.step!","text":"step!(sm::PMCSimulation)::PMCSimulation\n\nAdvance the simulation by one step.\n\nCalling solve! will advance the simulation until the last step or the wall time is exceeded. When completing the simulation without calling solve!, the simulation report needs to be finalised by calling Rimu.finalize_report!.\n\nSee also ProjectorMonteCarloProblem, init, solve!, solve, Rimu.PMCSimulation.\n\n\n\n\n\n","category":"function"},{"location":"projectormontecarlo.html","page":"Projector Monte Carlo","title":"Projector Monte Carlo","text":"After solve or solve! have been called the returned PMCSimulation contains the results of the projector Monte Carlo calculation.","category":"page"},{"location":"projectormontecarlo.html#PMCSimulation-and-report-as-a-DataFrame","page":"Projector Monte Carlo","title":"PMCSimulation and report as a DataFrame","text":"","category":"section"},{"location":"projectormontecarlo.html","page":"Projector Monte Carlo","title":"Projector Monte Carlo","text":"Rimu.PMCSimulation","category":"page"},{"location":"projectormontecarlo.html#Rimu.PMCSimulation-projectormontecarlo","page":"Projector Monte Carlo","title":"Rimu.PMCSimulation","text":"PMCSimulation\n\nHolds the state and the results of a projector quantum Monte Carlo (PMC) simulation. Is returned by init(::ProjectorMonteCarloProblem) and solved with solve!(::PMCSimulation).\n\nObtain the results of a simulation sm as a DataFrame with DataFrame(sm).\n\nFields\n\nproblem::ProjectorMonteCarloProblem: The problem that was solved\nstate::Rimu.ReplicaState: The current state of the simulation\nreport::Rimu.Report: The report of the simulation\nmodified::Bool: Whether the simulation has been modified\naborted::Bool: Whether the simulation has been aborted\nsuccess::Bool: Whether the simulation has been completed successfully\nmessage::String: A message about the simulation status\nelapsed_time::Float64: The time elapsed during the simulation\n\nSee also state_vectors, ProjectorMonteCarloProblem, init, solve!.\n\n\n\n\n\n","category":"type"},{"location":"projectormontecarlo.html","page":"Projector Monte Carlo","title":"Projector Monte Carlo","text":"The DataFrame returned from DataFrame(::PMCSimulation) contains the time series data from the projector Monte Carlo simulation that is of primary interest for analysis. Depending on the reporting_strategy and other options passed as keyword arguments to ProjectorMonteCarloProblem it can have different numbers of rows and columns. The rows correspond to the reported time steps (Monte Carlo steps). There is at least one column with the name :step. Further columns are usually present with additional data reported from the simulation.","category":"page"},{"location":"projectormontecarlo.html","page":"Projector Monte Carlo","title":"Projector Monte Carlo","text":"For the default option algorithm = FCIQMC(; shift_strategy, time_step_strategy) with a single replica (n_replicas = 1) and single spectral state, the fields :shift, :norm, :len will be present as well as others depending on the style argument and the post_step_strategy.","category":"page"},{"location":"projectormontecarlo.html","page":"Projector Monte Carlo","title":"Projector Monte Carlo","text":"If multiple replicas or spectral states are requested, then the relevant field names in the DataFrame will have a suffix identifying the respective replica simulation, e.g. the shifts will be reported as shift_1, shift_2, ... ","category":"page"},{"location":"projectormontecarlo.html","page":"Projector Monte Carlo","title":"Projector Monte Carlo","text":"Many tools for analysing the time series data obtained from a ProjectorMonteCarloProblem are contained in the Module StatsTools.","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"EditURL = \"../../../scripts/G2-example.jl\"","category":"page"},{"location":"generated/G2-example.html#Example-3:-Calculating-observables","page":"Calculating observables","title":"Example 3: Calculating observables","text":"","category":"section"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"This is an example calculation of the two-body correlation function G_2.","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"A runnable script for this example is located here. Run it with julia G2-example.jl.","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"First, we load the reqired packages. Rimu for FCIQMC calculation, and DataFrames for maniplating the output.","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"using Rimu\nusing Random\nusing DataFrames","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"We use the same Hamiltonian as the first example, a Bose-Hubbard model with 6 particles in 6 sites, with strong interactions (we expect a Mott insulating state).","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"m = n = 6\ninitial_address = near_uniform(BoseFS{n,m})\nH = HubbardReal1D(initial_address; u = 6.0, t = 1.0)","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"HubbardReal1D(fs\"|1 1 1 1 1 1⟩\"; u=6.0, t=1.0)","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"Now, we define the operators for the observables we wish to calculate.","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"dvals = 0:m-1\nG2list = ((G2RealCorrelator(d) for d in dvals)...,)","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"(G2RealCorrelator(0), G2RealCorrelator(1), G2RealCorrelator(2), G2RealCorrelator(3), G2RealCorrelator(4), G2RealCorrelator(5))","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"This is a tuple of G2RealCorrelators, subtypes of AbstractHamiltonian. It calculates the density-density correlation function on a lattice","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":" hatG^(2)(d) = frac1M sum_i^M hatn_i (hatn_i+d - delta_0d)","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"with normalisation","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":" sum_d=0^M-1 langle hatG^(2)(d) rangle = fracN (N-1)M","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"Observables that are defined by expectation values are calculated using the \"replica trick\". Thereby several independent copies or \"replicas\" of the state vector are propagated simultaneously. The reason is to have two (or more) stochastically independent copies of the state vector available such that we can calculate bias-free overlaps. We enable this by defining a ReplicaStrategy. Each replica has its own state and FCIQMC is effectively performed independently on each one. For calculating observables, we use AllOverlaps for the ReplicaStrategy. At each timestep, after the FCIQMC step is performed on, this strategy calculates the overlaps of every operator with the wavefunctions from each pair of replicas.","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"To obtain an unbiased result, at least two replicas should be used. One can also use more than two to improve the statistics. This is particularly helpful when the walker number is low.","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"n_replicas = 3\nreplica_strategy = AllOverlaps(n_replicas; operator=G2list)","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"AllOverlaps{3, 6, Tuple{G2RealCorrelator{0}, G2RealCorrelator{1}, G2RealCorrelator{2}, G2RealCorrelator{3}, G2RealCorrelator{4}, G2RealCorrelator{5}}, true}((G2RealCorrelator(0), G2RealCorrelator(1), G2RealCorrelator(2), G2RealCorrelator(3), G2RealCorrelator(4), G2RealCorrelator(5)))","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"Other FCIQMC parameters and strategies can be set in the same way as before.","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"steps_equilibrate = 1_000\nsteps_measure = 5_000\ntarget_walkers = 100;\ntime_step = 0.001\n","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"Now, we run FCIQMC. Note that passing an initial vector is optional - if we only pass the style, a vector with the appropriate style is created automatically.","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"problem = ProjectorMonteCarloProblem(H;\n style=IsDynamicSemistochastic(),\n time_step,\n last_step = steps_equilibrate + steps_measure,\n target_walkers,\n replica_strategy,\n)\nresult = solve(problem)\ndf = DataFrame(result);","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"The output DataFrame has FCIQMC statistics for each replica (e.g. shift, norm),","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"println(filter(startswith(\"shift_\"), names(df)))","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"[\"shift_1\", \"shift_2\", \"shift_3\"]\n","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"as well as vector-vector overlaps (e.g. c1_dot_c2),","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"println(filter(contains(\"dot\"), names(df)))","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"[\"c1_dot_c2\", \"c1_dot_c3\", \"c2_dot_c3\"]\n","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"and operator overlaps (e.g. c1_Op1_c2) between the replicas.","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"println(filter(contains(\"Op\"), names(df)))","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"[\"c1_Op1_c2\", \"c1_Op2_c2\", \"c1_Op3_c2\", \"c1_Op4_c2\", \"c1_Op5_c2\", \"c1_Op6_c2\", \"c1_Op1_c3\", \"c1_Op2_c3\", \"c1_Op3_c3\", \"c1_Op4_c3\", \"c1_Op5_c3\", \"c1_Op6_c3\", \"c2_Op1_c3\", \"c2_Op2_c3\", \"c2_Op3_c3\", \"c2_Op4_c3\", \"c2_Op5_c3\", \"c2_Op6_c3\"]\n","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"The vector-vector and operator overlaps go into calculating the Rayleigh quotient for an observable","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":" langle hatG^(2)(d) rangle = fracsum_ab mathbfc_a^dagger cdot hatG^(2)(d) cdot mathbfc_bsum_ab mathbfc_a^dagger cdot mathbfc_b ","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"The sum over all replica pairs (a,b), especially in the denominator, helps to avoid errors from poor sampling if the number of walkers is too low.","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"We use the function rayleigh_replica_estimator to calculate the Rayleigh quotient using all replicas in df, returning a RatioBlockingResult. Using the keyword skip will ignore the initial equilibration steps.","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"Now, we can calculate the correlation function for each value of d.","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"println(\"Two-body correlator from $n_replicas replicas:\")\nfor d in dvals\n r = rayleigh_replica_estimator(df; op_name = \"Op$(d+1)\", skip=steps_equilibrate)\n println(\" G2($d) = $(r.f) ± $(r.σ_f)\")\nend","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"Two-body correlator from 3 replicas:\n G2(0) = 0.20880526675490996 ± 0.001650235029310676\n G2(1) = 0.9187078655187123 ± 0.0007600488432629197\n G2(2) = 0.9821782165945223 ± 0.0006972126484492098\n G2(3) = 0.9894225690186212 ± 0.0009186561663562719\n G2(4) = 0.9821782165945223 ± 0.0006972126484492098\n G2(5) = 0.9187078655187123 ± 0.0007600488432629197\n","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"As expected, the onsite correlation at d=0 is low since this is a Mott insulating state with unit filling fraction, and is close to 10 for all other values of the displacement d.","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"Since we ran multiple independent replicas, we also have multiple estimates of the shift energy.","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"println(\"Shift energy from $n_replicas replicas:\")\nfor i in 1:n_replicas\n se = shift_estimator(df; shift=\"shift_$i\", skip=steps_equilibrate)\n println(\" Replica $i: $(se.mean) ± $(se.err)\")\nend\n","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"Shift energy from 3 replicas:\n Replica 1: -4.0481027033902715 ± 0.14022744896804235\n Replica 2: -3.999175246993472 ± 0.1440589169512744\n Replica 3: -4.004366054970122 ± 0.13757576512903064\n","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"","category":"page"},{"location":"generated/G2-example.html","page":"Calculating observables","title":"Calculating observables","text":"This page was generated using Literate.jl.","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"EditURL = \"../../../scripts/BHM-example.jl\"","category":"page"},{"location":"generated/BHM-example.html#Example-1:-1D-Bose-Hubbard-Model","page":"1D Bose-Hubbard Model","title":"Example 1: 1D Bose-Hubbard Model","text":"","category":"section"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"This is an example calculation finding the ground state of a 1D Bose-Hubbard chain with 6 particles in 6 lattice sites.","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"A runnable script for this example is located here. Run it with julia BHM-example.jl.","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"First, we load Rimu and Plots.","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"using Rimu\nusing Plots","category":"page"},{"location":"generated/BHM-example.html#Setting-up-the-model","page":"1D Bose-Hubbard Model","title":"Setting up the model","text":"","category":"section"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"We start by defining the physical problem. First, we generate an initial configuration which will be used as a starting point of our computation. In this example, we use a bosonic Fock state with 6 particles evenly distributed in 6 lattice sites.","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"initial_address = near_uniform(BoseFS{6,6})","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"BoseFS{6,6}(1, 1, 1, 1, 1, 1)","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"The Hamiltonian is constructed by initializing a struct with an initial address and model parameters. Here, we use the Bose Hubbard model in one-dimensional real space.","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"H = HubbardReal1D(initial_address; u = 6.0, t = 1.0)","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"HubbardReal1D(fs\"|1 1 1 1 1 1⟩\"; u=6.0, t=1.0)","category":"page"},{"location":"generated/BHM-example.html#Parameters-of-the-calculation","page":"1D Bose-Hubbard Model","title":"Parameters of the calculation","text":"","category":"section"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"Now, let's setup the Monte Carlo calculation. We need to decide the number of walkers to use in this Monte Carlo run, which is equivalent to the average one-norm of the coefficient vector. Higher values will result in better statistics, but require more memory and computing power.","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"target_walkers = 1_000;","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"FCIQMC takes a certain number of steps to equllibrate, after which the observables will fluctuate around a mean value. In this example, we will devote 1000 steps to equilibration and take an additional 2000 steps for measurement.","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"steps_equilibrate = 1_000;\nsteps_measure = 2_000;\nlast_step = steps_equilibrate + steps_measure","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"3000","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"Next, we pick a time step size. FCIQMC does not have a time step error, but the time step needs to be small enough, or the computation might diverge. If the time step is too small, however, the computation might take a long time to equilibrate. The appropriate time step size is problem-dependent and is best determined through experimentation.","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"time_step = 0.001;","category":"page"},{"location":"generated/BHM-example.html#Defining-an-observable","page":"1D Bose-Hubbard Model","title":"Defining an observable","text":"","category":"section"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"Now, let's set up an observable to measure. Here we will measure the projected energy. In additon to the shift, the projected energy is a second estimator for the energy. It usually produces better statistics than the shift.","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"We first need to define a projector. Here, we use the function default_starting_vector to generate a vector with only a single occupied configuration. We will use the same vector as the starting vector for the FCIQMC calculation.","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"initial_vector = default_starting_vector(initial_address; style=IsDynamicSemistochastic())","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"DVec{BoseFS{6, 6, BitString{11, 1, UInt16}},Float64} with 1 entry, style = IsDynamicSemistochastic{Float64,ThresholdCompression,DynamicSemistochastic}()\n fs\"|1 1 1 1 1 1⟩\" => 10.0","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"The choice of the style argument already determines the FCIQMC algorithm to use. IsDynamicSemistochastic is usually the best choice as it reduces noise and improves the sign problem.","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"Observables that can be calculated by projection of the fluctuating quantum state onto a constant vector are passed into the ProjectorMonteCarloProblem with the post_step_strategy keyword argument.","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"post_step_strategy = ProjectedEnergy(H, initial_vector)","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"ProjectedEnergy{HubbardReal1D{Float64, BoseFS{6, 6, BitString{11, 1, UInt16}}, 6.0, 1.0}, Rimu.DictVectors.FrozenDVec{BoseFS{6, 6, BitString{11, 1, UInt16}}, Float64}, Rimu.DictVectors.FrozenDVec{BoseFS{6, 6, BitString{11, 1, UInt16}}, Float64}}(:vproj, :hproj, HubbardReal1D(fs\"|1 1 1 1 1 1⟩\"; u=6.0, t=1.0), Rimu.FrozenDVec([fs\"|1 1 1 1 1 1⟩\"=>10.0]), Rimu.FrozenDVec([fs\"|1 1 1 1 2 0⟩\"=>-14.1421, fs\"|0 2 1 1 1 1⟩\"=>-14.1421, fs\"|1 1 1 1 0 2⟩\"=>-14.1421, fs\"|1 2 0 1 1 1⟩\"=>-14.1421, fs\"|2 0 1 1 1 1⟩\"=>-14.1421, fs\"|1 1 1 2 0 1⟩\"=>-14.1421, fs\"|1 1 2 0 1 1⟩\"=>-14.1421, fs\"|1 1 0 2 1 1⟩\"=>-14.1421, fs\"|1 1 1 0 2 1⟩\"=>-14.1421, fs\"|1 0 2 1 1 1⟩\"=>-14.1421, fs\"|2 1 1 1 1 0⟩\"=>-14.1421, fs\"|0 1 1 1 1 2⟩\"=>-14.1421]))","category":"page"},{"location":"generated/BHM-example.html#Running-the-calculation","page":"1D Bose-Hubbard Model","title":"Running the calculation","text":"","category":"section"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"This is a two-step process: First we define a ProjectorMonteCarloProblem with all the parameters needed for the simulation","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"problem = ProjectorMonteCarloProblem(\n H;\n start_at = initial_vector,\n last_step,\n time_step,\n target_walkers,\n post_step_strategy\n);","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"To run the simulation we simply call solve on the problem","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"simulation = solve(problem);","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"The simulation object contains the results of the simulation as well as state vectors and strategies. We can extract the time series data for further analysis:","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"df = DataFrame(simulation);","category":"page"},{"location":"generated/BHM-example.html#Analysing-the-results","page":"1D Bose-Hubbard Model","title":"Analysing the results","text":"","category":"section"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"We can plot the norm of the coefficient vector as a function of the number of steps.","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"hline(\n [target_walkers];\n label=\"target_walkers\", xlabel=\"step\", ylabel=\"norm\",\n color=2, linestyle=:dash, margin = 1Plots.cm\n)\nplot!(df.step, df.norm, label=\"norm\", color=1)","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"\n\n\n \n \n \n\n\n\n \n \n \n\n\n\n \n \n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"After an initial equilibriation period, the norm fluctuates around the target number of walkers.","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"Now, let's look at using the shift to estimate the ground state energy of H. The mean of the shift is a useful estimator of the energy. Calculating the error bars is a bit more involved as autocorrelations have to be removed from the time series. This can be done with the function shift_estimator, which performs a blocking analysis on the shift column of the dataframe.","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"se = shift_estimator(df; skip=steps_equilibrate)","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"BlockingResult{Float64}\n mean = -4.041 ± 0.025\n with uncertainty of ± 0.002249521709283463\n from 62 blocks after 5 transformations (k = 6).\n","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"Here, se contains the calculated mean and standard errors of the shift, as well as some additional information related to the blocking analysis.","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"Computing the error of the projected energy is a bit more complicated, as it's a ratio of fluctuating variables contained in the hproj and vproj columns in the dataframe. Thankfully, the complications are handled by the function projected_energy.","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"pe = projected_energy(df; skip=steps_equilibrate)","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"RatioBlockingResult{Float64,MonteCarloMeasurements.Particles{Float64, 2000}}\n ratio = -4.01331 ± (0.00328573, 0.00353296) (MC)\n 95% confidence interval: [-4.02063, -4.00652] (MC)\n linear error propagation: -4.01353 ± 0.00354394\n |δ_y| = |0.00322799| (≤ 0.1 for normal approx)\n Blocking successful with 15 blocks after 7 transformations (k = 8).\n","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"The result is a ratio distribution. We extract its median and the edges of the 95% confidence interval.","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"v = val_and_errs(pe; p=0.95)","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"(val = -4.013309070980869, val_l = 0.007319929452815899, val_u = 0.006792034209384568)","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"Let's visualise these estimators together with the time series of the shift.","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"plot(df.step, df.shift, ylabel=\"energy\", xlabel=\"step\", label=\"shift\", margin = 1Plots.cm)\n\nplot!(x->se.mean, df.step[steps_equilibrate+1:end], ribbon=se.err, label=\"shift mean\")\nplot!(\n x -> v.val, df.step[steps_equilibrate+1:end], ribbon=(v.val_l,v.val_u),\n label=\"projected energy\",\n)\nlens!([steps_equilibrate, last_step], [-5.1, -2.9]; inset=(1, bbox(0.2, 0.25, 0.6, 0.4)))","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"\n\n\n \n \n \n\n\n\n \n \n \n\n\n\n \n \n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n \n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"In this case the projected energy and the shift are close to each other and the error bars are hard to see.","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"The problem was just a toy example, as the dimension of the Hamiltonian is rather small:","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"dimension(H)","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"462","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"In this case, it's easy (and more efficient) to calculate the exact ground state energy using standard linear algebra. Read more about Rimu's capabilities for exact diagonalization in the example \"Exact diagonalization\".","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"edp = ExactDiagonalizationProblem(H)\nexact_energy = solve(edp).values[1]","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"-4.021502406906473","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"We finish by comparing our FCIQMC results with the exact computation.","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"println(\n \"\"\"\n Energy from $steps_measure steps with $target_walkers walkers:\n Shift: $(se.mean) ± $(se.err)\n Projected Energy: $(v.val) ± ($(v.val_l), $(v.val_u))\n Exact Energy: $exact_energy\n \"\"\"\n)\n\n","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"Energy from 2000 steps with 1000 walkers:\nShift: -4.041259061220064 ± 0.02484677939503602\nProjected Energy: -4.013309070980869 ± (0.007319929452815899, 0.006792034209384568)\nExact Energy: -4.021502406906473\n\n","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"","category":"page"},{"location":"generated/BHM-example.html","page":"1D Bose-Hubbard Model","title":"1D Bose-Hubbard Model","text":"This page was generated using Literate.jl.","category":"page"},{"location":"statstools.html#Module-StatsTools","page":"StatsTools","title":"Module StatsTools","text":"","category":"section"},{"location":"statstools.html","page":"StatsTools","title":"StatsTools","text":"The module StatsTools contains helper function for analysis and post processing of Monte Carlo data.","category":"page"},{"location":"statstools.html#Blocking-analysis","page":"StatsTools","title":"Blocking analysis","text":"","category":"section"},{"location":"statstools.html","page":"StatsTools","title":"StatsTools","text":"After equilibration, FCIQMC produces information about observables through correlated time series. In order to estimate the statistical errors the time series need to be decorrelated. The main workhorse for achieving this is the blocking_analysis, which is based on the paper by Flyvberg and Peterson JCP (1989), and automated with the M test of Jonsson PRE (2018).","category":"page"},{"location":"statstools.html","page":"StatsTools","title":"StatsTools","text":"Analysing the stochastic errors of observables obtained from the ratio of sample means is done with ratio_of_means, where error propagation of correlated uncertainties is done with the help of the package MonteCarloMeasurements.","category":"page"},{"location":"statstools.html","page":"StatsTools","title":"StatsTools","text":"Many convenience functions are implemented for directly analysing data obtained from solve as a DataFrame. See, e.g., shift_estimator and projected_energy. Asymptotically unbiased estimators are implemented as mixed_estimator, growth_estimator and rayleigh_replica_estimator.","category":"page"},{"location":"statstools.html#Exported","page":"StatsTools","title":"Exported","text":"","category":"section"},{"location":"statstools.html","page":"StatsTools","title":"StatsTools","text":"Modules = [StatsTools]\nPages = [\"StatsTools.jl\", \"blocking.jl\", \"ratio_of_means.jl\", \"convenience.jl\",\n \"variances.jl\", \"growth_witness.jl\", \"reweighting.jl\", \"fidelity.jl\", \"variational_energy_estimator.jl\"\n]\nPrivate = false","category":"page"},{"location":"statstools.html#Rimu.StatsTools","page":"StatsTools","title":"Rimu.StatsTools","text":"Tools for the statistical analysis of Monte Carlo data.\n\nExports:\n\nblocking_analysis\nblocking_analysis_data\nratio_of_means\ngrowth_witness\nsmoothen\nshift_estimator\nprojected_energy\nvariational_energy_estimator\ngrowth_estimator\ngrowth_estimator_analysis\nmixed_estimator\nmixed_estimator_analysis\nrayleigh_replica_estimator\nrayleigh_replica_estimator_analysis\nval_and_errs\nval\nmean_and_se\n\n\n\n\n\n","category":"module"},{"location":"statstools.html#Rimu.StatsTools.blocking_analysis-Tuple{AbstractVector}","page":"StatsTools","title":"Rimu.StatsTools.blocking_analysis","text":"blocking_analysis(v::AbstractVector; α = 0.01, corrected = true, skip=0, warn=true)\n-> BlockingResult(mean, err, err_err, p_cov, k, blocks)\n\nCompute the sample mean mean and estimate the standard deviation of the mean (standard error) err of a correlated time series. It uses the blocking algorithm from Flyvberg and Peterson JCP (1989) and the M test of Jonsson PRE (2018) at significance level 1-α.\n\nUse skip to skip the first skip elements in v. corrected controls whether bias correction for variances is used. If decorrelating the time series fails according to the M test, NaN is returned as the standard error and -1 for k. The keyword argument warn controls whether a warning message is logged.\n\nThe summary result is returned as a BlockingResult. k - 1 is the number of blocking transformations required to pass the hypothesis test for an uncorrelated time series and err_err the estimated standard error or err.\n\nThe detailed results from each reblocking step can be obtained with blocking_analysis_data.\n\nSee BlockingResult, shift_estimator, ratio_of_means, blocking_analysis_data.\n\n\n\n\n\n","category":"method"},{"location":"statstools.html#Rimu.StatsTools.blocking_analysis_data-Tuple{AbstractVector}","page":"StatsTools","title":"Rimu.StatsTools.blocking_analysis_data","text":"blocking_analysis_data(v::AbstractVector; kwargs...) ->\n(; br::BlockingResult, df::DataFrame)\n\nPerform a blocking_analysis and return the summary result br as well as a DataFrame df with information about the standard error in each blocking step.\n\nFor a description of the keyword arguments see blocking_analysis.\n\nExample\n\njulia> data = smoothen(rand(10_000), 2^6); # generate correlated data\n\njulia> br, df = blocking_analysis_data(data)\n(br = BlockingResult{Float64}\n mean = 0.5088 ± 0.0029\n with uncertainty of ± 0.00023454488294744232\n from 78 blocks after 7 transformations (k = 8).\n, df = 13×6 DataFrame\n Row │ blocks mean std_err std_err_err p_cov mj\n │ Int64 Float64 Float64 Float64 Float64 Float64\n─────┼──────────────────────────────────────────────────────────────────────\n 1 │ 10000 0.508806 0.000375044 2.6521e-6 1.40658e-7 9715.08\n 2 │ 5000 0.508806 0.000528547 5.28599e-6 2.79361e-7 4778.14\n 3 │ 2500 0.508806 0.000743386 1.05152e-5 5.52622e-7 2298.64\n 4 │ 1250 0.508806 0.00104064 2.08212e-5 1.08293e-6 1056.24\n 5 │ 625 0.508806 0.00144177 4.08121e-5 2.07871e-6 427.949\n 6 │ 312 0.508736 0.00194209 7.78707e-5 3.77171e-6 128.711\n 7 │ 156 0.508736 0.00247921 0.00014081 6.14647e-6 17.3075\n 8 │ 78 0.508736 0.00291063 0.000234545 8.47174e-6 0.731386\n 9 │ 39 0.508736 0.00284613 0.000326474 8.10046e-6 0.901054\n 10 │ 19 0.508241 0.0026998 0.000449967 7.28892e-6 2.85915\n 11 │ 9 0.507939 0.00359907 0.000899766 1.29533e-5 1.08644\n 12 │ 4 0.509327 0.00440559 0.00179857 1.94092e-5 0.0370381\n 13 │ 2 0.509327 0.00432708 0.00305971 1.87237e-5 0.125)\n\njulia> using StatsPlots; unicodeplots();\n\njulia> plot([br.k,br.k],[0.0,maximum(df.std_err.+df.std_err_err)], label=\"m test\");\n\njulia> @df df plot!(\n 1:length(:std_err), :std_err;\n err=:std_err_err, xlabel=\"k\", label=\"std err\",\n title=\"std err vs blocking steps\"\n )\n ⠀⠀⠀⠀⠀⠀⠀⠀⠀std err vs blocking steps⠀⠀⠀⠀⠀⠀⠀⠀\n ┌────────────────────────────────────────┐\n 0.00423501 │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⠀⠀⠀⠀│ m test\n │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠀⠀⢸⠀⠀⠀⠀│ std err\n │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⠀⠀⢸⠀⠀⠀⠀│\n │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⠀⠀⢸⠀⠀⠀⠀│\n │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⡠⢺⠒⠒⢺⠀⠀⠀⠀│\n │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⡀⠀⠀⡆⣀⠤⡗⠉⠀⢸⠀⠀⢸⡆⠀⠀⠀│\n │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⡧⠤⠔⡗⠊⠉⡏⠀⠀⡇⠀⠀⢸⠀⠀⢸⢣⠀⠀⠀│\n │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠔⠁⡇⠀⠀⠁⠀⠀⠁⠀⠀⠁⠀⠀⠀⠀⠀⢸⠸⡀⠀⠀│\n │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠴⠁⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠸⠀⡇⠀⠀│\n │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠔⠁⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⠀⠀│\n │⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠔⠊⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⣦⠀│\n │⠀⠀⠀⠀⠀⠀⠀⠀⡠⠔⠒⠁⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢹⠀│\n │⠀⠀⠀⢀⣀⠤⠒⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⠀│\n │⠀⠒⠉⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⠀│\n -0.00012335 │⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠧⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤│\n └────────────────────────────────────────┘\n ⠀0.64⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀k⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀13.36⠀\n\nA vertical line at k==8 indicates the blocking step identified by hypothesis testing to decorrelate the time series data. The decorrelation length can thus be estimated at 2^k-1 = 2^7 = 128. Note that the data was correlated with a sliding window of 2^6 steps.\n\nSee blocking_analysis, BlockingResult.\n\n\n\n\n\n","category":"method"},{"location":"statstools.html#Rimu.StatsTools.mean_and_se-Tuple{Rimu.StatsTools.BlockingResult}","page":"StatsTools","title":"Rimu.StatsTools.mean_and_se","text":"mean_and_se(v::AbstractVector; α = 0.01, corrected::Bool=true, skip=0) -> mean, err\nmean_and_se(r::BlockingResult) -> mean, err\n\nReturn the mean and standard error (as a tuple) of a time series obtained from blocking_analysis. See also BlockingResult.\n\n\n\n\n\n","category":"method"},{"location":"statstools.html#Statistics.cov-Tuple{Rimu.StatsTools.BlockingResult{<:Complex}}","page":"StatsTools","title":"Statistics.cov","text":"cov(r::BlockingResult{<:Complex})\n\nReturn the covariance matrix of the multivariate normal distribution approximating the uncertainty of the blocking result r of a complex time series. See (https://en.wikipedia.org/wiki/Complexnormaldistribution).\n\n\n\n\n\n","category":"method"},{"location":"statstools.html#Rimu.StatsTools.ratio_of_means-Tuple{Any, Any}","page":"StatsTools","title":"Rimu.StatsTools.ratio_of_means","text":"ratio_of_means(num, denom; α=0.01, corrected=true, mc_samples=nothing, skip=0, warn=true)\n-> r::RatioBlockingResult\n\nEstimate the ratio of mean(num)/mean(denom) assuming that num and denom are possibly correlated time series, skipping the first skip elements. A blocking analysis with m-test is used to uncorrelate the time series, see blocking_analysis. The remaining standard error and correlation of the means is propagated using MonteCarloMeasurements. The results are reported as a RatioBlockingResult.\n\nRobust estimates for the ratio are obtained from pmedian(r) and confidence intervals from pquantile(), e.g. pquantile(r, [0.025, 0.975]) for the 95% confidence interval.\n\nEstimates from linear uncertainty propagation are returned as r.f and r.σ_f using x_by_y_linear. The standard error estimate r.σ_f should only be trusted when the coefficient of variation std(denom)/mean(denom) is small: abs(r.δ_y) < 0.1. Under this condition can the ratio be approximated as a normal distribution. See wikipedia and Díaz-Francés, Rubio (2013)\n\nThe keyword mc_samples controls the number of samples used for error propagation by MonteCarloMeasurements. Use nothing for the default and Val(1000) to set the number to 1000 samples in a type-consistent way.\n\nThe keyword warn controls whether warning messages are logged when blocking fails or noisy denominators are encountered.\n\nNote: to compute statistics on the RatioBlockingResult, use functions pmedian, pquantile, pmiddle, piterate, pextrema, pminimum, pmaximum, pmean, and pcov.\n\n\n\n\n\n","category":"method"},{"location":"statstools.html#Rimu.StatsTools.errs-Tuple","page":"StatsTools","title":"Rimu.StatsTools.errs","text":"errs(x; n=1, p=nothing, name=:err) -> (; err_l, err_u)\n\nReturn the lower and upper error bar for the uncertain value x.\n\nSee val_and_errs.\n\n\n\n\n\n","category":"method"},{"location":"statstools.html#Rimu.StatsTools.to_measurement-Tuple{MonteCarloMeasurements.Particles}","page":"StatsTools","title":"Rimu.StatsTools.to_measurement","text":"to_measurement(p::MonteCarloMeasurements.Particles) -> ::Measurements.measurement\n\nConvert an uncertain number from MonteCarloMeasurements to Measurements format using the median as the central point. The new ± boundaries will include the 68% quantile around the median.\n\n\n\n\n\n","category":"method"},{"location":"statstools.html#Rimu.StatsTools.val-Tuple{Any}","page":"StatsTools","title":"Rimu.StatsTools.val","text":"val(x)\n\nReturn the best estimate value for an uncertain x. Defaults to the median for uncertain x represented by a (sampled) distribution. Supports MonteCarloMeasurements and Measurements.\n\nSee errs, BlockingResult, RatioBlockingResult.\n\n\n\n\n\n","category":"method"},{"location":"statstools.html#Rimu.StatsTools.val_and_errs-Tuple{Any}","page":"StatsTools","title":"Rimu.StatsTools.val_and_errs","text":"val_and_errs(x; n=1, p=nothing, name=:val) -> (;val, val_l, val_u)\n\nReturn the median and the lower and upper error bar for the uncertain value x as a NamedTuple. This is useful for plotting scripts. The interval [val - val_l, val + val_u] represents the confidence interval at level n*σ, or at probability p. Setting p overrides n. Supports MonteCarloMeasurements and Measurements. The names in the NamedTuple can be changed with name.\n\nExample:\n\njulia> results = [blocking_analysis(i:0.1:2i+20) for i in 1:3]; # mock results\n\njulia> v = val_and_errs.(results, name=\"res\"); # Vector of NamedTuple's with standard errors\n\njulia> DataFrame(v)\n3×3 DataFrame\n Row │ res res_l res_u\n │ Float64 Float64 Float64\n─────┼───────────────────────────\n 1 │ 11.5 1.7282 1.7282\n 2 │ 13.0 1.7282 1.7282\n 3 │ 14.5 1.78885 1.78885\n\nSee NamedTuple, val, errs, BlockingResult, RatioBlockingResult.\n\n\n\n\n\n","category":"method"},{"location":"statstools.html#Rimu.StatsTools.growth_witness","page":"StatsTools","title":"Rimu.StatsTools.growth_witness","text":"growth_witness(df::DataFrame, [b];\n shift=:shift,\n norm=:norm,\n time_step=determine_constant_time_step(df),\n skip=0\n)\ngrowth_witness(sim::PMCSimulation, [b]; kwargs...)\n\nCalculate the growth witness directly from the result (DataFrame or PMCSimulation) of solveing a ProjectorMonteCarloProblem. The keyword arguments shift and norm can be used to change the names of the relevant columns.\n\n\n\n\n\n","category":"function"},{"location":"statstools.html#Rimu.StatsTools.growth_witness-Tuple{AbstractArray, AbstractArray, Any}","page":"StatsTools","title":"Rimu.StatsTools.growth_witness","text":"growth_witness(shift::AbstractArray, norm::AbstractArray, dt, [b]; skip=0)\n\nCompute the growth witness\n\nG^(n) = S^(n) - fracvertmathbfc^(n+1)vert -\n vertmathbfc^(n)vertvertmathbfc^(n)vert dtau\n\nwhere S is the shift and vertmathbfc^(n)vert == norm[n, 1]. Setting b ≥ 1 a sliding average over b time steps is computed using smoothen(). The first skip time steps are skipped. mean(growth_witness) is approximately the same as growth_estimator with h=0.\n\nSee also growth_estimator.\n\n\n\n\n\n","category":"method"},{"location":"statstools.html#Rimu.StatsTools.smoothen-Tuple{AbstractVector, Integer}","page":"StatsTools","title":"Rimu.StatsTools.smoothen","text":"smoothen(noisy::AbstractVector, b)\n\nSmoothen the array noisy by averaging over a sliding window of length b and wrapping noisy periodically. The mean(noisy) is preserved.\n\n\n\n\n\n","category":"method"},{"location":"statstools.html#Rimu.StatsTools.growth_estimator-NTuple{4, Any}","page":"StatsTools","title":"Rimu.StatsTools.growth_estimator","text":"growth_estimator(\n shift, wn, h, time_step;\n skip = 0,\n E_r = mean(shift[skip+1:end]),\n weights = w_exp,\n change_type = identity,\n kwargs...\n)\ngrowth_estimator(\n df::DataFrame, h;\n shift_name=:shift,\n norm_name=:norm,\n time_step=determine_constant_time_step(df),\n kwargs...\n)\ngrowth_estimator(sim::PMCSimulation; kwargs...)\n-> r::RatioBlockingResult\n\nCompute the growth estimator with reference energy E_r by the reweighting technique described in Umrigar et al. (1993), see Eq. (20). shift and wn are equal length vectors containing the shift and walker number time series, respectively. Reweighting is done over h time steps and length(shift) - skip time steps are used for the blocking analysis done with ratio_of_means. weights is a function that calulates the weights. See w_exp and w_lin.\n\nE_gr = E_r - frac1dτln\n fracsum_n w_h+1^(n+1) N_mathrmw^(n+1)\n sum_m w_h^(m) N_mathrmw^(m) \n\nwhere dτ is the time_step\n\nWhen h is greater than the autocorrelation time scale of the shift, then E_gr (returned as r.ratio) is an unbiased but approximate estimator for the ground state energy E_0 with an error mathcalO(dτ^2) and potentially increased confidence intervals compared to the (biased) shift estimator. Error propagation is done with MonteCarloMeasurements. Propagation through the logarithm can be modified by setting change_type to to_measurement in order to avoid NaN results from negative outliers.\n\nIf success==true the blocking analysis was successful in k-1 steps, using blocks uncorrelated data points.\n\nThe second method calculates the growth estimator directly from a PMCSimulation or DataFrame returned by solve. The keyword arguments shift_name and norm_name can be used to change the names of the relevant columns.\n\nSee also mixed_estimator and RatioBlockingResult.\n\n\n\n\n\n","category":"method"},{"location":"statstools.html#Rimu.StatsTools.growth_estimator_analysis-Tuple{Any}","page":"StatsTools","title":"Rimu.StatsTools.growth_estimator_analysis","text":"growth_estimator_analysis(df::DataFrame; kwargs...)\ngrowth_estimator_analysis(sim::PMCSimulation; kwargs...)\n-> (; df_ge, correlation_estimate, se, se_l, se_u)\n\nCompute the growth_estimator on a DataFrame df or PMCSimulation sim. repeatedly over a range of reweighting depths.\n\nReturns a NamedTuple with the fields\n\ndf_ge: DataFrame with reweighting depth and growth_estiamator data. See example below.\ncorrelation_estimate: estimated correlation time from blocking analysis\nse, se_l, se_u: shift_estimator and error\n\nKeyword arguments\n\nh_range: The default is about h_values values from 0 to twice the estimated correlation time\nh_values = 100: minimum number of reweighting depths\nskip = 0: initial time steps to exclude from averaging\nthreading = Threads.nthreads() > 1: if false a progress meter is displayed\nshift_name = :shift name of column in df with shift data\nnorm_name = :norm name of column in df with walkernumber data\ntime_step = determine_constant_time_step(df) the time step\nwarn = true whether to log warning messages when blocking fails or denominators are small\n\nExample\n\nsim = solve(...)\ndf_ge, correlation_estimate, se, se_l, se_u = growth_estimator_analysis(sim; skip=5_000)\n\nusing StatsPlots\n@df df_ge plot(_ -> se, :h, ribbon = (se_l, se_u), label = \"⟨S⟩\") # constant line and ribbon for shift estimator\n@df df_ge plot!(:h, :val, ribbon = (:val_l, :val_u), label=\"E_gr\") # growth estimator as a function of reweighting depth\nxlabel!(\"h\")\n\nSee also: growth_estimator, mixed_estimator_analysis.\n\n\n\n\n\n","category":"method"},{"location":"statstools.html#Rimu.StatsTools.mixed_estimator-Tuple{AbstractVector, AbstractVector, AbstractVector, Any, Any}","page":"StatsTools","title":"Rimu.StatsTools.mixed_estimator","text":"mixed_estimator(\n hproj, vproj, shift, h, time_step;\n skip = 0,\n E_r = mean(shift[skip+1:end]),\n weights = w_exp,\n kwargs...\n)\nmixed_estimator(\n df::DataFrame, h;\n hproj_name=:hproj,\n vproj_name=:vproj,\n shift_name=:shift,\n time_step=determine_constant_time_step(df),\n kwargs...\n)\nmixed_estimator(sim::PMCSimulation, h; kwargs...)\n-> r::RatioBlockingResult\n\nCompute the mixed estimator by the reweighting technique described in Umrigar et al. (1993), Eq. (19)\n\nE_mathrmmix = fracsum_n w_h^(n) (Hmathbfv)mathbfc^(n)\n sum_m w_h^(m) mathbfvmathbfc^(m) \n\nwhere the time series hproj == (Hmathbfv)mathbfc^(n) and vproj == mathbfvmathbfc^(m) have the same length as shift (See ProjectedEnergy on how to set these up). Reweighting is done over h time steps and length(shift) - skip time steps are used for the blocking analysis done with ratio_of_means. weights is a function that calulates the weights. See w_exp and w_lin. Additional keyword arguments are passed on to ratio_of_means.\n\nWhen h is greater than the autocorrelation time scale of the shift, then r.ratio is an unbiased but approximate estimator for the ground state energy E_0 with an error mathcalO(dτ^2), where dτ is the time_step, and potentially increased confidence intervals compared to the unweighted ratio. Error propagation is done with MonteCarloMeasurements. Results are returned as RatioBlockingResult.\n\nThe second method calculates the mixed energy estimator directly from a DataFrame or PMCSimulation returned by solve. The keyword arguments hproj_name, vproj_name, and shift_name can be used to change the names of the relevant columns.\n\nSee also growth_estimator.\n\n\n\n\n\n","category":"method"},{"location":"statstools.html#Rimu.StatsTools.mixed_estimator_analysis-Tuple{DataFrame}","page":"StatsTools","title":"Rimu.StatsTools.mixed_estimator_analysis","text":"mixed_estimator_analysis(df::DataFrame; kwargs...)\nmixed_estimator_analysis(sim::PMCSimulation; kwargs...)\n-> (; df_me, correlation_estimate, se, se_l, se_u)\n\nCompute the mixed_estimator on a DataFrame df or PMCSimulation sim returned from solve repeatedly over a range of reweighting depths.\n\nReturns a NamedTuple with the fields\n\ndf_me: DataFrame with reweighting depth and mixed_estiamator data. See example below.\ncorrelation_estimate: estimated correlation time from blocking analysis\nse, se_l, se_u: shift_estimator and error\n\nKeyword arguments\n\nh_range: The default is about h_values values from 0 to twice the estimated correlation time\nh_values = 100: minimum number of reweighting depths\nskip = 0: initial time steps to exclude from averaging\nthreading = Threads.nthreads() > 1: if false a progress meter is displayed\nshift_name = :shift name of column in df with shift data\nhproj_name = :hproj name of column in df with operator overlap data\nvproj_name = :vproj name of column in df with projector overlap data\ntime_step = determine_constant_time_step(df) the time step\nwarn = true whether to log warning messages when blocking fails or denominators are small\n\nExample\n\nsim = solve(...)\ndf_me, correlation_estimate, se, se_l, se_u = mixed_estimator_analysis(sim; skip=5_000)\n\nusing StatsPlots\n@df df_me plot(_ -> se, :h, ribbon = (se_l, se_u), label = \"⟨S⟩\") # constant line and ribbon for shift estimator\n@df df_me plot!(:h, :val, ribbon = (:val_l, :val_u), label=\"E_mix\") # mixed estimator as a function of reweighting depth\nxlabel!(\"h\")\n\nSee also: mixed_estimator, growth_estimator_analysis.\n\n\n\n\n\n","category":"method"},{"location":"statstools.html#Rimu.StatsTools.projected_energy-Tuple{Any}","page":"StatsTools","title":"Rimu.StatsTools.projected_energy","text":"projected_energy(df::DataFrame; skip=0, hproj=:hproj, vproj=:vproj, kwargs...)\nprojected_energy(sim::PMCSimulation; kwargs...)\n-> r::RatioBlockingResult\n\nCompute the projected energy estimator\n\nE_mathrmp = fracsum_n mathbfvHmathbfc^(n)\n sum_m mathbfvmathbfc^(m) \n\nwhere the time series df.hproj == mathbfvHmathbfc^(n) and df.vproj == mathbfvmathbfc^(m) are taken from df, skipping the first skip entries (use post_step_strategy =ProjectedEnergy(...) to set these up in ProjectorMonteCarloProblem). projected_energy is equivalent to mixed_estimator with h=0.\n\nThe keyword arguments hproj and vproj can be used to change the names of the relevant columns. Other kwargs are passed on to ratio_of_means. Returns a RatioBlockingResult.\n\nSee NamedTuple, val_and_errs, val, errs for processing results.\n\n\n\n\n\n","category":"method"},{"location":"statstools.html#Rimu.StatsTools.rayleigh_replica_estimator-Tuple{Vector, Vector, Vector, Any, Any}","page":"StatsTools","title":"Rimu.StatsTools.rayleigh_replica_estimator","text":"rayleigh_replica_estimator(\n op_ol, vec_ol, shift, h, time_step;\n skip = 0,\n E_r = mean(shift[skip+1:end]),\n weights = w_exp,\n kwargs...\n)\nrayleigh_replica_estimator(\n df::DataFrame;\n shift_name=\"shift\",\n op_name=\"Op1\",\n vec_name=\"dot\",\n h=0,\n skip=0,\n Anorm=1,\n kwargs...\n)\nrayleigh_replica_estimator(sim::PMCSimulation; kwargs...)\n-> r::RatioBlockingResult\n\nCompute the estimator of a Rayleigh quotient of operator hatA with reweighting,\n\nA_mathrmest(h) = fracsum_ab sum_n w_ha^(n) w_hb^(n)\n mathbfc_a^(n) cdot hatA cdot mathbfc_b^(n)\n sum_ab sum_n w_ha^(n) w_hb^(n) mathbfc_a^(n) cdot mathbfc_b^(n)\n\nusing data from multiple replicas.\n\nArgument op_ol holds data for the operator overlap mathbfc_a^(n) hatA mathbfc_b^(n) and vec_ol holds data for the vector overlap mathbfc_a^(n) mathbfc_b^(n). They are of type Vector{Vector}, with each element Vector holding the data for a pair of replicas. Argument shift is of type Vector{Vector}, with each element Vector holding the shift data for each individual replica.\n\nThe second method computes the Rayleigh quotient directly from a DataFrame or PMCSimulation returned by solve. The keyword arguments shift_name, op_name and vec_name can be used to change the names of the relevant columns, see AllOverlaps for default formatting. The operator overlap data can be scaled by a prefactor Anorm. A specific reweighting depth can be set with keyword argument h. The default is h = 0 which calculates the Rayleigh quotient without reweighting.\n\nThe reweighting is an extension of the mixed estimator using the reweighting technique described in Umrigar et al. (1993). Reweighting is done over h time steps and length(shift) - skip time steps are used for the blocking analysis done with ratio_of_means. weights is a function that calulates the weights. See w_exp and w_lin. Additional keyword arguments are passed on to ratio_of_means.\n\nError propagation is done with MonteCarloMeasurements. Results are returned as RatioBlockingResult.\n\nSee also mixed_estimator, growth_estimator.\n\n\n\n\n\n","category":"method"},{"location":"statstools.html#Rimu.StatsTools.rayleigh_replica_estimator_analysis-Tuple{Any}","page":"StatsTools","title":"Rimu.StatsTools.rayleigh_replica_estimator_analysis","text":"rayleigh_replica_estimator_analysis(df::DataFrame; kwargs...)\nrayleigh_replica_estimator_analysis(sim::PMCSimulation; kwargs...)\n-> (; df_rre, df_se)\n\nCompute the rayleigh_replica_estimator on a DataFrame df or PMCSimulation sim returned from solve repeatedly over a range of reweighting depths.\n\nReturns a NamedTuple with the fields\n\ndf_rre: DataFrame with reweighting depth and rayleigh_replica_estimator data. See example below.\ndf_se: DataFrame with shift_estimator output, one row per replica\n\nKeyword arguments\n\nh_range: The default is about h_values values from 0 to twice the estimated correlation time\nh_values = 100: minimum number of reweighting depths\nskip = 0: initial time steps to exclude from averaging\nthreading = Threads.nthreads() > 1: if false a progress meter is displayed\nshift_name = \"shift\": shift data corresponding to column in df with names _1, ...\nop_name = \"Op1\": name of operator overlap corresponding to column in df with names c1__c2, ...\nvec_name = \"dot\": name of vector-vector overlap corresponding to column in df with names c1__c2, ...\nAnorm = 1: a scalar prefactor to scale the operator overlap data\nwarn = true: whether to log warning messages when blocking fails or denominators are small\n\nExample\n\nsim = solve(...)\ndf_rre, df_se = rayleigh_replica_estimator_analysis(sim; skip=5_000)\n\nusing StatsPlots\n@df df_rre plot(_ -> se, :h, ribbon = (se_l, se_u), label = \"⟨S⟩\") # constant line and ribbon for shift estimator\n@df df_rre plot!(:h, :val, ribbon = (:val_l, :val_u), label=\"E_mix\") # Rayleigh quotient estimator as a function of reweighting depth\nxlabel!(\"h\")\n\nSee also: rayleigh_replica_estimator, mixed_estimator_analysis, AllOverlaps.\n\n\n\n\n\n","category":"method"},{"location":"statstools.html#Rimu.StatsTools.shift_estimator-Tuple{Any}","page":"StatsTools","title":"Rimu.StatsTools.shift_estimator","text":"shift_estimator(df::DataFrame; shift=:shift, kwargs...)\nshift_estimator(sim::PMCSimulation; kwargs...)\n-> r::BlockingResult\n\nReturn the shift estimator from the data in df.shift. The keyword argument shift can be used to change the name of the relevant column. Other keyword arguments are passed on to blocking_analysis. Returns a BlockingResult.\n\nSee also growth_estimator, projected_energy.\n\n\n\n\n\n","category":"method"},{"location":"statstools.html#Rimu.StatsTools.w_exp-Tuple{Union{SubArray{<:Any, 1, <:Vector, <:Any, true}, Vector}, Any, Any}","page":"StatsTools","title":"Rimu.StatsTools.w_exp","text":"w_exp(shift, h, time_step; E_r = mean(shift), skip = 0)\n\nCompute the weights for reweighting over h time steps with reference energy E_r from the exponential formula\n\nw_h^(n) = prod_j=1^h exp-dτ(S^(q+n-j)-E_r) \n\nwhere q = skip and dτ is the time_step.\n\nSee also w_lin, growth_estimator, mixed_estimator.\n\n\n\n\n\n","category":"method"},{"location":"statstools.html#Rimu.StatsTools.w_lin-Tuple{Union{SubArray{<:Any, 1, <:Vector, <:Any, true}, Vector}, Any, Any}","page":"StatsTools","title":"Rimu.StatsTools.w_lin","text":"w_lin(shift, h, time_step; E_r = mean(shift), skip = 0)\n\nCompute the weights for reweighting over h time steps with reference energy E_r from the linearised formula\n\nw_h^(n) = prod_j=1^h 1-dτ(S^(q+n-j)-E_r) \n\nwhere q = skip and dτ is the time_step.\n\nSee also w_exp, growth_estimator, mixed_estimator.\n\n\n\n\n\n","category":"method"},{"location":"statstools.html#Rimu.StatsTools.replica_fidelity-Tuple{Any}","page":"StatsTools","title":"Rimu.StatsTools.replica_fidelity","text":"replica_fidelity(df::DataFrame; p_field = :hproj, skip = 0)\nreplica_fidelity(sim::PMCSimulation; kwargs...)\n\nCompute the fidelity of the average coefficient vector and the projector defined in p_field from the PMCSimulation or DataFrame returned by solve, using replicas _1 and _2. Calls ratio_of_means to perform a blocking analysis on a ratio of the means of separate time series and returns a RatioBlockingResult. The first skip steps in the time series are skipped.\n\nThe fidelity of states |ψ⟩ and |ϕ⟩ is defined as\n\nF(ψϕ) = fracψϕ^2ψψϕϕ \n\nSpecifically, replica_fidelity computes\n\nF(mathbfvmathbfc) =\n frac(mathbfc_1mathbfv)(mathbfvmathbfc_1)\n mathbfc_1mathbfc_1 \n\nwhere v is the projector specified by p_field, which is assumed to be normalised to unity with the two-norm (i.e. v⋅v == 1), and mathbfc_1 and mathbfc_2 are two replica coefficient vectors.\n\n\n\n\n\n","category":"method"},{"location":"statstools.html#Rimu.StatsTools.variational_energy_estimator-Tuple{Any, Any}","page":"StatsTools","title":"Rimu.StatsTools.variational_energy_estimator","text":"variational_energy_estimator(shifts, overlaps; kwargs...)\nvariational_energy_estimator(df::DataFrame; max_replicas=:all, kwargs...)\nvariational_energy_estimator(sim::PMCSimulation; kwargs...)\n-> r::RatioBlockingResult\n\nCompute the variational energy estimator from the replica time series of the shifts and coefficient vector overlaps by blocking analysis. The keyword argument max_replicas can be used to constrain the number of replicas processed to be smaller than all available in df. Other keyword arguments are passed on to ratio_of_means(). Returns a RatioBlockingResult.\n\nAn estimator for the variational energy\n\nfracmathbfc^ mathbfHmathbfcmathbfc^mathbfc\n\nis calculated from\n\nE_v = fracsum_ab^R overline(S_a+S_b) mathbfc_a^ mathbfc_b\n 2sum_ab^R overlinemathbfc_a^ mathbfc_b \n\nwhere the sum goes over distinct pairs out of the R replicas. See arXiv:2103.07800.\n\nThe DataFrame and PMCSimulation versions can extract the relevant information from the result of solve. Set up the ProjectorMonteCarloProblem with the keyword argument replica_strategy = AllOverlaps(R) and R ≥ 2. If passing shifts and overlaps, the data has to be arranged in the correct order (as provided in the DataFrame version).\n\nSee AllOverlaps.\n\n\n\n\n\n","category":"method"},{"location":"statstools.html#Additional-docstrings","page":"StatsTools","title":"Additional docstrings","text":"","category":"section"},{"location":"statstools.html","page":"StatsTools","title":"StatsTools","text":"Modules = [StatsTools]\nPages = [\"StatsTools.jl\", \"blocking.jl\", \"ratio_of_means.jl\", \"convenience.jl\",\n \"variances.jl\", \"growth_witness.jl\", \"reweighting.jl\"\n]\nPublic = false","category":"page"},{"location":"statstools.html#MonteCarloMeasurements.Particles-Tuple{Rimu.StatsTools.BlockingResult{<:Real}}","page":"StatsTools","title":"MonteCarloMeasurements.Particles","text":"MonteCarloMeasurements.Particles(r::BlockingResult; mc_samples = 2000)\nMonteCarloMeasurements.±(r::BlockingResult)\n\nConvert a BlockingResult into a Particles object for nonlinear error propagation with MonteCarloMeasurements.\n\n\n\n\n\n","category":"method"},{"location":"statstools.html#Rimu.StatsTools.BlockingResult","page":"StatsTools","title":"Rimu.StatsTools.BlockingResult","text":"BlockingResult(mean, err, err_err, p_cov, k, blocks)\n\nResult of blocking_analysis.\n\nFields:\n\nmean: sample mean\nerr: standard error (estimated standard deviation of the mean)\nerr_err: estimated uncertainty of err\np_cov: estimated pseudo covariance of mean, relevant for complex time series\nk::Int: k-1 blocking steps were used to uncorrelate time series\nblocks::Int: number of uncorrelated values after blocking\n\nHas methods for NamedTuple, val_and_errs, val, errs, mean_and_se, Measurements.:±, MonteCarloMeasurements.Particles, and Statistics.cov for Complex data.\n\nExample:\n\njulia> blocking_analysis(smoothen(randn(2^10), 2^5))\nBlockingResult{Float64}\n mean = -0.026 ± 0.029\n with uncertainty of ± 0.003638545517264226\n from 32 blocks after 5 transformations (k = 6).\n\n\n\n\n\n","category":"type"},{"location":"statstools.html#Measurements.measurement-Tuple{Rimu.StatsTools.BlockingResult{<:Real}}","page":"StatsTools","title":"Measurements.measurement","text":"measurement(r::BlockingResult)\nMeasurements.±(r::BlockingResult)\n\nConvert a BlockingResult into a Measurement for linear error propagation with Measurements.\n\nLimitation: Does not account for covariance in complex BlockingResult. Consider using MonteCarloMeasurements.Particles(r)!\n\n\n\n\n\n","category":"method"},{"location":"statstools.html#Rimu.StatsTools.blocker-Union{Tuple{AbstractVector{T}}, Tuple{T}} where T","page":"StatsTools","title":"Rimu.StatsTools.blocker","text":"blocker(v::Vector) -> new_v::Vector\n\nReblock the data by successively taking the mean of two adjacent data points to form a new vector with a half of the length(v). The last data point will be discarded if length(v) is odd.\n\n\n\n\n\n","category":"method"},{"location":"statstools.html#Rimu.StatsTools.blocks_with_m-Tuple{Any}","page":"StatsTools","title":"Rimu.StatsTools.blocks_with_m","text":"blocks_with_m(v; corrected = true) -> (;blocks, mean, std_err, std_err_err, p_cov, mj)\n\nPerform the blocking algorithm from Flyvberg and Peterson JCP (1989). Returns named tuple with the results from all blocking steps. See mtest().\n\n\n\n\n\n","category":"method"},{"location":"statstools.html#Rimu.StatsTools.mtest-Tuple{AbstractVector}","page":"StatsTools","title":"Rimu.StatsTools.mtest","text":"mtest(mj::AbstractVector; α = 0.01) -> k\nmtest(table::NamedTuple; α = 0.01) -> k\n\nHypothesis test for decorrelation of a time series after blocking transformations with significance level 1-α after Jonson PRE (2018). mj or table.mj is expected to be a vector with relevant M_j values from a blocking analysis as obtained from blocks_with_m(). Returns the row number k where the M-test is passed. If the M-test has failed mtest() returns the value -1.\n\n\n\n\n\n","category":"method"},{"location":"statstools.html#Rimu.StatsTools.RatioBlockingResult","page":"StatsTools","title":"Rimu.StatsTools.RatioBlockingResult","text":"RatioBlockingResult(ratio, f, σ_f, δ_y, k, success)\n\nResult of ratio_of_means().\n\nFields:\n\nratio::P: ratio with uncertainties propagated by MonteCarloMeasurements\nf::T: ratio of means\nσ_f::T: std from linear propagation\nδ_y::T: coefficient of variation for denominator (≤ 0.1 for normal approx)\nk::Int: k-1 blocking steps were used to uncorrelate time series\nblocks::Int: number of data values after blocking\nsuccess::Bool: false if any of the blocking steps failed\n\nHas methods for NamedTuple, val_and_errs, val, errs.\n\nNote: to compute statistics on the RatioBlockingResult, use functions pmedian, pquantile, pmiddle, piterate, pextrema, pminimum, pmaximum, pmean, and pcov.\n\n\n\n\n\n","category":"type"},{"location":"statstools.html#Rimu.StatsTools.particles-Tuple{Any, Any, Any}","page":"StatsTools","title":"Rimu.StatsTools.particles","text":"particles(samples, μ, σ)\nparticles(samples, μ::AbstractVector, Σ::AbstractMatrix)\n\nReturn Particles object from MonteCarloMeasurements with single- or multivariate normal distribution. Zero variance parameters are supported.\n\n\n\n\n\n","category":"method"},{"location":"statstools.html#Rimu.StatsTools.particles-Tuple{Any, Distributions.Distribution}","page":"StatsTools","title":"Rimu.StatsTools.particles","text":"particles(samples, d)\nparticles(::Nothing, d)\nparticles(::Val{T}, d) where T\n\nReturn Particles object from MonteCarloMeasurements using a type-stable constructor if possible. Pass nothing for the default number of particles or Val(1_000) for using 1000 particles in a type-stable manner. If d is a Particles object it is passed through without re-sampling.\n\n\n\n\n\n","category":"method"},{"location":"statstools.html#Rimu.StatsTools.ratio_estimators-Tuple{AbstractVector{<:Real}, AbstractVector{<:Real}}","page":"StatsTools","title":"Rimu.StatsTools.ratio_estimators","text":"ratio_estimators(x, y, [k]; corrected=true, mc_samples=10_000) -> (; r, f, σ_f, δ_y, n)\n\nEstimators for the ratio of means mean(x)/mean(y). If k is given, k-1 blocking steps are performed to remove internal correlations in the time series x and y. Otherwise these are assumed to be free of internal correlations. Correlations between x and y may be present and are taken into account.\n\nReturn values:\n\nr::Particles is the Monte Carlo sampled ratio estimator, see Particles\nf = mean(x)/mean(y)\nσ_f standard deviation of f from linear error propagation (normal approximation)\nδ_y = std(y)/mean(y) coefficient of variation; < 0.1 for normal approximation to work\nn: number of uncorrelated data used for uncertainty estimation\n\n\n\n\n\n","category":"method"},{"location":"statstools.html#Rimu.StatsTools.x_by_y_linear-NTuple{5, Any}","page":"StatsTools","title":"Rimu.StatsTools.x_by_y_linear","text":"x_by_y_linear(μ_x,μ_y,σ_x,σ_y,ρ) -> f, σ_f\n\nLinear error propagation for ratio f = x/y assuming x and y are correlated normal random variables and assuming the ratio can be approximated as a normal distribution. See wikipedia and Díaz-Francés, Rubio (2013).\n\nσ_f = sqrtfracσ_xμ_y^2 + fracμ_x σ_yμ_y^2^2 - frac2 ρ μ_xμ_y^3\n\n\n\n\n\n","category":"method"},{"location":"statstools.html#Core.NamedTuple-Tuple{Rimu.StatsTools.BlockingResult}","page":"StatsTools","title":"Core.NamedTuple","text":"NamedTuple(x::BlockingResult; n=1, p=nothing, name=:val)\nNamedTuple(x::RatioBlockingResult; n=1, p=nothing, name=:val)\n\nReturn a named tuple with value and error bars (see val_and_errs) as well as additional numerical fields relevant for x.\n\nExample:\n\njulia> results = [blocking_analysis(i:0.1:2i+20) for i in 1:3]; # mock results\n\njulia> df = NamedTuple.(results, name=:res)|>DataFrame\n3×7 DataFrame\n Row │ res res_l res_u res_err_err res_p_cov res_k res_blocks\n │ Float64 Float64 Float64 Float64 Float64 Int64 Int64\n─────┼──────────────────────────────────────────────────────────────────────\n 1 │ 11.5 1.7282 1.7282 0.352767 2.98667 5 13\n 2 │ 13.0 1.7282 1.7282 0.352767 2.98667 5 13\n 3 │ 14.5 1.78885 1.78885 0.350823 3.2 5 14\n\njulia> rbs = ratio_of_means(1 .+sin.(1:0.1:11),2 .+sin.(2:0.1:12)); # more mock results\n\njulia> [NamedTuple(rbs),]|>DataFrame\n1×9 DataFrame\n Row │ val val_l val_u val_f val_σ_f val_δ_y val_k val_blocks val_success\n │ Float64 Float64 Float64 Float64 Float64 Float64 Int64 Int64 Bool\n─────┼────────────────────────────────────────────────────────────────────────────────────────────────\n 1 │ 0.581549 0.0925669 0.0812292 0.560532 0.0875548 0.0875548 4 12 true\n\n\nSee val_and_errs, val, errs, BlockingResult, RatioBlockingResult.\n\n\n\n\n\n","category":"method"},{"location":"statstools.html#Rimu.StatsTools.autocovariance-Tuple{AbstractVector, Int64}","page":"StatsTools","title":"Rimu.StatsTools.autocovariance","text":"autocovariance(v::Vector,h::Int; corrected::Bool=true)\n\nhatgamma(h) =frac1nsum_t=1^n-h(v_t+h-barv)(v_t-barv)^* Calculate the autocovariance of dataset v with a delay h. If corrected is true (the default) then the sum is scaled with n-h, whereas the sum is scaled with n if corrected is false where n = length(v).\n\n\n\n\n\n","category":"method"},{"location":"statstools.html#Rimu.StatsTools.pseudo_cov-Tuple{Any, Any}","page":"StatsTools","title":"Rimu.StatsTools.pseudo_cov","text":"pseudo_cov(x, y; xmean = mean(x), ymean = mean(y), corrected = true)\n\nCompute the pseudo covariance between collections x and y returning a scalar:\n\nfrac1nsum_i=1^n (x_i - barx)(y_i - bary)\n\nOptionally, precomputed means can be passed as keyword arguments. pseudo_cov(x,y) is functionally equivalent to Statistics.cov(x, conj(y); corrected = false) but it is found to be significantly faster and avoids allocations.\n\n\n\n\n\n","category":"method"},{"location":"statstools.html#Rimu.StatsTools.determine_constant_time_step-Tuple{Any}","page":"StatsTools","title":"Rimu.StatsTools.determine_constant_time_step","text":"determine_constant_time_step(df) -> time_step\n\nGiven a DataFrame df, determine the time step that was used to compute it. Throw an error if time step is not constant.\n\n\n\n\n\n","category":"method"},{"location":"statstools.html#Index","page":"StatsTools","title":"Index","text":"","category":"section"},{"location":"statstools.html","page":"StatsTools","title":"StatsTools","text":"Pages = [\"statstools.md\"]","category":"page"},{"location":"interfaces.html#Module-Interfaces","page":"Interfaces","title":"Module Interfaces","text":"","category":"section"},{"location":"interfaces.html","page":"Interfaces","title":"Interfaces","text":"Interfaces","category":"page"},{"location":"interfaces.html#Rimu.Interfaces","page":"Interfaces","title":"Rimu.Interfaces","text":"module Interfaces\n\nThis module contains interfaces that can be used to extend and modify the algorithms and behaviours of Rimu.\n\nInterfaces\n\nFollow the links for the definitions of the interfaces!\n\nAbstractHamiltonian for defining Hamiltonians\nAbstractOperator for defining observable operators\nAbstractDVec for defining data structures for Rimu as in DictVectors\nStochasticStyle for controlling the stochastic algorithms used by ProjectorMonteCarloProblem as implemented in StochasticStyles\n\nAdditional exports\n\nInterface functions forAbstractHamiltonians:\n\ndiagonal_element\nnum_offdiagonals\nget_offdiagonal\noffdiagonals.\nrandom_offdiagonal\nstarting_address\nLOStructure\nallows_address_type\n\nworking with AbstractDVecs and StochasticStyle\n\ndeposit!\ndefault_style\nCompressionStrategy\nThe interface from VectorInterface.jl.\n\nFunctions Rimu.jl uses to do FCIQMC:\n\napply_column!\napply_operator!\nstep_stats\n\n\n\n\n\n","category":"module"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"EditURL = \"../../../scripts/HO-example.jl\"","category":"page"},{"location":"generated/HO-example.html#Example-5:-Degenerate-perturbation-theory-in-a-harmonic-oscillator-basis","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Example 5: Degenerate perturbation theory in a harmonic oscillator basis","text":"","category":"section"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"Rimu can also handle non-lattice systems. This example looks at weakly-interacting bosonic particles in a harmonic oscillator external potential using a basis of (Cartesian product) single-particle eigenstates of the harmonic oscillator potential. Blocks of degenerate non-interacting states are coupled by a contact interaction in first order degenerate perturbation theory. This example shows how to generate these blocks and find the energy and angular momentum eigenstates.","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"A runnable script for this example is located here. Run it with julia HO-example.jl.","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"First, load all needed packages.","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"using Rimu\nusing DataFrames\nusing LinearAlgebra","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"Define the system size for N=2 particles in a 2D harmonic oscillator allowing M=4 levels in each dimension, including the groundstate.","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"N = 2\nM = 4;","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"Use a tuple S to define the range of harmonic oscillator states in a Cartesian basis, in this isotropic case n_xn_y=01ldotsM-1.","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"S = (M, M);","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"In Rimu the N-particle states are still stored as Fock states.","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"P = prod(S)\naddr = BoseFS(P, M => N)","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"BoseFS{2,16}(0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"Here, the numbering of the modes folds in the two spatial dimensions. Use the utility function fock_to_cart to convert a Fock address to human-readable Cartesian quantum numbers for inspection.","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"fock_to_cart(addr, S)","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"2-element StaticArraysCore.SVector{2, Tuple{Int64, Int64}} with indices SOneTo(2):\n (3, 0)\n (3, 0)","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"The output shows that all N particles are in single-particle state n_x=M-1 n_y=0.","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"The harmonic oscillator Hamiltonian HOCartesianContactInteractions handles contact interactions with first-order perturbation theory, so the matrix representation will block according to the non-interacting energy of the basis states. The first task is to find all blocks of basis states with the same energy. The strength of the interaction is not relevant at this point, just that it is non-zero. Use an arbitrary N-particle starting address to build the Hamiltonian.","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"H = HOCartesianContactInteractions(BoseFS(P, 1 => N); S);","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"Then, use the utility function get_all_blocks to find all blocks. The blocks are found by looping over all possible states with N particles in Cartesian states defined by S. Note that this will only work for total energy up to the maximum accessible by a single particle. The N-particle groundstate energy for a 2D harmonic oscillator is E_0 = N hbar omega and the maximum single-particle energy is E = (E_0 + M - 1) hbar omega.","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"block_df = get_all_blocks(H; max_energy = N + M - 1)","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"
7×6 DataFrame
Rowblock_idblock_E0block_sizeaddrindicest_basis
Int64Float64Int64BoseFS…Tuple…Float64
112.01fs"|2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0⟩"(1, 1)1.13502
223.01fs"|1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0⟩"(2, 1)3.4244e-5
334.04fs"|0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0⟩"(2, 2)3.0928e-5
445.05fs"|0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0⟩"(3, 2)1.5028e-5
553.01fs"|1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0⟩"(5, 1)3.657e-6
664.02fs"|0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0⟩"(5, 2)6.612e-6
775.05fs"|0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0⟩"(5, 3)1.3896e-5
","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"This outputs a list of blocks in H indexed by the noninteracting energy of all states in the block, and a single address that can be used to rebuild the block for further analysis.","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"addr1 = block_df[7,:addr]\nE = block_df[7,:block_E0]","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"5.0","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"First, notice that all basis states have the same energy, defined by the block.","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"basis1 = build_basis(H, addr1)\nmap(b -> Hamiltonians.noninteracting_energy(H, b), basis1)","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"5-element Vector{Float64}:\n 5.0\n 5.0\n 5.0\n 5.0\n 5.0","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"There are two blocks at each energy level (except the groundstate), which are different due to parity conservation, which is the only other symmetry in the Cartesian harmonic oscillator. The basis of this other block is different,","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"addr2 = block_df[4,:addr]\nbasis2 = build_basis(H, addr2);\nbasis1 ≠ basis2","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"true","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"but its basis elements have the same energy.","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"map(b -> Hamiltonians.noninteracting_energy(H, b), basis2)","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"5-element Vector{Float64}:\n 5.0\n 5.0\n 5.0\n 5.0\n 5.0","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"However, since this system is an isotropic harmonic oscillator, it is possible to build simultaneous eigenstates of the angular momentum operator L_z, implemented with AxialAngularMomentumHO.","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"Lz = AxialAngularMomentumHO(S)","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"AxialAngularMomentumHO((4, 4); z_dim = 3, addr = BoseFS{0,16}(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"L_z does not conserve parity, so both blocks are required. First combine the bases of each block and convert to DVecs.","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"dvs = map(b -> DVec(b => 1.0), vcat(basis1, basis2));","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"and then compute overlaps for the matrix elements of L_z.","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"Lz_mat = [dot(v, Lz, w) for v in dvs, w in dvs]","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"10×10 Matrix{ComplexF64}:\n 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+1.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0-1.41421im\n 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+1.0im 0.0+0.0im 0.0+0.0im 0.0+1.41421im\n 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0-2.0im 0.0+1.73205im 0.0+0.0im\n 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+1.41421im 0.0-1.41421im 0.0+0.0im 0.0+0.0im 0.0-1.0im\n 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+1.73205im 0.0+0.0im 0.0+0.0im\n 0.0-1.0im 0.0+0.0im 0.0+0.0im 0.0-1.41421im 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im\n 0.0+0.0im 0.0-1.0im 0.0+0.0im 0.0+1.41421im 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im\n 0.0+0.0im 0.0+0.0im 0.0+2.0im 0.0+0.0im 0.0-1.73205im 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im\n 0.0+0.0im 0.0+0.0im 0.0-1.73205im 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im\n 0.0+1.41421im 0.0-1.41421im 0.0+0.0im 0.0+1.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"By diagonalising this matrix the eigenstate have energy E and well-defined angular momentum.","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"Diagonalise this matrix to obtain the eigenstates of L_z. The eigenvectors provide the linear combinations of basis states with well-defined angular momentum, within the subspace of energy E.","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"Lz_vals, Lz_vecs = eigen(Lz_mat)","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"Eigen{ComplexF64, Float64, Matrix{ComplexF64}, Vector{Float64}}\nvalues:\n10-element Vector{Float64}:\n -2.9999999999999956\n -2.999999999999992\n -0.9999999999999991\n -0.9999999999999991\n -0.9999999999999989\n 1.0000000000000002\n 1.0000000000000027\n 1.0000000000000036\n 3.0\n 3.0000000000000004\nvectors:\n10×10 Matrix{ComplexF64}:\n -5.21142e-19-1.11022e-16im 0.0+0.353553im 8.5601e-18-0.0618116im 0.0+0.353553im 0.0394729+0.494592im -0.000677524+0.16408im 0.0-0.353553im -3.16732e-17-0.472311im 0.0+0.353553im -5.48449e-18-5.55112e-17im\n -5.21142e-19-5.55112e-17im 0.0-0.353553im 8.5601e-18-0.0618116im 0.0-0.353553im 0.0394729+0.494592im -0.000677524+0.16408im 0.0+0.353553im -3.16732e-17-0.472311im 0.0-0.353553im -5.48449e-18-5.55112e-17im\n -7.63858e-18-0.612372im 0.0+0.0im 1.29697e-17-0.350841im 0.0+0.0im -0.00347719-0.0435689im -0.00137905+0.333971im 0.0+0.0im -4.17496e-17+0.116023im 0.0+0.0im 5.13001e-18-0.612372im\n 4.62223e-33-2.77556e-17im 0.0+0.5im 3.08149e-33+5.55112e-17im 0.0-0.5im 8.67362e-18+3.46945e-17im 0.0+0.0im 0.0+0.5im -6.16298e-33+1.38778e-17im 0.0+0.5im -1.54074e-33-2.77556e-17im\n 0.0+0.353553im 0.0+0.0im 0.0-0.607675im 0.0+0.0im -0.00602267-0.0754635im -0.00238858+0.578455im 0.0+0.0im -8.32667e-17+0.200958im 0.0+0.0im 0.0+0.353553im\n -3.33067e-16+1.80109e-17im -0.353553+0.0im 0.0618116-6.81613e-18im 0.353553+0.0im -0.494592+0.0394729im 0.16408+0.000677524im 0.353553+0.0im -0.472311-1.92131e-17im 0.353553+0.0im 5.55112e-17+6.86785e-18im\n -2.77556e-16+1.80109e-17im 0.353553+0.0im 0.0618116-6.81613e-18im -0.353553+0.0im -0.494592+0.0394729im 0.16408+0.000677524im -0.353553+0.0im -0.472311-1.92131e-17im -0.353553+0.0im -1.66533e-16+6.86785e-18im\n -0.612372+1.31535e-17im 0.0+0.0im 0.350841-1.23225e-17im 0.0+0.0im 0.0435689-0.00347719im 0.333971+0.00137905im 0.0+0.0im 0.116023+4.42387e-17im 0.0+0.0im 0.612372-5.88226e-18im\n 0.353553-2.94055e-17im 0.0+0.0im 0.607675-3.22708e-17im 5.55112e-17+0.0im 0.0754635-0.00602267im 0.578455+0.00238858im -1.38778e-16+0.0im 0.200958+5.6114e-17im 0.0+0.0im -0.353553+1.82545e-17im\n 0.0+0.0im 0.5+0.0im 0.0+0.0im 0.5+0.0im 0.0+0.0im 0.0+0.0im 0.5+0.0im 0.0+0.0im -0.5-0.0im 0.0+0.0im","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"Finally, consider the effect of interactions by looking at how states in a single block are perturbed. Only the energy shift due to the interaction is relevant so now rebuild the Hamiltonian without the non-interacting energy.","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"Hint = HOCartesianContactInteractions(addr1; S, interaction_only = true)\nΔE = eigvals(Matrix(Hint, addr1))","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"5-element Vector{Float64}:\n -2.081668171172327e-17\n 1.0625181290352691e-17\n 0.15915494309189532\n 0.15915494309189535\n 0.15915494309189543","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"Two eigenstates in this block are unaffected by the interaction and three have a non-zero energy shift.","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"The default strength of the interaction is g = 1.0. Other interactions strengths can be obtained by using keyword argument g in HOCartesianContactInteractions or by rescaling ΔE since the interactions are handled with first-order perturbation theory.","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"Rimu also contains HOCartesianEnergyConservedPerDim which is a similar Hamiltonian but with the stricter condition that the contact interaction only connects states that have the same total energy in each dimension, rather than conserving the overall total energy. Both Hamiltonians can handle anisotropic systems by passing a tuple S whose elements are not all the same. This will alter which states are connected by the interaction, but assumes that the harmonic trapping frequencies in each dimension are commensurate.","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"","category":"page"},{"location":"generated/HO-example.html","page":"Degenerate perturbation theory in a harmonic oscillator basis","title":"Degenerate perturbation theory in a harmonic oscillator basis","text":"This page was generated using Literate.jl.","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"EditURL = \"../../../scripts/exact-example.jl\"","category":"page"},{"location":"generated/exact-example.html#Example-4:-Exact-diagonalization","page":"Exact diagonalization","title":"Example 4: Exact diagonalization","text":"","category":"section"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"When working with smaller systems or when multiple eigenvalues of a system are required, one can use an exact diagonalization method. There are a few ways to go about this, each with its pros and cons. The purpose of this tutorial is to show off the methods as well as provide a few tips regarding them.","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"A runnable script for this example is located here. Run it with julia exact-example.jl.","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"We start by loading Rimu.","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"using Rimu","category":"page"},{"location":"generated/exact-example.html#Introduction","page":"Exact diagonalization","title":"Introduction","text":"","category":"section"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"We will look at a bosonic system of 4 particles in 5 sites, formulated in momentum space. Let's start by building the Hamiltonian. To create a Fock state where all particles have zero momentum, we put all the particles in the mode at the centre of the address.","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"M = 5\nN = 4\nadd = BoseFS(M, cld(M, 2) => N)\nham = HubbardMom1D(add)","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"HubbardMom1D(fs\"|0 0 4 0 0⟩\"; u=1.0, t=1.0)","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"Before performing exact diagonalization, it is a good idea to check the dimension of the Hamiltonian.","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"dimension(ham)","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"70","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"Keep in mind that this is an estimate of the number of Fock states the Hamiltonian can act on, not the actual matrix size - the matrix size can sometimes be smaller. It can still be used as a guide to decide whether a Hamiltonian is amenable to exact diagonalization and to determine which algorithm would be best suited to diagonalising it.","category":"page"},{"location":"generated/exact-example.html#The-BasisSetRepresentation","page":"Exact diagonalization","title":"The BasisSetRepresentation","text":"","category":"section"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"As we'll see later, there are two ways to construct the matrices from Hamiltonians directly, but they both use BasisSetRepresentation under the hood. The BasisSetRepresentation, when called with a Hamiltonian and optionally a starting address, constructs the sparse matrix of the system, as well as its basis. The starting address defaults to the one that was used to initialize the Hamiltonian. BasisSetRepresentation only returns the part of the matrix that is accessible from this starting address through non-zero offdiagonal elements.","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"bsr = BasisSetRepresentation(ham);","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"To access the matrix or basis, access the sparse_matrix and basis fields, respectively.","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"bsr.sparse_matrix","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"14×14 SparseArrays.SparseMatrixCSC{Float64, Int32} with 104 stored entries:\n -6.8 0.69282 0.69282 ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ \n 0.69282 -3.03607 0.4 0.4 0.8 ⋅ 0.4 0.282843 0.565685 0.8 ⋅ ⋅ ⋅ ⋅ \n 0.69282 0.4 1.43607 0.8 0.4 0.565685 0.8 0.282843 ⋅ 0.4 ⋅ ⋅ ⋅ ⋅ \n ⋅ 0.4 0.8 2.81803 0.4 0.282843 ⋅ 0.565685 ⋅ 0.4 0.69282 0.69282 ⋅ ⋅ \n ⋅ 0.8 0.4 0.4 0.581966 ⋅ 0.4 0.565685 0.282843 ⋅ ⋅ 0.69282 0.69282 ⋅ \n ⋅ ⋅ 0.565685 0.282843 ⋅ 8.47214 0.282843 0.8 ⋅ ⋅ ⋅ 0.489898 ⋅ 0.489898\n ⋅ 0.4 0.8 ⋅ 0.4 0.282843 2.81803 0.565685 ⋅ 0.4 ⋅ ⋅ 0.69282 0.69282\n ⋅ 0.282843 0.282843 0.565685 0.565685 0.8 0.565685 4.4 0.8 0.565685 0.489898 0.489898 0.489898 0.489898\n ⋅ 0.565685 ⋅ ⋅ 0.282843 ⋅ ⋅ 0.8 -0.472136 0.282843 0.489898 ⋅ 0.489898 ⋅ \n ⋅ 0.8 0.4 0.4 ⋅ ⋅ 0.4 0.565685 0.282843 0.581966 0.69282 ⋅ ⋅ 0.69282\n ⋅ ⋅ ⋅ 0.69282 ⋅ ⋅ ⋅ 0.489898 0.489898 0.69282 1.56393 ⋅ ⋅ ⋅ \n ⋅ ⋅ ⋅ 0.69282 0.69282 0.489898 ⋅ 0.489898 ⋅ ⋅ ⋅ 6.03607 ⋅ ⋅ \n ⋅ ⋅ ⋅ ⋅ 0.69282 ⋅ 0.69282 0.489898 0.489898 ⋅ ⋅ ⋅ 1.56393 ⋅ \n ⋅ ⋅ ⋅ ⋅ ⋅ 0.489898 0.69282 0.489898 ⋅ 0.69282 ⋅ ⋅ ⋅ 6.03607","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"bsr.basis","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"14-element Vector{BoseFS{4, 5, BitString{8, 1, UInt8}}}:\n fs\"|0 0 4 0 0⟩\"\n fs\"|0 1 2 1 0⟩\"\n fs\"|1 0 2 0 1⟩\"\n fs\"|2 1 1 0 0⟩\"\n fs\"|1 0 1 2 0⟩\"\n fs\"|2 0 0 0 2⟩\"\n fs\"|0 0 1 1 2⟩\"\n fs\"|1 1 0 1 1⟩\"\n fs\"|0 2 0 2 0⟩\"\n fs\"|0 2 1 0 1⟩\"\n fs\"|1 3 0 0 0⟩\"\n fs\"|3 0 0 1 0⟩\"\n fs\"|0 0 0 3 1⟩\"\n fs\"|0 1 0 0 3⟩\"","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"When the basis is not needed, we can use Matrix or sparse directly.","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"Matrix(ham)","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"14×14 Matrix{Float64}:\n -6.8 0.69282 0.69282 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0\n 0.69282 -3.03607 0.4 0.4 0.8 0.0 0.4 0.282843 0.565685 0.8 0.0 0.0 0.0 0.0\n 0.69282 0.4 1.43607 0.8 0.4 0.565685 0.8 0.282843 0.0 0.4 0.0 0.0 0.0 0.0\n 0.0 0.4 0.8 2.81803 0.4 0.282843 0.0 0.565685 0.0 0.4 0.69282 0.69282 0.0 0.0\n 0.0 0.8 0.4 0.4 0.581966 0.0 0.4 0.565685 0.282843 0.0 0.0 0.69282 0.69282 0.0\n 0.0 0.0 0.565685 0.282843 0.0 8.47214 0.282843 0.8 0.0 0.0 0.0 0.489898 0.0 0.489898\n 0.0 0.4 0.8 0.0 0.4 0.282843 2.81803 0.565685 0.0 0.4 0.0 0.0 0.69282 0.69282\n 0.0 0.282843 0.282843 0.565685 0.565685 0.8 0.565685 4.4 0.8 0.565685 0.489898 0.489898 0.489898 0.489898\n 0.0 0.565685 0.0 0.0 0.282843 0.0 0.0 0.8 -0.472136 0.282843 0.489898 0.0 0.489898 0.0\n 0.0 0.8 0.4 0.4 0.0 0.0 0.4 0.565685 0.282843 0.581966 0.69282 0.0 0.0 0.69282\n 0.0 0.0 0.0 0.69282 0.0 0.0 0.0 0.489898 0.489898 0.69282 1.56393 0.0 0.0 0.0\n 0.0 0.0 0.0 0.69282 0.69282 0.489898 0.0 0.489898 0.0 0.0 0.0 6.03607 0.0 0.0\n 0.0 0.0 0.0 0.0 0.69282 0.0 0.69282 0.489898 0.489898 0.0 0.0 0.0 1.56393 0.0\n 0.0 0.0 0.0 0.0 0.0 0.489898 0.69282 0.489898 0.0 0.69282 0.0 0.0 0.0 6.03607","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"sparse(ham)","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"14×14 SparseArrays.SparseMatrixCSC{Float64, Int32} with 104 stored entries:\n -6.8 0.69282 0.69282 ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ \n 0.69282 -3.03607 0.4 0.4 0.8 ⋅ 0.4 0.282843 0.565685 0.8 ⋅ ⋅ ⋅ ⋅ \n 0.69282 0.4 1.43607 0.8 0.4 0.565685 0.8 0.282843 ⋅ 0.4 ⋅ ⋅ ⋅ ⋅ \n ⋅ 0.4 0.8 2.81803 0.4 0.282843 ⋅ 0.565685 ⋅ 0.4 0.69282 0.69282 ⋅ ⋅ \n ⋅ 0.8 0.4 0.4 0.581966 ⋅ 0.4 0.565685 0.282843 ⋅ ⋅ 0.69282 0.69282 ⋅ \n ⋅ ⋅ 0.565685 0.282843 ⋅ 8.47214 0.282843 0.8 ⋅ ⋅ ⋅ 0.489898 ⋅ 0.489898\n ⋅ 0.4 0.8 ⋅ 0.4 0.282843 2.81803 0.565685 ⋅ 0.4 ⋅ ⋅ 0.69282 0.69282\n ⋅ 0.282843 0.282843 0.565685 0.565685 0.8 0.565685 4.4 0.8 0.565685 0.489898 0.489898 0.489898 0.489898\n ⋅ 0.565685 ⋅ ⋅ 0.282843 ⋅ ⋅ 0.8 -0.472136 0.282843 0.489898 ⋅ 0.489898 ⋅ \n ⋅ 0.8 0.4 0.4 ⋅ ⋅ 0.4 0.565685 0.282843 0.581966 0.69282 ⋅ ⋅ 0.69282\n ⋅ ⋅ ⋅ 0.69282 ⋅ ⋅ ⋅ 0.489898 0.489898 0.69282 1.56393 ⋅ ⋅ ⋅ \n ⋅ ⋅ ⋅ 0.69282 0.69282 0.489898 ⋅ 0.489898 ⋅ ⋅ ⋅ 6.03607 ⋅ ⋅ \n ⋅ ⋅ ⋅ ⋅ 0.69282 ⋅ 0.69282 0.489898 0.489898 ⋅ ⋅ ⋅ 1.56393 ⋅ \n ⋅ ⋅ ⋅ ⋅ ⋅ 0.489898 0.69282 0.489898 ⋅ 0.69282 ⋅ ⋅ ⋅ 6.03607","category":"page"},{"location":"generated/exact-example.html#Computing-eigenvalues","page":"Exact diagonalization","title":"Computing eigenvalues","text":"","category":"section"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"Now that we have a way of constructing matrices from Hamiltonians, we can use standard Julia functionality to diagonalise them.","category":"page"},{"location":"generated/exact-example.html#The-built-in-method","page":"Exact diagonalization","title":"The built-in method","text":"","category":"section"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"Let's begin by looking at the eigen, eigvecs, and eigvals functions from the LinearAlgebra standard library. They operate on dense matrices and return the full spectra, hence they are only useful for small systems, or when all eigenvalues are required.","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"using LinearAlgebra\n\nmat = Matrix(ham)\neig = eigen(mat);","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"The values can be accessed like so:","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"eig.values","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"14-element Vector{Float64}:\n -6.979863998321608\n -3.3631242916133672\n -0.759019192277071\n 0.1358418221962303\n 0.1578999869460933\n 0.8767114411781449\n 1.5305929970973349\n 1.5835732611867455\n 3.072870330325866\n 3.1256726539518453\n 4.862107221562177\n 6.2606948503805935\n 6.402671211183116\n 9.093371706203953","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"The vectors are stored as columns in eig.vectors:","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"eig.vectors","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"14×14 Matrix{Float64}:\n -0.980348 -0.175378 -0.0135766 -3.15026e-15 0.0221221 0.0697193 9.29812e-16 -0.0314466 -1.42247e-16 -0.0360987 -0.0161557 -9.02056e-17 0.00625248 -0.0058099\n 0.177701 -0.932229 -0.105473 3.33067e-14 -0.225254 0.132826 9.4369e-16 0.00292026 -1.49013e-15 -0.0861158 -0.0907789 -1.16573e-15 0.0591715 -0.0264275\n 0.0768085 0.0622307 -0.0129069 -6.11039e-14 0.447424 0.63969 1.24831e-14 -0.383444 -3.80078e-15 -0.431051 -0.181167 -1.16573e-15 0.0599783 -0.106852\n -0.0119687 0.0373038 -0.0678797 0.0693699 -0.0495446 -0.416847 0.33773 -0.0584554 -0.601232 -0.467179 -0.215841 -0.140166 0.190543 -0.114342\n -0.0214153 0.175119 0.20169 -0.616673 -0.522017 0.296818 0.31234 0.122119 0.123629 -0.106455 -0.126661 -0.0829132 0.148347 -0.0574235\n -0.00237613 -0.00294196 -0.00143189 6.05072e-15 -0.0427486 -0.0110863 -1.72085e-15 0.0663108 -5.55112e-17 0.00167015 0.0832916 4.36456e-15 -0.448519 -0.8863\n -0.0119687 0.0373038 -0.0678797 -0.0693699 -0.0495446 -0.416847 -0.33773 -0.0584554 0.601232 -0.467179 -0.215841 0.140166 0.190543 -0.114342\n -0.00234782 -0.00840544 0.098969 -1.28231e-14 0.0847116 -0.082999 6.70297e-15 -0.274424 3.2474e-15 0.575786 -0.61385 -5.37764e-15 0.353775 -0.259338\n -0.0138439 0.165902 -0.922758 1.50713e-14 -0.1111 0.172508 -4.02109e-15 0.207974 -4.85723e-17 0.0848902 -0.149153 -8.60423e-16 0.0712921 -0.0301968\n -0.0214153 0.175119 0.20169 0.616673 -0.522017 0.296818 -0.31234 0.122119 -0.123629 -0.106455 -0.126661 0.0829132 0.148347 -0.0574235\n 0.00363555 -0.0455298 0.133824 -0.332825 0.290831 0.057199 -0.527627 0.588225 -0.332816 -0.0472302 -0.18528 -0.00844536 0.0915588 -0.0346434\n 0.00195478 -0.0150664 -0.0206752 0.0642658 0.0638689 0.0250518 -0.0999631 0.012992 0.111668 0.0393523 0.423534 -0.688046 0.513839 -0.222499\n 0.00363555 -0.0455298 0.133824 0.332825 0.290831 0.057199 0.527627 0.588225 0.332816 -0.0472302 -0.18528 0.00844536 0.0915588 -0.0346434\n 0.00195478 -0.0150664 -0.0206752 -0.0642658 0.0638689 0.0250518 0.0999631 0.012992 -0.111668 0.0393523 0.423534 0.688046 0.513839 -0.222499","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"If you need the full spectrum, but would like to use less memory, consider using the in-place eigen!.","category":"page"},{"location":"generated/exact-example.html#Iterative-sparse-solvers","page":"Exact diagonalization","title":"Iterative sparse solvers","text":"","category":"section"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"For larger Hamiltonians, it is better to use an iterative solver. There are several options. We will look at eigs from Arpack.jl and eigsolve from KrylovKit.jl.","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"Let's start with Arpack's eigs. It is important to set the nev and which keyword arguments. nev sets the number of eigenpairs to find. which should in most cases be set to :SR, which will find the eigenvalues with the smallest real part.","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"using Arpack\n\nnum_eigvals = 3\n\nsparse_matrix = sparse(ham)\nvals_ar, vecs_ar = eigs(sparse_matrix; which=:SR, nev=num_eigvals)\nvals_ar","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"3-element Vector{Float64}:\n -6.979863998321618\n -3.363124291613361\n -0.7590191922770777","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"Using KrylovKit's eigsolve is similar, but the nev and which are given as positional arguments. Note that KrylovKit may sometimes return more than nev eigenpairs if it happens to find them.","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"using KrylovKit\n\nvals_kk, vecs_kk = eigsolve(sparse_matrix, num_eigvals, :SR)\nvals_kk","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"14-element Vector{Float64}:\n -6.979863998321601\n -3.3631242916133672\n -0.7590191922770995\n 0.1358418221962161\n 0.15789998694608265\n 0.8767114411781378\n 1.5305929970973278\n 1.583573261186741\n 3.0728703303258706\n 3.1256726539518347\n 4.862107221562172\n 6.260694850380597\n 6.402671211183112\n 9.093371706203957","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"Both solvers use variants of the Lanczos algorithm for Hermitian matrices and the Arnoldi algorithm for non-Hermitian ones. These may in some cases miss degenerate eigenpairs.","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"If diagonalization takes too long, you can reduce the tolerance by setting the tol keyword argument to eigs or eigsolve. Using drastically lower tolerances than the default can still produce good results in practice. This, however, should be checked on a case-by-case basis.","category":"page"},{"location":"generated/exact-example.html#The-matrix-free-method","page":"Exact diagonalization","title":"The matrix-free method","text":"","category":"section"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"KrylovKit's eigsolve function is implemented in a way that does not require the linear operator and vector to be Julia arrays. Rimu leverages this functionality, which allows diagonalising Hamiltonians without ever needing to construct the matrix - all matrix elements are generated on the fly.","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"While this method is by far the slowest of the ones discussed, it also uses drastically less memory. This allows us to diagonalise much larger Hamiltonians.","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"To use this method, you first need a starting vector. It's best to use PDVec here as it leverages threading during the diagonalization.","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"dvec = PDVec(add => 1.0)","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"1-element PDVec: style = IsDeterministic{Float64}()\n fs\"|0 0 4 0 0⟩\" => 1.0","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"Then, pass that vector and the Hamiltonian to eigsolve.","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"vals_mf, vecs_mf = eigsolve(ham, dvec, num_eigvals, :SR; issymmetric=true)\nvals_mf","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"10-element Vector{Float64}:\n -6.979863998321612\n -3.3631242916133406\n -0.7590191922770728\n 0.1578999869460862\n 0.8767114411781503\n 1.5835732611867401\n 3.125672653951839\n 4.862107221562172\n 6.402671211183112\n 9.093371706203953","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"Keep in mind that if an eigenvector is orthogonal to dvec, KrylovKit will miss it. Consider the following example:","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"eigsolve(ham, vecs_mf[2], num_eigvals, :SR, issymmetric=true)[1]","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"1-element Vector{Float64}:\n -3.3631242916133606","category":"page"},{"location":"generated/exact-example.html#Reducing-matrix-size-with-symmetries","page":"Exact diagonalization","title":"Reducing matrix size with symmetries","text":"","category":"section"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"As these matrices tend to get large quickly, memory is usually the bottleneck. There are currently two methods implemented to reduce the matrix size, ParitySymmetry and TimeReversalSymmetry. These symmetries work by performing a unitary transformation on the Hamiltonian which causes it to become block-diagonal. When building a matrix from a block-diagonal Hamiltonian, only the block that contains the starting address is constructed.","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"You should only use these where the relevant symmetries actually apply - no checks are performed to make sure they do. There is also currently no way of using both at the same time. Please consult the documentation for a more in-depth description of these options.","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"The Hamiltonian presented in this example is compatible with ParitySymmetry. Let's see how the matrix size is reduced when applying it.","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"size(sparse(ham))","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"(14, 14)","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"size(sparse(ParitySymmetry(ham)))","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"(10, 10)","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"In this small example, the size reduction is modest, but for larger systems, you can expect to reduce the dimension of the matrix by about half.","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"all_eigs = eigvals(Matrix(ham))\neven_eigs = eigvals(Matrix(ParitySymmetry(ham)))","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"10-element Vector{Float64}:\n -6.979863998321619\n -3.3631242916133615\n -0.7590191922770766\n 0.1578999869460802\n 0.876711441178143\n 1.5835732611867412\n 3.1256726539518436\n 4.862107221562176\n 6.4026712111831126\n 9.093371706203952","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"The eigenvalues of the transformed Hamiltonian are a subset of the full spectrum. To get the other half, we can pass the even=false keyword argument to ParitySymmetry. When doing that, we need to make sure the starting address of the Hamiltonian is not symmetric under reversal:","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"add_odd = BoseFS(M, cld(M, 2) => N - 3, cld(M, 2) - 1 => 2, cld(M, 2) + 2 => 1)","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"BoseFS{4,5}(0, 2, 1, 0, 1)","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"odd_eigs = eigvals(Matrix(ParitySymmetry(HubbardMom1D(add_odd); even=false)))","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"4-element Vector{Float64}:\n 0.135841822196218\n 1.530592997097328\n 3.0728703303258613\n 6.260694850380591","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"Now, let's check that combining the two sets of eigenvalues indeed recovers the whole spectrum.","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"sort([even_eigs; odd_eigs]) ≈ all_eigs","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"true","category":"page"},{"location":"generated/exact-example.html#Computing-observables","page":"Exact diagonalization","title":"Computing observables","text":"","category":"section"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"Since building a matrix from an operator only builds the part that is reachable from the starting address, we need to use a different approach when computing observables.","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"To demonstrate this, we will use the DensityMatrixDiagonal operator, which in this case will give the momentum density.","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"The idea here is to construct a PDVec from the computed eigenvector and use it directly with the operator.","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"dvec = PDVec(zip(bsr.basis, eigvecs(Matrix(ham))[:, 1]))","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"14-element PDVec: style = IsDeterministic{Float64}()\n fs\"|1 3 0 0 0⟩\" => 0.00363555\n fs\"|1 0 1 2 0⟩\" => -0.0214153\n fs\"|2 0 0 0 2⟩\" => -0.00237613\n fs\"|0 0 4 0 0⟩\" => -0.980348\n fs\"|0 1 2 1 0⟩\" => 0.177701\n fs\"|0 0 1 1 2⟩\" => -0.0119687\n fs\"|3 0 0 1 0⟩\" => 0.00195478\n fs\"|0 0 0 3 1⟩\" => 0.00363555\n fs\"|0 2 0 2 0⟩\" => -0.0138439\n fs\"|2 1 1 0 0⟩\" => -0.0119687\n fs\"|1 1 0 1 1⟩\" => -0.00234782\n fs\"|0 1 0 0 3⟩\" => 0.00195478\n fs\"|1 0 2 0 1⟩\" => 0.0768085\n fs\"|0 2 1 0 1⟩\" => -0.0214153","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"The eigenvectors these methods produce are normalized, hence we can use the three-argument dot to compute the values of observables. Here we are computing the single particle momentum density distribution, which is just the diagonal of the single-particle density matrix in momentum space.","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"[dot(dvec, DensityMatrixDiagonal(i), dvec) for i in 1:M]","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"5-element Vector{Float64}:\n 0.006686138945087834\n 0.03307039977204201\n 3.9204869225657397\n 0.033070399772041965\n 0.006686138945087815","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"","category":"page"},{"location":"generated/exact-example.html","page":"Exact diagonalization","title":"Exact diagonalization","text":"This page was generated using Literate.jl.","category":"page"},{"location":"rimuio.html#Module-RimuIO","page":"I/O","title":"Module RimuIO","text":"","category":"section"},{"location":"rimuio.html","page":"I/O","title":"I/O","text":"Modules = [RimuIO]","category":"page"},{"location":"rimuio.html#Rimu.RimuIO","page":"I/O","title":"Rimu.RimuIO","text":"Module to provide file input and output functionality for Rimu. Provides convenience functions:\n\nRimuIO.save_df(filename, df::DataFrame) Save dataframe in Arrow format.\nRimuIO.load_df(filename) Load Arrow file into dataframe.\nRimuIO.save_state(filename, vector; metadata...) Save a vector and optinal metadata in Arrow format.\nRimuIO.load_state(filename) Load a file created by save_state.\n\n\n\n\n\n","category":"module"},{"location":"rimuio.html#Rimu.RimuIO.DVecAsTable","page":"I/O","title":"Rimu.RimuIO.DVecAsTable","text":"struct DVecAsTable\n\nWrapper over the storage of a DVec that allows us to treat a DVec as a table from Tables.jl. Constructed with Tables.table(::DVec).\n\n\n\n\n\n","category":"type"},{"location":"rimuio.html#Rimu.RimuIO.PDVecAsTable","page":"I/O","title":"Rimu.RimuIO.PDVecAsTable","text":"struct PDVecAsTable\n\nWrapper over the storage of a PDVec that allows us to treat a PDVec as a table from Tables.jl. Constructed with Tables.table(::PDVec).\n\n\n\n\n\n","category":"type"},{"location":"rimuio.html#Rimu.RimuIO.load_df-Tuple{Any}","page":"I/O","title":"Rimu.RimuIO.load_df","text":"load_df(filename; propagate_metadata = true, add_filename = true) -> DataFrame\n\nLoad Arrow file into DataFrame. Optionally propagate metadata to DataFrame and add the file name as metadata.\n\nSee also RimuIO.save_df.\n\n\n\n\n\n","category":"method"},{"location":"rimuio.html#Rimu.RimuIO.load_state-Union{Tuple{D}, Tuple{Type{D}, Any}} where D","page":"I/O","title":"Rimu.RimuIO.load_state","text":"load_state(filename; kwargs...) -> PDVec, NamedTuple\nload_state(PDVec, filename; kwargs...) -> PDVec, NamedTuple\nload_state(DVec, filename; kwargs...) -> DVec, NamedTuple\n\nLoad the state saved in the Arrow file filename. kwargs are passed to the constructor of PDVec/DVec. Any metadata stored in the file is be parsed as a number (if possible) and returned alongside the vector in a NamedTuple.\n\nSee also save_state.\n\n\n\n\n\n","category":"method"},{"location":"rimuio.html#Rimu.RimuIO.save_df-Tuple{Any, DataFrame}","page":"I/O","title":"Rimu.RimuIO.save_df","text":"save_df(filename, df::DataFrame; kwargs...)\n\nSave dataframe in Arrow format.\n\nKeyword arguments are passed on to Arrow.write. Compression is enabled by default for large DataFrames (over 10,000 rows).\n\nTable-level metadata of the DataFrame is saved as Arrow metadata (with String value) unless overwritten with the keyword argument metadata.\n\nSee also RimuIO.load_df.\n\n\n\n\n\n","category":"method"},{"location":"rimuio.html#Rimu.RimuIO.save_state-Tuple{Any, Any}","page":"I/O","title":"Rimu.RimuIO.save_state","text":"save_state(filename, vector; io, kwargs...)\n\nSave PDVec or DVec vector to an arrow file filename.\n\nio determines the output stream to write progress to. Defaults to stderr when MPI is enabled and devnull otherwise.\n\nAll other kwargs are saved as strings to the arrow file and will be parsed back when the state is loaded.\n\nSee also load_state.\n\n\n\n\n\n","category":"method"},{"location":"rimuio.html#Index","page":"I/O","title":"Index","text":"","category":"section"},{"location":"rimuio.html","page":"I/O","title":"I/O","text":"Pages = [\"rimuio.md\"]","category":"page"},{"location":"hamiltonians.html#Module-Hamiltonians","page":"Hamiltonians","title":"Module Hamiltonians","text":"","category":"section"},{"location":"hamiltonians.html","page":"Hamiltonians","title":"Hamiltonians","text":"This module contains definitions of Hamiltonians, in particular specific physical models of interest. These are organised by means of an interface around the abstract type AbstractHamiltonian, in the spirit of the AbstractArray interface as discussed in the Julia Documentation.","category":"page"},{"location":"hamiltonians.html","page":"Hamiltonians","title":"Hamiltonians","text":"The Hamiltonians can be used for projector quantum Monte Carlo with ProjectorMonteCarloProblem or for exact diagonalization with ExactDiagonalizationProblem, see Exact Diagonalization.","category":"page"},{"location":"hamiltonians.html","page":"Hamiltonians","title":"Hamiltonians","text":"Hamiltonians","category":"page"},{"location":"hamiltonians.html#Rimu.Hamiltonians","page":"Hamiltonians","title":"Rimu.Hamiltonians","text":"The module Rimu.Hamiltonians defines types and functions for working with Hamiltonians.\n\nExported concrete Hamiltonian types\n\nReal space Hubbard models\n\nHubbardReal1D\nHubbardReal1DEP\nHubbardRealSpace\nExtendedHubbardReal1D\n\nMomentum space Hubbard models\n\nHubbardMom1D\nHubbardMom1DEP\n\nHarmonic oscillator models\n\nHOCartesianContactInteractions\nHOCartesianEnergyConservedPerDim\nHOCartesianCentralImpurity\n\nOther\n\nFroehlichPolaron\nMatrixHamiltonian\nTranscorrelated1D\n\nWrappers\n\nGutzwillerSampling\nGuidingVectorSampling\nParitySymmetry\nTimeReversalSymmetry\nStoquastic\n\nObservables\n\nParticleNumberOperator\nG2RealCorrelator\nG2MomCorrelator\nG2RealSpace\nDensityMatrixDiagonal\nSingleParticleExcitation\nTwoParticleExcitation\nMomentum\nAxialAngularMomentumHO\n\nInterface for working with Hamiltonians\n\nAbstractHamiltonian: defined in the module Interfaces\n\n\n\n\n\n","category":"module"},{"location":"hamiltonians.html","page":"Hamiltonians","title":"Hamiltonians","text":"Here is a list of fully implemented model Hamiltonians. There are several variants of the Hubbard model in real and momentum space, as well as some other models.","category":"page"},{"location":"hamiltonians.html#Real-space-Hubbard-models","page":"Hamiltonians","title":"Real space Hubbard models","text":"","category":"section"},{"location":"hamiltonians.html","page":"Hamiltonians","title":"Hamiltonians","text":"HubbardReal1D\nHubbardReal1DEP\nHubbardRealSpace\nExtendedHubbardReal1D","category":"page"},{"location":"hamiltonians.html#Rimu.Hamiltonians.HubbardReal1D","page":"Hamiltonians","title":"Rimu.Hamiltonians.HubbardReal1D","text":"HubbardReal1D(address; u=1.0, t=1.0)\n\nImplements a one-dimensional Bose Hubbard chain in real space.\n\nhatH = -t sum_langle ijrangle a_i^ a_j + fracu2sum_i n_i (n_i-1)\n\nArguments\n\naddress: the starting address, defines number of particles and sites.\nu: the interaction parameter.\nt: the hopping strength.\n\nSee also\n\nHubbardMom1D\nExtendedHubbardReal1D\n\n\n\n\n\n","category":"type"},{"location":"hamiltonians.html#Rimu.Hamiltonians.HubbardReal1DEP","page":"Hamiltonians","title":"Rimu.Hamiltonians.HubbardReal1DEP","text":"HubbardReal1DEP(address; u=1.0, t=1.0, v_ho=1.0)\n\nImplements a one-dimensional Bose Hubbard chain in real space with external potential.\n\nhatH = -t sum_langle ijrangle a_i^ a_j + sum_i ϵ_i n_i\n+ fracu2sum_i n_i (n_i-1)\n\nArguments\n\naddress: the starting address, defines number of particles and sites.\nu: the interaction parameter.\nt: the hopping strength.\nv_ho: strength of the external harmonic oscillator potential ϵ_i = v_ho i^2.\n\nThe first index is i=0 and the maximum of the potential occurs in the centre of the lattice.\n\nSee also\n\nHubbardReal1D\nHubbardMom1D\nExtendedHubbardReal1D\n\n\n\n\n\n","category":"type"},{"location":"hamiltonians.html#Rimu.Hamiltonians.HubbardRealSpace","page":"Hamiltonians","title":"Rimu.Hamiltonians.HubbardRealSpace","text":"HubbardRealSpace(address; geometry=PeriodicBoundaries(M,), t=ones(C), u=ones(C, C), v=zeros(C, D))\n\nHubbard model in real space. Supports single or multi-component Fock state addresses (with C components) and various (rectangular) lattice geometries in D dimensions.\n\n hatH = -sum_langle ijrangleσ t_σ a^_iσ a_jσ +\n frac12sum_iσ u_σσ n_iσ (n_iσ - 1) +\n sum_iστu_στ n_iσ n_iτ\n\nIf v is nonzero then this calculates hatH + hatV by adding the harmonic trapping potential\n\n hatV = sum_iσd v_σd x_di^2 n_iσ\n\nwhere x_di is the distance of site i from the centre of the trap along dimension d.\n\nAddress types\n\nBoseFS: Single-component Bose-Hubbard model.\nFermiFS: Single-component Fermi-Hubbard model.\nCompositeFS: For multi-component models.\n\nNote that a single component of fermions cannot interact with itself. A warning is produced if addressis incompatible with the interaction parameters u.\n\nGeometries\n\nImplemented CubicGrids for keyword geometry\n\nPeriodicBoundaries\nHardwallBoundaries\nLadderBoundaries\n\nDefault is geometry=PeriodicBoundaries(M,), i.e. a one-dimensional lattice with the number of sites M inferred from the number of modes in address.\n\nOther parameters\n\nt: the hopping strengths. Must be a vector of length C. The i-th element of the vector corresponds to the hopping strength of the i-th component.\nu: the on-site interaction parameters. Must be a symmetric matrix. u[i, j] corresponds to the interaction between the i-th and j-th component. u[i, i] corresponds to the interaction of a component with itself. Note that u[i,i] must be zero for fermionic components.\nv: the trap potential strengths. Must be a matrix of size C × D. v[i,j] is the strength of the trap for component i in the jth dimension.\n\n\n\n\n\n","category":"type"},{"location":"hamiltonians.html#Rimu.Hamiltonians.ExtendedHubbardReal1D","page":"Hamiltonians","title":"Rimu.Hamiltonians.ExtendedHubbardReal1D","text":"ExtendedHubbardReal1D(address; u=1.0, v=1.0, t=1.0, boundary_condition=:periodic)\n\nImplements the extended Hubbard model on a one-dimensional chain in real space. This Hamiltonian can be either real or complex, depending on the choice of boundary_condition.\n\nhatH = -t sum_langle ijrangle a_i^ a_j + fracu2sum_i n_i (n_i-1) +\nv sum_langle ijrangle n_i n_j\n\nArguments\n\naddress: the starting address.\nu: on-site interaction parameter\nv: the next-neighbor interaction\nt: the hopping strength\nboundary_condition The following values are supported:\n:periodic: usual period boundary condition realising a ring geometry.\n:hard_wall: hopping over the boundary is not allowed.\n:twisted: like :periodic but hopping over the boundary incurs an additional factor of -1.\nθ <: Number: like :periodic and :twisted but hopping over the boundary incurs a factor exp(iθ) for a hop to the right and exp(iθ) for a hop to the left. With this choice the Hamiltonian will have a complex eltype whereas otherwise the eltype is determined by the type of the parameters t, u, and v.\n\nSee also HubbardRealSpace.\n\n\n\n\n\n","category":"type"},{"location":"hamiltonians.html#Momentum-space-Hubbard-models","page":"Hamiltonians","title":"Momentum space Hubbard models","text":"","category":"section"},{"location":"hamiltonians.html","page":"Hamiltonians","title":"Hamiltonians","text":"HubbardMom1D\nHubbardMom1DEP\nExtendedHubbardMom1D","category":"page"},{"location":"hamiltonians.html#Rimu.Hamiltonians.HubbardMom1D","page":"Hamiltonians","title":"Rimu.Hamiltonians.HubbardMom1D","text":"HubbardMom1D(address; u=1.0, t=1.0, dispersion=hubbard_dispersion)\n\nImplements a one-dimensional Bose Hubbard chain in momentum space.\n\nhatH = sum_k ϵ_k n_k + fracuMsum_kpqr a^_r a^_q a_p a_k δ_r+qp+k\n\nArguments\n\naddress: the starting address, defines number of particles and sites.\nu: the interaction parameter.\nt: the hopping strength.\ndispersion: defines ϵ_k =dispersion(t, k)\nhubbard_dispersion: ϵ_k = -2(Re(t) cos(k) + Im(t) sin(k))\ncontinuum_dispersion: ϵ_k = Re(t) k^2 - 2 Im(t) k\n\nSee also\n\nHubbardReal1D\nExtendedHubbardReal1D\n\n\n\n\n\n","category":"type"},{"location":"hamiltonians.html#Rimu.Hamiltonians.HubbardMom1DEP","page":"Hamiltonians","title":"Rimu.Hamiltonians.HubbardMom1DEP","text":"HubbardMom1DEP(address; u=1.0, t=1.0, v_ho=1.0, dispersion=hubbard_dispersion)\n\nImplements a one-dimensional Bose Hubbard chain in momentum space with harmonic external potential.\n\nH = sum_k ϵ_k n_k + fracuMsum_kpqr a^_r a^_q a_p a_k δ_r+qp+k\n + V_mathrmho \n\nwhere\n\nbeginaligned\nV_mathrmho = frac1M sum_pq mathrmDFTV_ext_p-q \n a^_p a_q \nV_mathrmext(x) = v_mathrmho x^2 \nendaligned\n\nis an external harmonic potential in momentum space, mathrmDFT_k is a discrete Fourier transform performed by fft()[k%M + 1], and M == num_modes(address).\n\nArguments\n\naddress: the starting address, defines number of particles and sites.\nu: the interaction parameter.\nt: the hopping strength.\ndispersion: defines ϵ_k =dispersion(t, k)\nhubbard_dispersion: ϵ_k = -2Re(t) cos(k) + Im(t) sin(k)\ncontinuum_dispersion: ϵ_k = Re(t) k^2 - 2 Im(t) k\nv_ho: strength of the external harmonic oscillator potential v_mathrmho.\n\nSee also HubbardMom1D, HubbardReal1DEP, Transcorrelated1D, Hamiltonians.\n\n\n\n\n\n","category":"type"},{"location":"hamiltonians.html#Rimu.Hamiltonians.ExtendedHubbardMom1D","page":"Hamiltonians","title":"Rimu.Hamiltonians.ExtendedHubbardMom1D","text":"ExtendedHubbardMom1D(\n address; \n u=1.0, t=1.0, v=1.0, dispersion=hubbard_dispersion, boundary_condition = 0.0\n)\n\nImplements a one-dimensional extended Hubbard chain, also known as the t - V model, in momentum space.\n\nhatH = sum_k ϵ_k n_k + frac12M sum_kpqr (u + 2v cos(q-p)) a^_r a^_q a_p a_k δ_r+qp+k\n\nArguments\n\naddress: the starting address, defines number of particles and sites.\nu: the interaction parameter.\nt: the hopping strength.\nboundary_condition: θ <: Number: hopping over the boundary incurs a factor exp(iθ) for a hop to the right and exp(iθ) for a hop to the left.\ndispersion: defines ϵ_k =dispersion(t, k + θ)\nhubbard_dispersion: ϵ_k = -2 (Re(t) cos(k + θ) + Im(t) sin(k + θ))\ncontinuum_dispersion: ϵ_k = Re(t) (k + θ)^2 - 2 Im(t) (k + θ)\n\nSee also\n\nHubbardMom1D\nHubbardReal1D\nExtendedHubbardReal1D\n\n\n\n\n\n","category":"type"},{"location":"hamiltonians.html#Harmonic-oscillator-models","page":"Hamiltonians","title":"Harmonic oscillator models","text":"","category":"section"},{"location":"hamiltonians.html","page":"Hamiltonians","title":"Hamiltonians","text":"HOCartesianContactInteractions\nHOCartesianEnergyConservedPerDim\nHOCartesianCentralImpurity","category":"page"},{"location":"hamiltonians.html#Rimu.Hamiltonians.HOCartesianContactInteractions","page":"Hamiltonians","title":"Rimu.Hamiltonians.HOCartesianContactInteractions","text":"HOCartesianContactInteractions(addr; S, η, g = 1.0, interaction_only = false, block_by_level = true)\n\nImplements a bosonic harmonic oscillator in Cartesian basis with contact interactions\n\nhatH = sum_i epsilon_mathbfi n_mathbfi + fracg2sum_mathbfijkl\n V_mathbfijkl a^_mathbfi a^_mathbfj a_mathbfk a_mathbfl\n\nFor a D-dimensional harmonic oscillator indices mathbfi mathbfj ldots are D-tuples. The energy scale is defined by the first dimension i.e. hbar omega_x so that single particle energies are\n\n fracepsilon_mathbfihbar omega_x = (i_x + 12) + eta_y (i_y+12) + ldots\n\nThe factors eta_y ldots allow for anisotropic trapping geometries and are assumed to be greater than 1 so that omega_x is the smallest trapping frequency.\n\nBy default the offdiagonal elements due to the interactions are consistent with first-order degenerate perturbation theory\n\n V_mathbfijkl = delta_epsilon_mathbfi + epsilon_mathbfj\n ^epsilon_mathbfk + epsilon_mathbfl\n prod_d in x yldots mathcalI(i_dj_dk_dl_d)\n\nwhere the delta function indicates that the total noninteracting energy is conserved meaning all states with the same noninteracting energy are connected by this interaction and the Hamiltonian blocks according to noninteracting energy levels. Setting block_by_level = false will disable this restriction and allow coupling between basis states of any noninteracting energy level, leading to many more offdiagonals and fewer but larger blocks (the blocks are still distinguished by parity of basis states). Alternatively, see HOCartesianEnergyConservedPerDim for a model with the stronger restriction that conserves energy separately per spatial dimension. The integral mathcalI(abcd) is of four one dimensional harmonic oscillator basis functions, implemented in four_oscillator_integral_general.\n\nArguments\n\naddr: the starting address, defines number of particles and total number of modes.\nS: Tuple of the number of levels in each dimension, including the groundstate. The allowed couplings between states is defined by the aspect ratio of S .- 1. Defaults to a 1D spectrum with number of levels matching modes of addr. Will be sorted to make the first dimension the largest.\nη: Define a custom aspect ratio for the trapping potential strengths, instead of deriving from S .- 1. This will only affect the single particle energy scale and not the interactions. The values are always scaled relative to the first dimension, which sets the energy scale of the system, hbaromega_x.\ng: the (isotropic) bare interaction parameter. The value of g is assumed to be in trap units.\ninteraction_only: if set to true then the noninteracting single-particle terms are ignored. Useful if only energy shifts due to interactions are required.\nblock_by_level: if set to false will allow the interactions to couple all states without comparing their noninteracting energy.\n\nwarning: Warning\nnum_offdiagonals is a bad estimate for this Hamiltonian. Take care when building a matrix or using QMC methods. Use get_all_blocks first then pass option col_hint = block_size to BasisSetRep to safely build the matrix.\n\n\n\n\n\n","category":"type"},{"location":"hamiltonians.html#Rimu.Hamiltonians.HOCartesianEnergyConservedPerDim","page":"Hamiltonians","title":"Rimu.Hamiltonians.HOCartesianEnergyConservedPerDim","text":"HOCartesianEnergyConservedPerDim(addr; S, η, g = 1.0, interaction_only = false)\n\nImplements a bosonic harmonic oscillator in Cartesian basis with contact interactions\n\nhatH = sum_i ϵ_i n_i + fracg2sum_ijkl V_ijkl a^_i a^_j a_k a_l\n\nwith the additional restriction that the interactions only couple states with the same energy in each dimension separately. See HOCartesianContactInteractions for a model that conserves total energy.\n\nFor a D-dimensional harmonic oscillator indices mathbfi mathbfj ldots are D-tuples. The energy scale is defined by the first dimension i.e. hbar omega_x so that single particle energies are\n\n fracepsilon_mathbfihbar omega_x = (i_x + 12) + eta_y (i_y+12) + ldots\n\nThe factors eta_y ldots allow for anisotropic trapping geometries and are assumed to be greater than 1 so that omega_x is the smallest trapping frequency.\n\nMatrix elements V_mathbfijkl are for a contact interaction calculated in this basis using first-order degenerate perturbation theory.\n\n V_mathbfijkl = prod_d in x yldots mathcalI(i_dj_dk_dl_d)\n delta_i_d + j_d^k_d + l_d\n\nwhere the delta-function indicates that the noninteracting energy is conserved along each dimension. The integral mathcalI(abcd) is of four one dimensional harmonic oscillator basis functions, see four_oscillator_integral_general, with the additional restriction that energy is conserved in each dimension.\n\nArguments\n\naddr: the starting address, defines number of particles and total number of modes.\nS: Tuple of the number of levels in each dimension, including the groundstate. Defaults to a 1D spectrum with number of levels matching modes of addr. Will be sorted to make the first dimension the largest.\nη: Define a custom aspect ratio for the trapping potential strengths, instead of deriving from S .- 1. The values are always scaled relative to the first dimension, which sets the energy scale of the system, hbaromega_x.\ng: the (isotropic) interparticle interaction parameter. The value of g is assumed to be in trap units.\ninteraction_only: if set to true then the noninteracting single-particle terms are ignored. Useful if only energy shifts due to interactions are required.\n\n\n\n\n\n","category":"type"},{"location":"hamiltonians.html#Rimu.Hamiltonians.HOCartesianCentralImpurity","page":"Hamiltonians","title":"Rimu.Hamiltonians.HOCartesianCentralImpurity","text":"HOCartesianCentralImpurity(addr; kwargs...)\n\nHamiltonian of non-interacting particles in an arbitrary harmonic trap with a delta-function potential at the centre, with strength g,\n\nhatH_mathrmrel = sum_mathbfi ϵ_mathbfi n_mathbfi\n + gsum_mathbfij V_mathbfij a^_mathbfi a_mathbfj\n\nFor a D-dimensional harmonic oscillator indices mathbfi mathbfj ldots are D-tuples. The energy scale is defined by the first dimension i.e. hbar omega_x so that single particle energies are\n\n fracepsilon_mathbfihbar omega_x = (i_x + 12) + eta_y (i_y+12) + ldots\n\nThe factors eta_y ldots allow for anisotropic trapping geometries and are assumed to be greater than 1 so that omega_x is the smallest trapping frequency.\n\nMatrix elements V_mathbfij are for a delta function potential calculated in this basis\n\n V_mathbfij = prod_d in x yldots psi_i_d(0) psi_j_d(0)\n\nOnly even parity states feel this impurity, so all i_d are even. Note that the matrix representation of this Hamiltonian for a single particle is completely dense in the even-parity subspace.\n\nArguments\n\naddr: the starting address, defines number of particles and total number of modes.\nmax_nx = num_modes(addr) - 1: the maximum harmonic oscillator index number in the x-dimension. Must be even. Index number for the harmonic oscillator groundstate is 0.\nηs = (): a tuple of aspect ratios for the remaining dimensions (η_y, ...). Should be empty for a 1D trap or contain values greater than 1.0. The maximum index in other dimensions will be the largest even number less than M/η_y.\nS = nothing: Instead of max_nx, manually set the number of levels in each dimension, including the groundstate. Must be a Tuple of Ints.\ng = 1.0: the strength of the delta impurity in (x-dimension) trap units.\nimpurity_only=false: if set to true then the trap energy terms are ignored. Useful if only energy shifts due to the impurity are required.\n\nwarning: Warning\nDue to use of `SpecialFunctions` with large arguments the matrix representation of\nthis Hamiltonian may not be strictly symmetric, but is approximately symmetric within\nmachine precision.\n\nSee also HOCartesianContactInteractions andHOCartesianEnergyConservedPerDim.\n\n\n\n\n\n","category":"type"},{"location":"hamiltonians.html#Other-model-Hamiltonians","page":"Hamiltonians","title":"Other model Hamiltonians","text":"","category":"section"},{"location":"hamiltonians.html","page":"Hamiltonians","title":"Hamiltonians","text":"MatrixHamiltonian\nTranscorrelated1D\nFroehlichPolaron","category":"page"},{"location":"hamiltonians.html#Rimu.Hamiltonians.MatrixHamiltonian","page":"Hamiltonians","title":"Rimu.Hamiltonians.MatrixHamiltonian","text":"MatrixHamiltonian(\n mat::AbstractMatrix{T};\n starting_address::Int = starting_address(mat)\n) <: AbstractHamiltonian{T}\n\nWrap an abstract matrix mat as an AbstractHamiltonian object. Works with stochastic methods of ProjectorMonteCarloProblem() and DVec. Optionally, a valid index can be provided as the starting_address.\n\nSpecialised methods are implemented for sparse matrices of type AbstractSparseMatrixCSC. One based indexing is required for the matrix mat.\n\n\n\n\n\n","category":"type"},{"location":"hamiltonians.html#Rimu.Hamiltonians.Transcorrelated1D","page":"Hamiltonians","title":"Rimu.Hamiltonians.Transcorrelated1D","text":"Transcorrelated1D(address; t=1.0, v=1.0, v_ho=0.0, cutoff=1, three_body_term=true)\n\nImplements a transcorrelated Hamiltonian for contact interactions in one dimensional momentum space from Jeszenski et al. (2018). Currently limited to two component fermionic addresses.\n\nbeginaligned\n\ntildeH = t sum_kσk^2 n_kσ \n quad + sum_pqkσσ T_pqk a^_p-kσ a^_q+kσ a_qσ a_pσ \n quad + sum_pqskkσσ Q_kka^_p-kσ a^_q+kσ a^_s+k-kσ\n a_sσ a_qσ a_pσ \n quad + V_mathrmho\nendaligned\n\nwhere\n\nbeginaligned\ntildeu(k) = begincases -frac2k^2 mathrmif k k_c\n0 mathrmotherwise\nendcases\n\n\nT_pqk = fracvM + frac2vMleftk^2tildeu(k)\n - (p - q)ktildeu(k)right + frac2v^2tW(k)\nW(k) = frac1M^2sum_q (k - q)q tildeu(q)tildeu(k - q) \nQ_kl = -fracv^2t M^2k tildeu(k)ltildeu(l)\nendaligned\n\nArguments\n\naddress: The starting address, defines number of particles and sites.\nv: The interaction parameter.\nt: The kinetic energy prefactor.\nv_ho: Strength of the external harmonic oscillator potential V_mathrmho. See HubbardMom1DEP.\ncutoff controls k_c in equations above. Note: skipping generating off-diagonal elements below the cutoff is not implemented - zero-valued elements are returned instead.\nthree_body_term: If set to false, generating three body excitations is skipped. Note: when disabling three body terms, cutoff should be set to a higher value for best results.\n\nSee also\n\nHubbardMom1D\nHubbardMom1DEP\n\n\n\n\n\n","category":"type"},{"location":"hamiltonians.html#Rimu.Hamiltonians.FroehlichPolaron","page":"Hamiltonians","title":"Rimu.Hamiltonians.FroehlichPolaron","text":"FroehlichPolaron(address::OccupationNumberFS{M}; kwargs...) <: AbstractHamiltonian\n\nThe Froehlich polaron Hamiltonian for a 1D lattice with M momentum modes is given by\n\nH = (p_f - p)^2m + ωN - v Σₖ(aₖ^ + aₖ)\n\nwhere p is the total momentum, p_f = Σ_k k aₖ^ aₖ is the momentum operator for the bosons, and k part of the momentum lattice with separation 2πl. N is the number operator for the bosons.\n\nKeyword Arguments\n\np=0.0: the total momentum p.\nv=1.0: the coupling strength v.\nmass=1.0: the particle mass m.\nomega=1.0: the oscillation frequency of the phonons ω.\nl=1.0: the box size in real space l. Provides scale parameter of the momentum lattice.\nmomentum_cutoff=nothing: the maximum boson momentum allowed for an address.\nmode_cutoff: the maximum number of bosons in each momentum mode. Defaults to the maximum value supported by the address type OccupationNumberFS.\n\nExamples\n\njulia> fs = OccupationNumberFS(0,0,0)\nOccupationNumberFS{3, UInt8}(0, 0, 0)\n\njulia> ham = FroehlichPolaron(fs; v=0.5)\nFroehlichPolaron(fs\"|0 0 0⟩{8}\"; v=0.5, mass=1.0, omega=1.0, l=1.0, p=0.0, mode_cutoff=255)\n\njulia> dimension(ham)\n16777216\n\njulia> dimension(FroehlichPolaron(fs; v=0.5, mode_cutoff=5))\n216\n\nSee also OccupationNumberFS, dimension, AbstractHamiltonian.\n\n\n\n\n\n","category":"type"},{"location":"hamiltonians.html#Convenience-functions","page":"Hamiltonians","title":"Convenience functions","text":"","category":"section"},{"location":"hamiltonians.html","page":"Hamiltonians","title":"Hamiltonians","text":"rayleigh_quotient\nmomentum\nhubbard_dispersion\ncontinuum_dispersion\nshift_lattice\nshift_lattice_inv","category":"page"},{"location":"hamiltonians.html#Rimu.Hamiltonians.rayleigh_quotient","page":"Hamiltonians","title":"Rimu.Hamiltonians.rayleigh_quotient","text":"rayleigh_quotient(H, v)\n\nReturn the Rayleigh quotient of the linear operator H and the vector v:\n\nfrac v H v vv \n\n\n\n\n\n","category":"function"},{"location":"hamiltonians.html#Rimu.Hamiltonians.momentum","page":"Hamiltonians","title":"Rimu.Hamiltonians.momentum","text":"momentum(ham::AbstractHamiltonian)\n\nMomentum as a linear operator in Fock space. Pass a Hamiltonian ham in order to convey information about the Fock basis. Returns an AbstractHamiltonian that represents the momentum operator.\n\nNote: momentum is currently only defined on HubbardMom1D.\n\nExample\n\njulia> add = BoseFS((1, 0, 2, 1, 2, 1, 1, 3));\n\n\njulia> ham = HubbardMom1D(add; u = 2.0, t = 1.0);\n\n\njulia> mom = momentum(ham);\n\n\njulia> diagonal_element(mom, add) # calculate the momentum of a single configuration\n-1.5707963267948966\n\njulia> v = DVec(add => 10; capacity=1000);\n\n\njulia> rayleigh_quotient(mom, v) # momentum expectation value for state vector `v`\n-1.5707963267948966\n\nPart of the AbstractHamiltonian interface.\n\n\n\n\n\n","category":"function"},{"location":"hamiltonians.html#Rimu.Hamiltonians.hubbard_dispersion","page":"Hamiltonians","title":"Rimu.Hamiltonians.hubbard_dispersion","text":"hubbard_dispersion(t, k)\n\nDispersion relation for HubbardMom1D. Returns -2(Re(t) cos(k) + Im(t) sin(k)).\n\nSee also continuum_dispersion.\n\n\n\n\n\n","category":"function"},{"location":"hamiltonians.html#Rimu.Hamiltonians.continuum_dispersion","page":"Hamiltonians","title":"Rimu.Hamiltonians.continuum_dispersion","text":"continuum_dispersion(t, k)\n\nDispersion relation for HubbardMom1D. Returns Re(t) k^2 - 2 Im(t) k.\n\nSee also hubbard_dispersion.\n\n\n\n\n\n","category":"function"},{"location":"hamiltonians.html#Rimu.Hamiltonians.shift_lattice","page":"Hamiltonians","title":"Rimu.Hamiltonians.shift_lattice","text":"shift_lattice(is)\n\nCircular shift contiguous indices is in interval [M÷2, M÷2) such that set starts with 0, where M=length(is).\n\nInverse operation: shift_lattice_inv. Used in HubbardReal1DEP and HubbardMom1DEP\n\n\n\n\n\n","category":"function"},{"location":"hamiltonians.html#Rimu.Hamiltonians.shift_lattice_inv","page":"Hamiltonians","title":"Rimu.Hamiltonians.shift_lattice_inv","text":"shift_lattice_inv(js)\n\nCircular shift indices starting with 0 into a contiguous set in interval [M÷2, M÷2), where M=length(js).\n\nInverse operation of shift_lattice. Used in HubbardReal1DEP and HubbardMom1DEP\n\n\n\n\n\n","category":"function"},{"location":"hamiltonians.html#Hamiltonian-wrappers","page":"Hamiltonians","title":"Hamiltonian wrappers","text":"","category":"section"},{"location":"hamiltonians.html","page":"Hamiltonians","title":"Hamiltonians","text":"The following Hamiltonians are constructed from an existing Hamiltonian instance and change its behaviour:","category":"page"},{"location":"hamiltonians.html","page":"Hamiltonians","title":"Hamiltonians","text":"GutzwillerSampling\nGuidingVectorSampling\nParitySymmetry\nTimeReversalSymmetry\nStoquastic","category":"page"},{"location":"hamiltonians.html#Rimu.Hamiltonians.GutzwillerSampling","page":"Hamiltonians","title":"Rimu.Hamiltonians.GutzwillerSampling","text":"GutzwillerSampling(::AbstractHamiltonian; g)\n\nWrapper over any AbstractHamiltonian that implements Gutzwiller sampling. In this importance sampling scheme the Hamiltonian is modified as follows\n\ntildeH_ij = H_ij e^-g(H_ii - H_jj) \n\nThis way off-diagonal spawns to higher-energy configurations are discouraged and spawns to lower-energy configurations encouraged for positive g.\n\nConstructor\n\nGutzwillerSampling(::AbstractHamiltonian, g)\nGutzwillerSampling(::AbstractHamiltonian; g)\n\nAfter construction, we can access the underlying Hamiltonian with G.hamiltonian and the g parameter with G.g.\n\nExample\n\njulia> H = HubbardMom1D(BoseFS(1,1,1); u=6.0, t=1.0)\nHubbardMom1D(fs\"|1 1 1⟩\"; u=6.0, t=1.0)\n\njulia> G = GutzwillerSampling(H, g=0.3)\nGutzwillerSampling(HubbardMom1D(fs\"|1 1 1⟩\"; u=6.0, t=1.0); g=0.3)\n\njulia> get_offdiagonal(H, BoseFS(2, 1, 0), 1)\n(BoseFS{3,3}(1, 0, 2), 2.0)\n\njulia> get_offdiagonal(G, BoseFS(2, 1, 0), 1)\n(BoseFS{3,3}(1, 0, 2), 0.8131393194811987)\n\nObservables\n\nTo calculate observables, pass the transformed Hamiltonian G to AllOverlaps with keyword argument transform=G.\n\n\n\n\n\n","category":"type"},{"location":"hamiltonians.html#Rimu.Hamiltonians.GuidingVectorSampling","page":"Hamiltonians","title":"Rimu.Hamiltonians.GuidingVectorSampling","text":"GuidingVectorSampling\n\nWrapper over any AbstractHamiltonian that implements guided vector a.k.a. guided wave function sampling. In this importance sampling scheme the Hamiltonian is modified as follows.\n\ntildeH_ij = v_i H_ij v_j^-1\n\nand where v is the guiding vector. v_i and v_j are also thresholded to avoid dividing by zero (see below).\n\nConstructors\n\nGuidingVectorSampling(::AbstractHamiltonian, vector, eps)\nGuidingVectorSampling(::AbstractHamiltonian; vector, eps)\n\neps is a thresholding parameter used to avoid dividing by zero; all values below eps are set to eps. It is recommended that eps is in the same value range as the guiding vector. The default value is set to eps=norm(v, Inf) * 1e-2\n\nAfter construction, we can access the underlying hamiltonian with G.hamiltonian, the eps parameter with G.eps, and the guiding vector with G.vector.\n\nExample\n\njulia> H = HubbardReal1D(BoseFS(1,1,1); u=6.0, t=1.0);\n\njulia> v = DVec(starting_address(H) => 10; capacity=1);\n\njulia> G = GuidingVectorSampling(H, v, 0.1);\n\njulia> get_offdiagonal(H, starting_address(H), 4)\n(BoseFS{3,3}(2, 0, 1), -1.4142135623730951)\n\njulia> get_offdiagonal(G, starting_address(G), 4)\n(BoseFS{3,3}(2, 0, 1), -0.014142135623730952)\n\nObservables\n\nTo calculate observables, pass the transformed Hamiltonian G to AllOverlaps with keyword argument transform=G.\n\n\n\n\n\n","category":"type"},{"location":"hamiltonians.html#Rimu.Hamiltonians.ParitySymmetry","page":"Hamiltonians","title":"Rimu.Hamiltonians.ParitySymmetry","text":"ParitySymmetry(ham::AbstractHamiltonian{T}; even=true) <: AbstractHamiltonian{T}\n\nImpose even or odd parity on all states and the Hamiltonian ham as controlled by the keyword argument even. Parity symmetry of the Hamiltonian is assumed. For some Hamiltonians, ParitySymmetry reduces the size of the Hilbert space by half.\n\nParitySymmetry performs a unitary transformation, leaving the eigenvalues unchanged and preserving the LOStructure. This is achieved by changing the basis set to states with defined parity. Effectively, a non-even address α is replaced by frac12(α α) for even and odd parity, respectively, where ᾱ == reverse(α).\n\nNotes\n\nThis modifier currently only works on starting_addresss with an odd number of modes.\nFor odd parity, the starting_address of the underlying Hamiltonian cannot be symmetric.\nIf parity is not a symmetry of the Hamiltonian ham then the result is undefined.\nParitySymmetry works by modifying the offdiagonals iterator.\n\njulia> ham = HubbardReal1D(BoseFS(0,2,1))\nHubbardReal1D(fs\"|0 2 1⟩\"; u=1.0, t=1.0)\n\njulia> size(Matrix(ham))\n(10, 10)\n\njulia> size(Matrix(ParitySymmetry(ham)))\n(6, 6)\n\njulia> size(Matrix(ParitySymmetry(ham; odd=true)))\n(4, 4)\n\njulia> eigvals(Matrix(ham))[1] ≈ eigvals(Matrix(ParitySymmetry(ham)))[1]\ntrue\n\nSee also TimeReversalSymmetry.\n\n\n\n\n\n","category":"type"},{"location":"hamiltonians.html#Rimu.Hamiltonians.TimeReversalSymmetry","page":"Hamiltonians","title":"Rimu.Hamiltonians.TimeReversalSymmetry","text":"TimeReversalSymmetry(ham::AbstractHamiltonian{T}; even=true) <: AbstractHamiltonian{T}\n\nImpose even or odd time reversal on all states and the Hamiltonian ham as controlled by the keyword argument even. If time reversal is a symmetry of the Hamiltonian it will block (reducing Hilbert space dimension) preserving the eigenvalues and LOStructure.\n\nNotes\n\nThis modifier only works two component starting_addresses.\nFor odd time reversal symmetry, the starting_address of the underlying Hamiltonian must not be symmetric.\nIf time reversal is not a symmetry of the Hamiltonian ham then the result is undefined.\nTimeReversalSymmetry works by modifying the offdiagonals iterator.\n\njulia> ham = HubbardMom1D(FermiFS2C((1,0,1),(0,1,1)));\n\njulia> size(Matrix(ham))\n(3, 3)\n\njulia> size(Matrix(TimeReversalSymmetry(ham)))\n(2, 2)\n\njulia> size(Matrix(TimeReversalSymmetry(ham, even=false)))\n(1, 1)\n\njulia> eigvals(Matrix(TimeReversalSymmetry(ham)))[1] ≈ eigvals(Matrix(ham))[1]\ntrue\n\nSee also ParitySymmetry.\n\n\n\n\n\n","category":"type"},{"location":"hamiltonians.html#Rimu.Hamiltonians.Stoquastic","page":"Hamiltonians","title":"Rimu.Hamiltonians.Stoquastic","text":"Stoquastic(ham <: AbstractHamiltonian) <: AbstractHamiltonian\n\nA wrapper for an AbstractHamiltonian that replaces all off-diagonal matrix elements v by -abs(v), thus making the new Hamiltonian stoquastic.\n\nA stoquastic Hamiltonian does not have a Monte Carlo sign problem. For a hermitian ham the smallest eigenvalue of Stoquastic(ham) is ≤ the smallest eigenvalue of ham.\n\n\n\n\n\n","category":"type"},{"location":"hamiltonians.html#Observables","page":"Hamiltonians","title":"Observables","text":"","category":"section"},{"location":"hamiltonians.html","page":"Hamiltonians","title":"Hamiltonians","text":"Rimu.jl offers two other supertypes for operators that are less restrictive than AbstractHamiltonian. AbstractObservable and AbstractOperators both can represent a physical observable. Their expectation values can be sampled during a ProjectorMonteCarloProblem simulation by passing them into a suitable ReplicaStrategy, e.g. AllOverlaps. Some observables are also AbstractHamiltonians. The full type hierarchy is","category":"page"},{"location":"hamiltonians.html","page":"Hamiltonians","title":"Hamiltonians","text":"AbstractHamiltonian{T} <: AbstractOperator{T} <: AbstractObservable{T}","category":"page"},{"location":"hamiltonians.html","page":"Hamiltonians","title":"Hamiltonians","text":"ParticleNumberOperator\nG2RealCorrelator\nG2RealSpace\nG2MomCorrelator\nSuperfluidCorrelator\nStringCorrelator\nDensityMatrixDiagonal\nSingleParticleExcitation\nTwoParticleExcitation\nReducedDensityMatrix\nMomentum\nAxialAngularMomentumHO","category":"page"},{"location":"hamiltonians.html#Rimu.Hamiltonians.ParticleNumberOperator","page":"Hamiltonians","title":"Rimu.Hamiltonians.ParticleNumberOperator","text":"ParticleNumberOperator() <: AbstractOperator{Float64}\n\nThe number operator in Fock space. This operator is diagonal in the Fock basis and returns the number of particles in the Fock state. It works with any address type that is a subtype of AbstractFockAddress.\n\njulia> p = ExactDiagonalizationProblem(FroehlichPolaron(fs\"|0 0⟩{}\"; mode_cutoff=5, v=3));\n\njulia> gs = solve(p).vectors[1]; # normalised ground state vector\n\njulia> dot(gs, ParticleNumberOperator(), gs) # particle number expectation value\n2.8823297252925917\n\nSee also AbstractHamiltonian.\n\n\n\n\n\n","category":"type"},{"location":"hamiltonians.html#Rimu.Hamiltonians.G2RealCorrelator","page":"Hamiltonians","title":"Rimu.Hamiltonians.G2RealCorrelator","text":"G2RealCorrelator(d::Int) <: AbstractOperator{Float64}\n\nTwo-body operator for density-density correlation between sites separated by d with 0 ≤ d < M.\n\n hatG^(2)(d) = frac1M sum_i^M hatn_i (hatn_i+d - delta_0d)\n\nAssumes a one-dimensional lattice with periodic boundary conditions where\n\n hatG^(2)(-M2 leq d 0) = hatG^(2)(d)\n\n hatG^(2)(M2 d M) = hatG^(2)(M - d)\n\nand normalisation\n\n sum_d=0^M-1 langle hatG^(2)(d) rangle = fracN (N-1)M\n\nFor multicomponent basis, calculates correlations between all particles equally, equivalent to stacking all components into a single Fock state.\n\nArguments\n\nd::Integer: distance between sites.\n\nSee also\n\nHubbardReal1D\nG2RealSpace\nG2MomCorrelator\nAbstractOperator\nAllOverlaps\n\n\n\n\n\n","category":"type"},{"location":"hamiltonians.html#Rimu.Hamiltonians.G2RealSpace","page":"Hamiltonians","title":"Rimu.Hamiltonians.G2RealSpace","text":"G2RealSpace(geometry::CubicGrid, σ=1, τ=1; sum_components=false) <: AbstractOperator{SArray}\n\nTwo-body operator for density-density correlation for all Displacements d in the specified geometry.\n\n hatG^(2)_στ(d) = frac1M _i n_σi (n_τi+d - δ_0dδ_στ)\n\nFor multicomponent addresses, σ and τ control the components involved. Alternatively, sum_components can be set to true, which treats all particles as belonging to the same component.\n\nExamples\n\njulia> geom = CubicGrid(2, 2);\n\njulia> g2 = G2RealSpace(geom)\nG2RealSpace(CubicGrid((2, 2), (true, true)), 1,1)\n\njulia> diagonal_element(g2, BoseFS(2,0,1,1))\n2×2 StaticArraysCore.SMatrix{2, 2, Float64, 4} with indices SOneTo(2)×SOneTo(2):\n 0.5 1.0\n 0.5 1.0\n\njulia> g2_cross = G2RealSpace(geom, 1, 2)\nG2RealSpace(CubicGrid((2, 2), (true, true)), 1,2)\n\njulia> g2_sum = G2RealSpace(geom, sum_components=true)\nG2RealSpace(CubicGrid((2, 2), (true, true)); sum_components=true)\n\njulia> diagonal_element(g2, fs\"|⇅⋅↓↑⟩\")\n2×2 StaticArraysCore.SMatrix{2, 2, Float64, 4} with indices SOneTo(2)×SOneTo(2):\n 0.0 0.0\n 0.0 0.5\n\njulia> diagonal_element(g2_cross, fs\"|⇅⋅↓↑⟩\")\n2×2 StaticArraysCore.SMatrix{2, 2, Float64, 4} with indices SOneTo(2)×SOneTo(2):\n 0.25 0.25\n 0.25 0.25\n\njulia> diagonal_element(g2_sum, fs\"|⇅⋅↓↑⟩\")\n2×2 StaticArraysCore.SMatrix{2, 2, Float64, 4} with indices SOneTo(2)×SOneTo(2):\n 0.5 1.0\n 0.5 1.0\n\nSee also\n\nCubicGrid\nHubbardRealSpace\nG2RealCorrelator\nG2MomCorrelator\nAbstractOperator\nAllOverlaps\n\n\n\n\n\n","category":"type"},{"location":"hamiltonians.html#Rimu.Hamiltonians.G2MomCorrelator","page":"Hamiltonians","title":"Rimu.Hamiltonians.G2MomCorrelator","text":"G2MomCorrelator(d::Int) <: AbstractOperator{ComplexF64}\n\nTwo-body correlation operator representing the density-density correlation at distance d. It returns a Complex value.\n\nCorrelation within a single component:\n\nhatG^(2)(d) = frac1Msum_spqr=1^M e^-id(p-q)2πM a^_s a^_p a_q a_r δ_s+pq+r\n\nThe diagonal element, where (p-q)=0, is\n\nfrac1Msum_kp=1^M a^_k b^_p b_p a_k \n\nArguments\n\nd::Integer: the distance between two particles.\n\nSee also\n\nRimu.G2RealCorrelator\nRimu.G2RealSpace\nRimu.AbstractOperator\nRimu.AllOverlaps\n\n\n\n\n\n","category":"type"},{"location":"hamiltonians.html#Rimu.Hamiltonians.SuperfluidCorrelator","page":"Hamiltonians","title":"Rimu.Hamiltonians.SuperfluidCorrelator","text":"SuperfluidCorrelator(d::Int) <: AbstractOperator{Float64}\n\nOperator for extracting superfluid correlation between sites separated by a distance d with 0 ≤ d < M:\n\n hatC_textSF(d) = frac1M sum_i^M a_i^dagger a_i + d\n\nAssumes a one-dimensional lattice with M sites and periodic boundary conditions. M is also the number of modes in the Fock state address.\n\nUsage\n\nSuperfluid correlations can be extracted from a Monte Carlo calculation by wrapping SuperfluidCorrelator with AllOverlaps and passing into ProjectorMonteCarloProblem with the replica keyword argument. For an example with a similar use of G2RealCorrelator see G2 Correlator Example.\n\nSee also HubbardReal1D, G2RealCorrelator, AbstractOperator, and AllOverlaps.\n\n\n\n\n\n","category":"type"},{"location":"hamiltonians.html#Rimu.Hamiltonians.StringCorrelator","page":"Hamiltonians","title":"Rimu.Hamiltonians.StringCorrelator","text":"StringCorrelator(d::Int; address=nothing, type=nothing) <: AbstractOperator{T}\n\nOperator for extracting string correlation between lattice sites on a one-dimensional Hubbard lattice separated by a distance d with 0 ≤ d < M\n\n C_textstring(d) = frac1M sum_j^M δ n_j\n (e^i π sum_j k j + d δ n_k) δ n_j+d\n\nHere, δ n_j = n_j - n is the boson number deviation from the mean filling number and n = NM is the mean filling number of lattice sites with N particles and M lattice sites (or modes).\n\nAssumes a one-dimensional lattice with periodic boundary conditions. For usage see SuperfluidCorrelator and AllOverlaps.\n\nThe default element type T is ComplexF64. This can be overridden with the type keyword argument. If an address is provided, then T is calculated from the address type. It is set to ComplexF64 for non-integer filling numbers, and to Float64 for integer filling numbers or if d==0.\n\nSee also HubbardReal1D, G2RealCorrelator, SuperfluidCorrelator, AbstractOperator, and AllOverlaps.\n\n\n\n\n\n","category":"type"},{"location":"hamiltonians.html#Rimu.Hamiltonians.DensityMatrixDiagonal","page":"Hamiltonians","title":"Rimu.Hamiltonians.DensityMatrixDiagonal","text":"DensityMatrixDiagonal(mode; component=0) <: AbstractHamiltonian\n\nRepresent a diagonal element of the single-particle density:\n\nhatn_iσ = hat a^_iσ hat a_iσ\n\nwhere i is the mode and σ is the component. If component is zero, the sum over all components is computed.\n\nSee also\n\nsingle_particle_density\nSingleParticleDensity\nSingleParticleExcitation\n\n\n\n\n\n","category":"type"},{"location":"hamiltonians.html#Rimu.Hamiltonians.SingleParticleExcitation","page":"Hamiltonians","title":"Rimu.Hamiltonians.SingleParticleExcitation","text":"SingleParticleExcitation(i, j) <: AbstractOperator\n\nRepresent the ij element of the single-particle reduced density matrix:\n\nρ^(1)_ij = a^_i a_j\n\nwhere i <: Int and j <: Int specify the mode numbers.\n\nSee also\n\nsingle_particle_density\nSingleParticleDensity\nTwoParticleExcitation\n\n\n\n\n\n","category":"type"},{"location":"hamiltonians.html#Rimu.Hamiltonians.TwoParticleExcitation","page":"Hamiltonians","title":"Rimu.Hamiltonians.TwoParticleExcitation","text":"TwoParticleExcitation(i, j, k, l) <: AbstractOperator\n\nRepresent the ij kl element of the two-particle reduced density matrix:\n\nρ^(2)_ij kl = a^_i a^_j a_l a_k\n\nwhere i, j, k, and l (all <: Int) specify the mode numbers.\n\nSee also\n\nsingle_particle_density\nSingleParticleDensity\nSingleParticleExcitation\n\n\n\n\n\n","category":"type"},{"location":"hamiltonians.html#Rimu.Hamiltonians.ReducedDensityMatrix","page":"Hamiltonians","title":"Rimu.Hamiltonians.ReducedDensityMatrix","text":"ReducedDensityMatrix{T=Float64}(p) <: AbstractObservable{Hermitian{T, Matrix{T}}}\n\nA matrix-valued operator that can be used to calculate the p-particle reduced density matrix. The matrix elements are defined as:\n\nhatρ^(p)_j_1j_1k_1k_p = prod_i=1^p a^_j_i prod_l=p^1 a_k_l\n\nThe integer indices j_i and k_i represent single particle modes. For efficiency they are chosen to be distinct and ordered:\n\nj_1 j_2 ldots j_p quad land quad k_1 k_2 ldots k_p\n\nReducedDensityMatrix can be used to construct the single-particle reduced density matrix (with p == 1) for fermionic and bosonic Fock spaces with address types <: SingleComponentFockAddress. For higher order reduced density matrices with p > 1 only fermionic Fock addresses (FermiFS) are supported due to the ordering of indices.\n\nReducedDensityMatrix can be used with dot or AllOverlaps to calculate the whole matrix in one go.\n\nExamples\n\njulia> dvec_b = PDVec(BoseFS(1,1) => 0.5, BoseFS(2,0) => 0.5)\n2-element PDVec: style = IsDeterministic{Float64}()\n fs\"|2 0⟩\" => 0.5\n fs\"|1 1⟩\" => 0.5\n\njulia> Op1 = ReducedDensityMatrix(1)\nReducedDensityMatrix{Float64}(1)\n\njulia> dot(dvec_b, Op1, dvec_b)\n2×2 Hermitian{Float64, Matrix{Float64}}:\n 0.75 0.353553\n 0.353553 0.25\n\njulia> Op2 = ReducedDensityMatrix{Float32}(2)\nReducedDensityMatrix{Float32}(2)\n\njulia> dot(dvec_b, Op2, dvec_b)\nERROR: ArgumentError: ReducedDensityMatrix(p) with `p > 1` requires `FermiFS` addresses\n\njulia> dvec_f = PDVec(FermiFS(1,1,0,0) => 0.5, FermiFS(0,1,1,0) => 0.5)\n2-element PDVec: style = IsDeterministic{Float64}()\n fs\"|⋅↑↑⋅⟩\" => 0.5\n fs\"|↑↑⋅⋅⟩\" => 0.5\n\njulia> dot(dvec_f, Op2, dvec_f)\n6×6 Hermitian{Float32, Matrix{Float32}}:\n 0.25 0.0 0.25 0.0 0.0 0.0\n 0.0 0.0 0.0 0.0 0.0 0.0\n 0.25 0.0 0.25 0.0 0.0 0.0\n 0.0 0.0 0.0 0.0 0.0 0.0\n 0.0 0.0 0.0 0.0 0.0 0.0\n 0.0 0.0 0.0 0.0 0.0 0.0\n\nSee also single_particle_density, SingleParticleDensity, SingleParticleExcitation, TwoParticleExcitation.\n\n\n\n\n\n","category":"type"},{"location":"hamiltonians.html#Rimu.Hamiltonians.Momentum","page":"Hamiltonians","title":"Rimu.Hamiltonians.Momentum","text":"Momentum(component=0; fold=true) <: AbstractHamiltonian\n\nThe momentum operator P.\n\nThe component argument controls which component of the address is taken into consideration. A value of 0 sums the contributions of all components. If fold is true, the momentum is folded into the Brillouin zone.\n\njulia> address = BoseFS((1, 0, 2, 1, 2, 1, 1, 3))\nBoseFS{11,8}(1, 0, 2, 1, 2, 1, 1, 3)\n\njulia> v = DVec(address => 10);\n\njulia> rayleigh_quotient(Momentum(), DVec(address => 1))\n-2.0\n\njulia> rayleigh_quotient(Momentum(fold=false), DVec(address => 1))\n14.0\n\n\n\n\n\n","category":"type"},{"location":"hamiltonians.html#Rimu.Hamiltonians.AxialAngularMomentumHO","page":"Hamiltonians","title":"Rimu.Hamiltonians.AxialAngularMomentumHO","text":"AxialAngularMomentumHO(S; z_dim = 3, addr = BoseFS(prod(S))) <: AbstractHamiltonian\n\nAngular momentum operator for application to Cartesian harmonic oscillator basis, see HOCartesianContactInteractions or HOCartesianEnergyConservedPerDim. Represents the projection of angular momentum onto z-axis:\n\nhatL_z = i hbar sum_j=1^N left( b_x b_y^dag - b_y b_x^dag right)\n\nwhere b_x^dag and b_x are raising and lowering (ladder) operators for a harmonic oscillator in the x dimension, and simlarly for y.\n\nThis is implemented for an N particle Fock space with creation and annihilation operators as\n\nfrac1hbar hatL_z = i sum_n_x=1^M_x sum_n_y=1^M_y\n left( a_n_x-1n_y+1^dag - a_n_x+1n_y-1^dag right) a_n_x n_y\n\nin units of hbar.\n\nArgument S is a tuple defining the range of Cartesian modes in each dimension and their mapping to Fock space modes in a SingleComponentFockAddress. If S indicates a 3D system the z dimension can be changed by setting z_dim; S should be be isotropic in the remaining x-y plane, i.e. must have S[x_dim] == S[y_dim]. The starting address addr only needs to satisfy num_modes(addr) == prod(S).\n\nExample\n\nCalculate the overlap of two Fock addresses interpreted as harmonic oscillator states in a 2D Cartesian basis\n\njulia> S = (2,2)\n(2, 2)\n\njulia> Lz = AxialAngularMomentumHO(S)\nAxialAngularMomentumHO((2, 2); z_dim = 3, addr = BoseFS{0,4}(0, 0, 0, 0))\n\njulia> v = DVec(BoseFS(prod(S), 2 => 1) => 1.0)\nDVec{BoseFS{1, 4, BitString{4, 1, UInt8}},Float64} with 1 entry, style = IsDeterministic{Float64}()\n fs\"|0 1 0 0⟩\" => 1.0\n\njulia> w = DVec(BoseFS(prod(S), 3 => 1) => 1.0)\nDVec{BoseFS{1, 4, BitString{4, 1, UInt8}},Float64} with 1 entry, style = IsDeterministic{Float64}()\n fs\"|0 0 1 0⟩\" => 1.0\n\njulia> dot(w, Lz, v)\n0.0 + 1.0im\n\n\n\n\n\n","category":"type"},{"location":"hamiltonians.html#Geometry","page":"Hamiltonians","title":"Geometry","text":"","category":"section"},{"location":"hamiltonians.html","page":"Hamiltonians","title":"Hamiltonians","text":"Lattices in higher dimensions are defined here and can be passed with the keyword argument geometry to HubbardRealSpace and G2RealSpace.","category":"page"},{"location":"hamiltonians.html","page":"Hamiltonians","title":"Hamiltonians","text":"CubicGrid\nHamiltonians.Directions\nHamiltonians.Displacements\nHamiltonians.neighbor_site\nPeriodicBoundaries\nHardwallBoundaries\nLadderBoundaries","category":"page"},{"location":"hamiltonians.html#Rimu.Hamiltonians.CubicGrid","page":"Hamiltonians","title":"Rimu.Hamiltonians.CubicGrid","text":"CubicGrid(dims::NTuple{D,Int}, fold::NTuple{D,Bool})\n\nRepresents a D-dimensional grid. Used to define a cubic lattice and boundary conditions for some AbstractHamiltonians, e.g. with the keyword argument geometry when constructing a HubbardRealSpace. The type instance can be used to convert between cartesian vector indices (tuples or SVectors) and linear indices (integers). When indexed with vectors, it folds them back into the grid if the out-of-bounds dimension is periodic and 0 otherwise (see example below).\n\ndims controls the size of the grid in each dimension.\nfold controls whether the boundaries in each dimension are periodic (or folded in the case of momentum space).\n\njulia> geo = CubicGrid((2,3), (true,false))\nCubicGrid{2}((2, 3), (true, false))\n\njulia> geo[1]\n(1, 1)\n\njulia> geo[2]\n(2, 1)\n\njulia> geo[3]\n(1, 2)\n\njulia> geo[(1,2)]\n3\n\njulia> geo[(3,2)] # 3 is folded back into 1\n3\n\njulia> geo[(3,3)]\n5\n\njulia> geo[(3,4)] # returns 0 if out of bounds\n0\n\nSee also PeriodicBoundaries, HardwallBoundaries and LadderBoundaries for special-case constructors. See also HubbardRealSpace and G2RealSpace.\n\n\n\n\n\n","category":"type"},{"location":"hamiltonians.html#Rimu.Hamiltonians.Directions","page":"Hamiltonians","title":"Rimu.Hamiltonians.Directions","text":"Directions(D) <: AbstractVector{SVector{D,Int}}\nDirections(geometry::CubicGrid) <: AbstractVector{SVector{D,Int}}\n\nIterate over axis-aligned direction vectors in D dimensions.\n\njulia> Directions(3)\n6-element Directions{3}:\n [1, 0, 0]\n [0, 1, 0]\n [0, 0, 1]\n [-1, 0, 0]\n [0, -1, 0]\n [0, 0, -1]\n\n\nSee also CubicGrid.\n\n\n\n\n\n","category":"type"},{"location":"hamiltonians.html#Rimu.Hamiltonians.Displacements","page":"Hamiltonians","title":"Rimu.Hamiltonians.Displacements","text":"Displacements(geometry::CubicGrid) <: AbstractVector{SVector{D,Int}}\n\nReturn all valid offset vectors in a CubicGrid. If center=true the (0,0) displacement is placed at the centre of the array.\n\njulia> geometry = CubicGrid((3,4));\n\njulia> reshape(Displacements(geometry), (3,4))\n3×4 reshape(::Displacements{2, CubicGrid{2, (3, 4), (true, true)}}, 3, 4) with eltype StaticArraysCore.SVector{2, Int64}:\n [0, 0] [0, 1] [0, 2] [0, 3]\n [1, 0] [1, 1] [1, 2] [1, 3]\n [2, 0] [2, 1] [2, 2] [2, 3]\n\njulia> reshape(Displacements(geometry; center=true), (3,4))\n3×4 reshape(::Displacements{2, CubicGrid{2, (3, 4), (true, true)}}, 3, 4) with eltype StaticArraysCore.SVector{2, Int64}:\n [-1, -1] [-1, 0] [-1, 1] [-1, 2]\n [0, -1] [0, 0] [0, 1] [0, 2]\n [1, -1] [1, 0] [1, 1] [1, 2]\n\n\n\n\n\n\n","category":"type"},{"location":"hamiltonians.html#Rimu.Hamiltonians.neighbor_site","page":"Hamiltonians","title":"Rimu.Hamiltonians.neighbor_site","text":"neighbor_site(geom::CubicGrid, site, i)\n\nFind the i-th neighbor of site in the geometry. If the move is illegal, return 0.\n\nSee also CubicGrid.\n\n\n\n\n\n","category":"function"},{"location":"hamiltonians.html#Rimu.Hamiltonians.PeriodicBoundaries","page":"Hamiltonians","title":"Rimu.Hamiltonians.PeriodicBoundaries","text":"PeriodicBoundaries(dims...) -> CubicGrid\nPeriodicBoundaries(dims) -> CubicGrid\n\nReturn a CubicGrid with all dimensions periodic. Equivalent to CubicGrid(dims).\n\n\n\n\n\n","category":"function"},{"location":"hamiltonians.html#Rimu.Hamiltonians.HardwallBoundaries","page":"Hamiltonians","title":"Rimu.Hamiltonians.HardwallBoundaries","text":"HardwallBoundaries(dims...) -> CubicGrid\nHardwallBoundaries(dims) -> CubicGrid\n\nReturn a CubicGrid with all dimensions non-periodic. Equivalent to CubicGrid(dims, (false, false, ...)).\n\n\n\n\n\n","category":"function"},{"location":"hamiltonians.html#Rimu.Hamiltonians.LadderBoundaries","page":"Hamiltonians","title":"Rimu.Hamiltonians.LadderBoundaries","text":"LadderBoundaries(dims...) -> CubicGrid\nLadderBoundaries(dims) -> CubicGrid\n\nReturn a CubicGrid where the first dimension is dimensions non-periodic and the rest are periodic. Equivalent to CubicGrid(dims, (true, false, ...)).\n\n\n\n\n\n","category":"function"},{"location":"hamiltonians.html#Index","page":"Hamiltonians","title":"Index","text":"","category":"section"},{"location":"hamiltonians.html","page":"Hamiltonians","title":"Hamiltonians","text":"Pages = [\"hamiltonians.md\"]","category":"page"},{"location":"testing.html#Code-testing","page":"Code testing","title":"Code testing","text":"","category":"section"},{"location":"testing.html","page":"Code testing","title":"Code testing","text":"The script runtest.jl in the test/ folder contains tests of the code in Rimu. To run the test simply run the script from the Julia REPL or run","category":"page"},{"location":"testing.html","page":"Code testing","title":"Code testing","text":"Rimu$ julia test/runtest.jl","category":"page"},{"location":"testing.html","page":"Code testing","title":"Code testing","text":"from the command line.","category":"page"},{"location":"testing.html","page":"Code testing","title":"Code testing","text":"More tests should be added over time to test core functionality of the code. To add new tests, directly edit the file runtest.jl.","category":"page"},{"location":"testing.html#Automated-testing-with-GitHub-Actions","page":"Code testing","title":"Automated testing with GitHub Actions","text":"","category":"section"},{"location":"testing.html","page":"Code testing","title":"Code testing","text":"GitHub Actions are set up to run the test script automatically on the GitHub cloud server every time a new commit to the master branch is pushed to the server. The setup for this to happen is configured in the file actions.yml in the Rimu/.github/workflows folder.","category":"page"},{"location":"testing.html#Testing-of-custom-types-for-use-with-Rimu","page":"Code testing","title":"Testing of custom types for use with Rimu","text":"","category":"section"},{"location":"testing.html","page":"Code testing","title":"Code testing","text":"The module Rimu.InterfaceTests contains a number of functions to test the interfaces of the AbstractHamiltonian type hierarchy. See Interface tests in the section Advanced operator usage and custom Hamiltonians.","category":"page"},{"location":"exactdiagonalization.html#Exact-Diagonalization","page":"Exact Diagonalization","title":"Exact Diagonalization","text":"","category":"section"},{"location":"exactdiagonalization.html","page":"Exact Diagonalization","title":"Exact Diagonalization","text":"The main functionality of Rimu for exact diagonalization is contained in the module ExactDiagonalization.","category":"page"},{"location":"exactdiagonalization.html","page":"Exact Diagonalization","title":"Exact Diagonalization","text":"ExactDiagonalization","category":"page"},{"location":"exactdiagonalization.html#Rimu.ExactDiagonalization","page":"Exact Diagonalization","title":"Rimu.ExactDiagonalization","text":"The module Rimu.ExactDiagonalization provides a framework for exact diagonalization of quantum many-body systems defined by an AbstractHamiltonian type.\n\nThe main usage is through defining an ExactDiagonalizationProblem and solving it with the solve function. The module provides a unified interface for accessing different solver algorithms, which make use of solvers provided by external packages.\n\nExports\n\nExactDiagonalizationProblem\nBasisSetRepresentation\nbuild_basis\nKrylovKitSolver\nLinearAlgebraSolver\nArpackSolver\nLOBPCGSolver\n\n\n\n\n\n","category":"module"},{"location":"exactdiagonalization.html#ExactDiagonalizationProblem","page":"Exact Diagonalization","title":"ExactDiagonalizationProblem","text":"","category":"section"},{"location":"exactdiagonalization.html","page":"Exact Diagonalization","title":"Exact Diagonalization","text":"ExactDiagonalizationProblem\nsolve(::ExactDiagonalizationProblem)\ninit(::ExactDiagonalizationProblem)","category":"page"},{"location":"exactdiagonalization.html#Rimu.ExactDiagonalization.ExactDiagonalizationProblem","page":"Exact Diagonalization","title":"Rimu.ExactDiagonalization.ExactDiagonalizationProblem","text":"ExactDiagonalizationProblem(hamiltonian::AbstractHamiltonian, [v0]; kwargs...)\n\nDefines an exact diagonalization problem with an AbstractHamiltonian hamiltonian. Optionally, a starting vector of type AbstractDVec, or a single address or a collection of addresses can be passed as v0.\n\nExactDiagonalizationProblems can be solved with solve.\n\nKeyword arguments\n\nalgorithm=LinearAlgebraSolver(): The algorithm to use for solving the problem. The algorithm can also be specified as the second positional argument in the init function.\nOptional keyword arguments will be passed on to the init and solve functions.\n\nAlgorithms\n\nLinearAlgebraSolver(): An algorithm for solving the problem using the dense-matrix eigensolver from the LinearAlgebra standard library (eventually using LAPACK). Only suitable for small matrices.\nKrylovKitSolver(matrix_free=true): An algorithm for finding a few eigenvalues and vectors. With matrix_free=true the problem is solved without instatiating a matrix. This is suitable for large dimensions. With matrix_free=false the problem is solved after instantiating a sparse matrix. This is faster if sufficient memory is available. Requires using KrylovKit.\nArpackSolver(): An algorithm for solving the problem after instantiating a sparse matrix and using the Arpack Fortran library. Requires using Arpack.\nLOBPCGSolver(): An algorithm for solving the problem after instantiating a sparse matrix using the LOBPCG method. Requires using IterativeSolvers.\n\nKeyword arguments for matrix-based algorithms (also accepted by init)\n\nSee BasisSetRepresentation for more information.\n\nsizelim: The maximum size of the basis set representation. The default is 10^6 for sparse matrices and 10^5 for dense matrices.\ncutoff: A cutoff value for the basis set representation.\nfilter: A filter function for the basis set representation.\nmax_depth = Inf: Limit the depth when building the matrix.\nminimum_size = Inf: Stop building the matrix after this size is reached.\nnnzs = 0: A hint for the number of non-zero elements in the basis set representation. Setting a non-zero value can speed up the computation.\ncol_hint = 0: A hint for the number of columns in the basis set representation.\nsort = false: Whether to sort the basis set representation.\n\nKeyword arguments for iterative algorithms (also accepted by solve)\n\nverbose = false: Whether to print additional information.\nabstol = nothing: The absolute tolerance for the solver. If nothing, the solver chooses a default value.\nhowmany = 1: The minimum number of eigenvalues to compute.\nwhich = :SR: Whether to compute the largest or smallest eigenvalues.\nmaxiters = nothing: The maximum number of iterations for the solver. If nothing, the solver chooses a default value.\n\nSolving an ExactDiagonalizationProblem\n\nThe solve function can be called directly on an ExactDiagonalizationProblem to solve it. Alternatively, the init function can be used to initialize a solver, which can then be solved with solve. The solve function returns a result type with the eigenvalues, eigenvectors, and convergence information.\n\nResult type\n\nThe result type for the solve function is determined by the algorithm used. It has the following fields:\n\nvalues::Vector: The eigenvalues.\nvectors::Vector{<:AbstractDVec}: The eigenvectors.\nsuccess::Bool: A boolean flag indicating whether the solver was successful.\ninfo: Convergence information.\nalgorithm: The algorithm used for the computation.\nproblem: The ExactDiagonalizationProblem that was solved.\nAdditional fields may be present depending on the algorithm used.\n\nIterating the result type will yield the eigenvalues, eigenvectors, and a boolean flag success in that order.\n\nExamples\n\njulia> p = ExactDiagonalizationProblem(HubbardReal1D(BoseFS(1,1,1)))\nExactDiagonalizationProblem(\n HubbardReal1D(fs\"|1 1 1⟩\"; u=1.0, t=1.0),\n nothing;\n NamedTuple()...\n)\n\njulia> result = solve(p) # convert to dense matrix and solve with LinearAlgebra.eigen\nEDResult for algorithm LinearAlgebraSolver() with 10 eigenvalue(s),\n values = [-5.09593, -1.51882, -1.51882, 1.55611, 1.6093, 1.6093, 4.0, 4.53982, 4.90952, 4.90952],\n and vectors of length 10.\n Convergence info: \"Dense matrix eigensolver solution from `LinearAlgebra.eigen`\", with howmany = 10 eigenvalues requested.\n success = true.\n\njulia> using KrylovKit # an external package has to be installed and loaded\n\njulia> s = init(p; algorithm = KrylovKitSolver(true)) # solve without building a matrix\nKrylovKitDirectEDSolver\n with algorithm KrylovKitSolver(matrix_free = true,) for hamiltonian = HubbardReal1D(fs\"|1 1 1⟩\"; u=1.0, t=1.0),\n v0 = 1-element PDVec: style = IsDeterministic{Float64}()\n fs\"|1 1 1⟩\" => 1.0,\n kwargs = NamedTuple()\n)\n\njulia> values, vectors, success = solve(s);\n\njulia> result.values[1] ≈ values[1]\ntrue\n\nSee also solve(::ExactDiagonalizationProblem), init(::ExactDiagonalizationProblem), KrylovKitSolver, ArpackSolver, LinearAlgebraSolver.\n\nnote: Note\nUsing the KrylovKitSolver() algorithms requires the KrylovKit.jl package. The package can be loaded with using KrylovKit. Using the ArpackSolver() algorithm requires the Arpack.jl package. The package can be loaded with using Arpack. Using the LOBPCGSolver() algorithm requires the IterativeSolvers.jl package. The package can be loaded with using IterativeSolvers.\n\n\n\n\n\n","category":"type"},{"location":"exactdiagonalization.html#CommonSolve.solve-Tuple{ExactDiagonalizationProblem}","page":"Exact Diagonalization","title":"CommonSolve.solve","text":"solve(p::ExactDiagonalizationProblem, [algorithm]; kwargs...)\n\nSolve an ExactDiagonalizationProblem p directly. Optionally specify an algorithm. Returns a result type with the eigenvalues, eigenvectors, and convergence information.\n\nFor a description of the keyword arguments, see the documentation for ExactDiagonalizationProblem.\n\nSee also solve(::ProjectorMonteCarloProblem).\n\n\n\n\n\n","category":"method"},{"location":"exactdiagonalization.html#CommonSolve.init-Tuple{ExactDiagonalizationProblem}","page":"Exact Diagonalization","title":"CommonSolve.init","text":"init(p::ExactDiagonalizationProblem, [algorithm]; kwargs...)\n\nInitialize a solver for an ExactDiagonalizationProblem p with an optional algorithm. Returns a solver instance that can be solved with solve.\n\nFor a description of the keyword arguments, see the documentation for ExactDiagonalizationProblem.\n\n\n\n\n\n","category":"method"},{"location":"exactdiagonalization.html#Solver-algorithms","page":"Exact Diagonalization","title":"Solver algorithms","text":"","category":"section"},{"location":"exactdiagonalization.html","page":"Exact Diagonalization","title":"Exact Diagonalization","text":"KrylovKitSolver\nLinearAlgebraSolver\nArpackSolver\nLOBPCGSolver","category":"page"},{"location":"exactdiagonalization.html#Rimu.ExactDiagonalization.KrylovKitSolver","page":"Exact Diagonalization","title":"Rimu.ExactDiagonalization.KrylovKitSolver","text":"KrylovKitSolver(matrix_free::Bool; kwargs...)\nKrylovKitSolver(; matrix_free = false, kwargs...)\n\nAlgorithm for solving a large ExactDiagonalizationProblem to find a few eigenvalues and vectors using the KrylovKit.jl package. The Lanczos method is used for hermitian matrices, and the Arnoldi method is used for non-hermitian matrices.\n\nArguments\n\nmatrix_free = false: Whether to use a matrix-free algorithm. If false, a sparse matrix will be instantiated. This is typically faster and recommended for small matrices, but requires more memory. If true, the matrix is not instantiated, which is useful for large matrices that would not fit into memory. The calculation will parallelise using threading and MPI if available by making use of PDVec.\nkwargs: Additional keyword arguments are passed on to the function KrylovKit.eigsolve().\n\nSee also ExactDiagonalizationProblem, solve.\n\nnote: Note\nRequires the KrylovKit.jl package to be loaded with using KrylovKit.\n\n\n\n\n\n","category":"type"},{"location":"exactdiagonalization.html#Rimu.ExactDiagonalization.LinearAlgebraSolver","page":"Exact Diagonalization","title":"Rimu.ExactDiagonalization.LinearAlgebraSolver","text":"LinearAlgebraSolver(; kwargs...)\n\nAlgorithm for solving an ExactDiagonalizationProblem using the dense-matrix eigensolver from the LinearAlgebra standard library. This is only suitable for small matrices.\n\nThe kwargs are passed on to function LinearAlgebra.eigen.\n\nKeyword arguments\n\npermute = true: Whether to permute the matrix before diagonalization.\nscale = true: Whether to scale the matrix before diagonalization.\nsortby: The sorting order for the eigenvalues.\n\nSee also ExactDiagonalizationProblem, solve.\n\n\n\n\n\n","category":"type"},{"location":"exactdiagonalization.html#Rimu.ExactDiagonalization.ArpackSolver","page":"Exact Diagonalization","title":"Rimu.ExactDiagonalization.ArpackSolver","text":"ArpackSolver(; kwargs...)\n\nAlgorithm for solving an ExactDiagonalizationProblem after instantiating a sparse matrix. It uses the Lanzcos method for hermitian problems, and the Arnoldi method for non-hermitian problems, using the Arpack Fortran library. This is faster than KrylovKitSolver(; matrix_free=true), but it requires more memory and will only be useful if the matrix fits into memory.\n\nThe kwargs are passed on to the function Arpack.eigs().\n\nSee also ExactDiagonalizationProblem, solve.\n\nnote: Note\nRequires the Arpack.jl package to be loaded with using Arpack.\n\n\n\n\n\n","category":"type"},{"location":"exactdiagonalization.html#Rimu.ExactDiagonalization.LOBPCGSolver","page":"Exact Diagonalization","title":"Rimu.ExactDiagonalization.LOBPCGSolver","text":"LOBPCGSolver(; kwargs...)\n\nThe Locally Optimal Block Preconditioned Conjugate Gradient Method (LOBPCG). Algorithm for solving an ExactDiagonalizationProblem after instantiating a sparse matrix.\n\nLOBPCG is not suitable for non-hermitian eigenvalue problems.\n\nThe kwargs are passed on to the function IterativeSolvers.lobpcg().\n\nSee also ExactDiagonalizationProblem, solve.\n\nnote: Note\nRequires the IterativeSolvers.jl package to be loaded with using IterativeSolvers.\n\n\n\n\n\n","category":"type"},{"location":"exactdiagonalization.html#Converting-a-Hamiltonian-in-to-a-matrix","page":"Exact Diagonalization","title":"Converting a Hamiltonian in to a matrix","text":"","category":"section"},{"location":"exactdiagonalization.html","page":"Exact Diagonalization","title":"Exact Diagonalization","text":"BasisSetRepresentation\nbuild_basis\nMatrix\nsparse","category":"page"},{"location":"exactdiagonalization.html#Rimu.ExactDiagonalization.BasisSetRepresentation","page":"Exact Diagonalization","title":"Rimu.ExactDiagonalization.BasisSetRepresentation","text":"BasisSetRepresentation(\n hamiltonian::AbstractHamiltonian, addr=starting_address(hamiltonian);\n sizelim=10^7, cutoff, filter, max_depth, minimum_size, sort=false, kwargs...\n)\nBasisSetRepresentation(hamiltonian::AbstractHamiltonian, addresses::AbstractVector; kwargs...)\n\nEagerly construct the basis set representation of the operator hamiltonian with all addresses reachable from addr. Instead of a single address, a vector of addresses can be passed.\n\nAn ArgumentError is thrown if dimension(hamiltonian) > sizelim in order to prevent memory overflow. Set sizelim = Inf in order to disable this behaviour.\n\nProviding the number nnzs of expected calculated matrix elements and col_hint for the estimated number of nonzero off-diagonal matrix elements in each matrix column may improve performance.\n\nProviding an energy cutoff will skip the columns and rows with diagonal elements greater than cutoff. Alternatively, an arbitrary filter function can be used instead. Addresses passed as arguments are not filtered. To generate the matrix truncated to the subspace spanned by the addresses, use filter = Returns(false).\n\nProviding a max_depth will limit the size of the matrix and basis by only visiting addresses that are connected to the starting_address through max_depth hops through the Hamiltonian. Similarly, providing minimum_size will stop the bulding process after the basis reaches a length of at least minimum_size.\n\nSetting sort to true will sort the matrix rows and columns. This is useful when the order of the columns matters, e.g. when comparing matrices. Any additional keyword arguments are passed on to Base.sortperm.\n\nwarning: Warning\nThe order of the returned basis and matrix rows and columns is arbitrary and\nnon-deterministic. Use `sort=true` if the ordering matters.\n\nFields\n\nsparse_matrix: sparse matrix representing hamiltonian in the basis basis\nbasis: vector of addresses\nhamiltonian: the Hamiltonian hamiltonian\n\nExample\n\njulia> hamiltonian = HubbardReal1D(BoseFS(1,0,0));\n\njulia> bsr = BasisSetRepresentation(hamiltonian)\nBasisSetRepresentation(HubbardReal1D(fs\"|1 0 0⟩\"; u=1.0, t=1.0)) with dimension 3 and 6 stored entries:3×3 SparseArrays.SparseMatrixCSC{Float64, Int32} with 6 stored entries:\n ⋅ -1.0 -1.0\n -1.0 ⋅ -1.0\n -1.0 -1.0 ⋅\n\njulia> BasisSetRepresentation(hamiltonian, bsr.basis[1:2]; filter = Returns(false)) # passing addresses and truncating\nBasisSetRepresentation(HubbardReal1D(fs\"|1 0 0⟩\"; u=1.0, t=1.0)) with dimension 2 and 2 stored entries:2×2 SparseArrays.SparseMatrixCSC{Float64, Int32} with 2 stored entries:\n ⋅ -1.0\n -1.0 ⋅\n\njulia> using LinearAlgebra; round.(eigvals(Matrix(bsr)); digits = 4) # eigenvalues\n3-element Vector{Float64}:\n -2.0\n 1.0\n 1.0\n\njulia> ev = eigvecs(Matrix(bsr))[:,1]; ev = ev .* sign(ev[1]) # ground state eigenvector\n3-element Vector{Float64}:\n 0.5773502691896257\n 0.5773502691896255\n 0.5773502691896257\n\njulia> dv = DVec(zip(bsr.basis, ev)) # ground state as DVec\nDVec{BoseFS{1, 3, BitString{3, 1, UInt8}},Float64} with 3 entries, style = IsDeterministic{Float64}()\n fs\"|0 0 1⟩\" => 0.57735\n fs\"|0 1 0⟩\" => 0.57735\n fs\"|1 0 0⟩\" => 0.57735\n\nHas methods for dimension, sparse, Matrix, starting_address.\n\nPart of the AbstractHamiltonian interface. See also build_basis.\n\n\n\n\n\n","category":"type"},{"location":"exactdiagonalization.html#Rimu.ExactDiagonalization.build_basis","page":"Exact Diagonalization","title":"Rimu.ExactDiagonalization.build_basis","text":"build_basis(\n ham, address=starting_address(ham);\n cutoff, filter, sizelim, sort=false, kwargs...\n) -> basis\nbuild_basis(ham, addresses::AbstractVector; kwargs...)\n\nGet all basis element of a linear operator ham that are reachable (via non-zero matrix elements) from the address address, returned as a vector. Instead of a single address, a vector of addresses can be passed. Does not return the matrix, for that purpose use BasisSetRepresentation.\n\nProviding an energy cutoff will skip addresses with diagonal elements greater than cutoff. Alternatively, an arbitrary filter function can be used instead. Addresses passed as arguments are not filtered.\n\nProviding a max_depth will limit the size of the basis by only visiting addresses that are connected to the starting_address through max_depth hops through the Hamiltonian. Similarly, providing minimum_size will stop the bulding process after the basis reaches a length of at least minimum_size.\n\nA maximum basis size sizelim can be set which will throw an error if the expected dimension of ham is larger than sizelim. This may be useful when memory may be a concern. These options are disabled by default.\n\nwarning: Warning\nThe order the basis is returned in is arbitrary and non-deterministic. Use\n`sort=true` if the ordering matters.\n\n\n\n\n\nbuild_basis(addr::AbstractFockAddress)\nbuild_basis(::Type{<:AbstractFockAddress}) -> basis\n\nReturn all possible Fock states of a given type as a vector. This method is much faster than build_basis(::AbstractHamiltonian, ...), but does not take matrix blocking into account. This version of build_basis accepts no additional arguments.\n\nAll address types except OccupationNumberFS are supported.\n\nReturns a sorted vector of length equal to the dimension of addr.\n\nSee also AbstractFockAddress.\n\n\n\n\n\n","category":"function"},{"location":"exactdiagonalization.html#Base.Matrix","page":"Exact Diagonalization","title":"Base.Matrix","text":"Matrix(\n hamiltonian::AbstractHamiltonian, addr=starting_address(hamiltonian);\n sizelim=10^4, kwargs...\n)\nMatrix(bsr::BasisSetRepresentation)\n\nReturn a dense matrix representation of hamiltonian or bsr. kwargs are passed to BasisSetRepresentation.\n\nSee BasisSetRepresentation.\n\n\n\n\n\n","category":"type"},{"location":"exactdiagonalization.html#SparseArrays.sparse","page":"Exact Diagonalization","title":"SparseArrays.sparse","text":"sparse(hamiltonian::AbstractHamiltonian, addr=starting_address(hamiltonian); kwargs...)\nsparse(bsr::BasisSetRepresentation)\n\nReturn a sparse matrix representation of hamiltonian or bsr. kwargs are passed to BasisSetRepresentation.\n\nSee BasisSetRepresentation.\n\n\n\n\n\n","category":"function"},{"location":"exactdiagonalization.html#Deprecated","page":"Exact Diagonalization","title":"Deprecated","text":"","category":"section"},{"location":"exactdiagonalization.html","page":"Exact Diagonalization","title":"Exact Diagonalization","text":"BasisSetRep","category":"page"},{"location":"exactdiagonalization.html#Rimu.ExactDiagonalization.BasisSetRep","page":"Exact Diagonalization","title":"Rimu.ExactDiagonalization.BasisSetRep","text":"BasisSetRep(args...; kwargs...)\n\nBasisSetRep is deprecated. Use BasisSetRepresentation instead.\n\n\n\n\n\n","category":"function"},{"location":"documentation.html#Documentation-generation","page":"Documentation generation","title":"Documentation generation","text":"","category":"section"},{"location":"documentation.html","page":"Documentation generation","title":"Documentation generation","text":"We are using Documenter.jl to generate the documentation web site based on markdown files stored in docs/src. Please help keeping the documentation up-to-date by editing the markdown files! For instructions on how to write appropriate documentation please refer to the relevant chapter in the Julia documentation and the Documenter.jl documentation.","category":"page"},{"location":"documentation.html#Generating-the-documentation-web-site","page":"Documentation generation","title":"Generating the documentation web site","text":"","category":"section"},{"location":"documentation.html","page":"Documentation generation","title":"Documentation generation","text":"The documentation pages can be generated by running the build script by typing","category":"page"},{"location":"documentation.html","page":"Documentation generation","title":"Documentation generation","text":"Rimu$ julia --project=docs docs/make.jl","category":"page"},{"location":"documentation.html","page":"Documentation generation","title":"Documentation generation","text":"on the shell prompt from the Rimu/ folder. A complete image of the static documentation web site will be generated in the folder docs/build/. It can be viewed locally by pointing a web browser to file docs/build/index.html, or by deploying it to the GitHub pages web server.","category":"page"},{"location":"documentation.html#Automatic-documentation-generation-and-deployment","page":"Documentation generation","title":"Automatic documentation generation and deployment","text":"","category":"section"},{"location":"documentation.html","page":"Documentation generation","title":"Documentation generation","text":"Our documentation is hosted on GitHub pages. The documentation web site can be built and deployed automatically with GitHub Actions. This needs to be set up with an appropriate script in the file .github/workflows/docs.yml, where triggers for this to happen can be defined. In the current set up, a new documentation web site is generated and deployed whenever someone pushes to the develop branch on the GitHub server. The updated documentation can then be accessed here.","category":"page"},{"location":"documentation.html","page":"Documentation generation","title":"Documentation generation","text":"Previews for pull-requests can be accessed by replacing 101 in the following link with the PR number: https://RimuQMC.github.io/Rimu.jl/previews/PR101/","category":"page"},{"location":"documentation.html#Example-scripts","page":"Documentation generation","title":"Example scripts","text":"","category":"section"},{"location":"documentation.html","page":"Documentation generation","title":"Documentation generation","text":"Examples should be added to the scripts folder, in the form of .jl files suitable for parsing by Literate. The process of generating documentation is automated in the docs/make.jl file and assumes that the following line is at (or near) the top of the script:","category":"page"},{"location":"documentation.html","page":"Documentation generation","title":"Documentation generation","text":"# # Example N: Title","category":"page"},{"location":"documentation.html","page":"Documentation generation","title":"Documentation generation","text":"where the number N and Title will be extracted automatically.","category":"page"},{"location":"documentation.html","page":"Documentation generation","title":"Documentation generation","text":"Tests for the results and output of specific scripts should be added at the end of each example. The code to run the test should be hidden from the final generated document by appending \"#hide\" to each line of testing code. For example,","category":"page"},{"location":"documentation.html","page":"Documentation generation","title":"Documentation generation","text":"using Test #hide\n@test isfile(\"result.out\") #hide\n@test result == expected_result #hide","category":"page"},{"location":"addresses.html#Module-BitStringAddresses","page":"BitString addresses","title":"Module BitStringAddresses","text":"","category":"section"},{"location":"addresses.html","page":"BitString addresses","title":"BitString addresses","text":"This module contains the implementations of BitString and various Fock addresses. The addresses serve as a basis for a Hamiltonian.","category":"page"},{"location":"addresses.html","page":"BitString addresses","title":"BitString addresses","text":"While there are not restrictions on the type of address a Hamiltonian uses, Rimu provides implementations for Bosonic, Fermionic, and mixed Fock States.","category":"page"},{"location":"addresses.html","page":"BitString addresses","title":"BitString addresses","text":"When implementing a new address type, care must be taken to make them space-efficient and stack-allocated - avoid using (heap-allocated) arrays to represent your addresses at all costs!","category":"page"},{"location":"addresses.html#Fock-addresses","page":"BitString addresses","title":"Fock addresses","text":"","category":"section"},{"location":"addresses.html","page":"BitString addresses","title":"BitString addresses","text":"Rimu provides a variety of address implementations that should make it straightforward to implement efficient Hamiltonians. Examples are:","category":"page"},{"location":"addresses.html","page":"BitString addresses","title":"BitString addresses","text":"BoseFS Single-component bosonic Fock state with fixed particle and mode number.\nFermiFS Single-component fermionic Fock state with fixed particle and mode number.\nCompositeFS Multi-component Fock state composed of the above types.\nOccupationNumberFS Single-component bosonic Fock state with a fixed number of modes. The number of particles is not part of the type and can be changed by operators.","category":"page"},{"location":"addresses.html#Fock-address-API","page":"BitString addresses","title":"Fock address API","text":"","category":"section"},{"location":"addresses.html","page":"BitString addresses","title":"BitString addresses","text":"Modules = [BitStringAddresses]\nPages = [\"fockaddress.jl\",\"bosefs.jl\",\"fermifs.jl\",\"multicomponent.jl\",\"occupationnumberfs.jl\"]\nPrivate = false","category":"page"},{"location":"addresses.html#Rimu.BitStringAddresses.AbstractFockAddress","page":"BitString addresses","title":"Rimu.BitStringAddresses.AbstractFockAddress","text":"AbstractFockAddress{N,M}\n\nAbstract type representing a Fock state with N particles and M modes.\n\nSee also SingleComponentFockAddress, CompositeFS, BoseFS, FermiFS.\n\n\n\n\n\n","category":"type"},{"location":"addresses.html#Rimu.BitStringAddresses.BoseFSIndex","page":"BitString addresses","title":"Rimu.BitStringAddresses.BoseFSIndex","text":"BoseFSIndex\n\nStruct used for indexing and performing excitations on a BoseFS.\n\nFields:\n\noccnum: the occupation number.\nmode: the index of the mode.\noffset: the position of the mode in the address. This is the bit offset of the mode when\n\nthe address is represented by a bitstring, and the position in the list when it is represented by SortedParticleList.\n\n\n\n\n\n","category":"type"},{"location":"addresses.html#Rimu.BitStringAddresses.FermiFSIndex","page":"BitString addresses","title":"Rimu.BitStringAddresses.FermiFSIndex","text":"FermiFSIndex\n\nStruct used for indexing and performing excitations on a FermiFS.\n\nFields:\n\noccnum: the occupation number.\nmode: the index of the mode.\noffset: the position of the mode in the address. This is mode - 1 when the address is represented by a bitstring, and the position in the list when using SortedParticleList.\n\n\n\n\n\n","category":"type"},{"location":"addresses.html#Rimu.BitStringAddresses.OccupiedModeMap","page":"BitString addresses","title":"Rimu.BitStringAddresses.OccupiedModeMap","text":"OccupiedModeMap(addr) <: AbstractVector\n\nGet a map of occupied modes in address as an AbstractVector of indices compatible with excitation - BoseFSIndex or FermiFSIndex.\n\nOccupiedModeMap(addr)[i] contains the index for the i-th occupied mode. This is useful because repeatedly looking for occupied modes with find_occupied_mode can be time-consuming. OccupiedModeMap(addr) is an eager version of the iterator returned by occupied_modes. It is similar to onr but contains more information.\n\nExample\n\njulia> b = BoseFS(10, 0, 0, 0, 2, 0, 1)\nBoseFS{13,7}(10, 0, 0, 0, 2, 0, 1)\n\njulia> mb = OccupiedModeMap(b)\n3-element OccupiedModeMap{7, BoseFSIndex}:\n BoseFSIndex(occnum=10, mode=1, offset=0)\n BoseFSIndex(occnum=2, mode=5, offset=14)\n BoseFSIndex(occnum=1, mode=7, offset=18)\n\njulia> f = FermiFS(1,1,1,1,0,0,1,0,0)\nFermiFS{5,9}(1, 1, 1, 1, 0, 0, 1, 0, 0)\n\njulia> mf = OccupiedModeMap(f)\n5-element OccupiedModeMap{5, FermiFSIndex}:\n FermiFSIndex(occnum=1, mode=1, offset=0)\n FermiFSIndex(occnum=1, mode=2, offset=1)\n FermiFSIndex(occnum=1, mode=3, offset=2)\n FermiFSIndex(occnum=1, mode=4, offset=3)\n FermiFSIndex(occnum=1, mode=7, offset=6)\n\njulia> mf == collect(occupied_modes(f))\ntrue\n\njulia> dot(mf, mb)\n11\n\njulia> dot(mf, 1:20)\n17\n\nSee also dot, SingleComponentFockAddress.\n\n\n\n\n\n","category":"type"},{"location":"addresses.html#Rimu.BitStringAddresses.OccupiedPairsMap","page":"BitString addresses","title":"Rimu.BitStringAddresses.OccupiedPairsMap","text":"OccupiedPairsMap(addr::SingleComponentFockAddress) <: AbstractVector\n\nGet a map of all distinct pairs of indices in addr. Pairs involving multiply-occupied modes are counted once, (including self-pairing). This is useful for cases where identifying pairs of particles for eg. interactions is not well-defined or efficient to do on the fly. This is an eager iterator whose elements are a tuple of particle indices that can be given to excitation\n\nExample\n\njulia> addr = BoseFS(10, 0, 0, 0, 2, 0, 1)\nBoseFS{13,7}(10, 0, 0, 0, 2, 0, 1)\n\njulia> pairs = OccupiedPairsMap(addr)\n5-element OccupiedPairsMap{78, Tuple{BoseFSIndex, BoseFSIndex}}:\n (BoseFSIndex(occnum=10, mode=1, offset=0), BoseFSIndex(occnum=10, mode=1, offset=0))\n (BoseFSIndex(occnum=2, mode=5, offset=14), BoseFSIndex(occnum=2, mode=5, offset=14))\n (BoseFSIndex(occnum=2, mode=5, offset=14), BoseFSIndex(occnum=10, mode=1, offset=0))\n (BoseFSIndex(occnum=1, mode=7, offset=18), BoseFSIndex(occnum=10, mode=1, offset=0))\n (BoseFSIndex(occnum=1, mode=7, offset=18), BoseFSIndex(occnum=2, mode=5, offset=14))\n\njulia> excitation(addr, pairs[2], pairs[4])\n(BoseFS{13,7}(9, 0, 0, 0, 4, 0, 0), 10.954451150103322)\n\nSee also OccupiedModeMap.\n\n\n\n\n\n","category":"type"},{"location":"addresses.html#Rimu.BitStringAddresses.SingleComponentFockAddress","page":"BitString addresses","title":"Rimu.BitStringAddresses.SingleComponentFockAddress","text":"SingleComponentFockAddress{N,M} <: AbstractFockAddress{N,M}\n\nA type representing a single component Fock state with N particles and M modes.\n\nImplemented subtypes: BoseFS, FermiFS.\n\nSupported functionality\n\nfind_mode\nfind_occupied_mode\nnum_occupied_modes\noccupied_modes: Lazy iterator.\nOccupiedModeMap: AbstractVector with eager construction.\nexcitation: Create a new address.\nBoseFSIndex and FermiFSIndex for indexing.\n\nSee also CompositeFS, AbstractFockAddress.\n\n\n\n\n\n","category":"type"},{"location":"addresses.html#Rimu.BitStringAddresses.excitation","page":"BitString addresses","title":"Rimu.BitStringAddresses.excitation","text":"excitation(addr::SingleComponentFockAddress, creations::NTuple, destructions::NTuple)\n\nGenerate an excitation on address addr by applying creations and destructions, which are tuples of the appropriate address indices (i.e. BoseFSIndex for bosons, or FermiFSIndex for fermions).\n\na^_c_1 a^_c_2 ldots a_d_1 a_d_2 ldots mathrmaddrrangle to\nαmathrmnaddrrangle\n\nReturns the new address naddr and the factor α. The value of α is given by the square root of the product of mode occupations before destruction and after creation. If the excitation is illegal, returns an arbitrary address and the value 0.0.\n\nExample\n\njulia> f = FermiFS(1,1,0,0,1,1,1,1)\nFermiFS{6,8}(1, 1, 0, 0, 1, 1, 1, 1)\n\njulia> i, j, k, l = find_mode(f, (3,4,2,5))\n(FermiFSIndex(occnum=0, mode=3, offset=2), FermiFSIndex(occnum=0, mode=4, offset=3), FermiFSIndex(occnum=1, mode=2, offset=1), FermiFSIndex(occnum=1, mode=5, offset=4))\n\njulia> excitation(f, (i,j), (k,l))\n(FermiFS{6,8}(1, 0, 1, 1, 0, 1, 1, 1), -1.0)\n\nSee SingleComponentFockAddress.\n\n\n\n\n\n","category":"function"},{"location":"addresses.html#Rimu.BitStringAddresses.find_mode","page":"BitString addresses","title":"Rimu.BitStringAddresses.find_mode","text":"find_mode(::SingleComponentFockAddress, i)\n\nFind the i-th mode in address. Returns BoseFSIndex for BoseFS, and FermiFSIndex for FermiFS. Can work on a tuple of modes. Does not check bounds.\n\njulia> find_mode(BoseFS(1, 0, 2), 2)\nBoseFSIndex(occnum=0, mode=2, offset=2)\n\njulia> find_mode(FermiFS(1, 1, 1, 0), (2,3))\n(FermiFSIndex(occnum=1, mode=2, offset=1), FermiFSIndex(occnum=1, mode=3, offset=2))\n\nSee SingleComponentFockAddress.\n\n\n\n\n\n","category":"function"},{"location":"addresses.html#Rimu.BitStringAddresses.find_occupied_mode","page":"BitString addresses","title":"Rimu.BitStringAddresses.find_occupied_mode","text":"find_occupied_mode(::SingleComponentFockAddress, k)\nfind_occupied_mode(::BoseFS, k, [n])\n\nFind the k-th occupied mode in address (with at least n particles). Returns BoseFSIndex for BoseFS, and FermiFSIndex for FermiFS. When unsuccessful it returns a zero index.\n\nExample\n\njulia> find_occupied_mode(FermiFS(1, 1, 1, 0), 2)\nFermiFSIndex(occnum=1, mode=2, offset=1)\n\njulia> find_occupied_mode(BoseFS(1, 0, 2), 1)\nBoseFSIndex(occnum=1, mode=1, offset=0)\n\njulia> find_occupied_mode(BoseFS(1, 0, 2), 1, 2)\nBoseFSIndex(occnum=2, mode=3, offset=3)\n\nSee also occupied_modes, OccupiedModeMap, SingleComponentFockAddress.\n\n\n\n\n\n","category":"function"},{"location":"addresses.html#Rimu.BitStringAddresses.num_components-Tuple{AbstractFockAddress}","page":"BitString addresses","title":"Rimu.BitStringAddresses.num_components","text":"num_components(::Type{<:AbstractFockAddress})\nnum_components(::AbstractFockAddress)\n\nNumber of components in address.\n\n\n\n\n\n","category":"method"},{"location":"addresses.html#Rimu.BitStringAddresses.num_modes-Tuple{AbstractFockAddress}","page":"BitString addresses","title":"Rimu.BitStringAddresses.num_modes","text":"num_modes(::Type{<:AbstractFockAddress})\nnum_modes(::AbstractFockAddress)\n\nNumber of modes represented by address.\n\n\n\n\n\n","category":"method"},{"location":"addresses.html#Rimu.BitStringAddresses.num_occupied_modes","page":"BitString addresses","title":"Rimu.BitStringAddresses.num_occupied_modes","text":"num_occupied_modes(::SingleComponentFockAddress)\n\nGet the number of occupied modes in address. Equivalent to length(occupied_modes(address)), or the number of non-zeros in its ONR representation.\n\nExample\n\njulia> num_occupied_modes(BoseFS((1, 0, 2)))\n2\njulia> num_occupied_modes(FermiFS((1, 1, 1, 0)))\n3\n\nSee SingleComponentFockAddress.\n\n\n\n\n\n","category":"function"},{"location":"addresses.html#Rimu.BitStringAddresses.num_particles-Tuple{AbstractFockAddress}","page":"BitString addresses","title":"Rimu.BitStringAddresses.num_particles","text":"num_particles(::Type{<:AbstractFockAddress})\nnum_particles(::AbstractFockAddress)\n\nNumber of particles represented by address.\n\n\n\n\n\n","category":"method"},{"location":"addresses.html#Rimu.BitStringAddresses.occupied_modes","page":"BitString addresses","title":"Rimu.BitStringAddresses.occupied_modes","text":"occupied_modes(::SingleComponentFockAddress)\n\nReturn a lazy iterator over all occupied modes in an address. Iterates over BoseFSIndexs for BoseFS, and over FermiFSIndexs for FermiFS. See OccupiedModeMap for an eager version.\n\nExample\n\njulia> b = BoseFS((1,5,0,4));\n\njulia> foreach(println, occupied_modes(b))\nBoseFSIndex(occnum=1, mode=1, offset=0)\nBoseFSIndex(occnum=5, mode=2, offset=2)\nBoseFSIndex(occnum=4, mode=4, offset=9)\n\njulia> f = FermiFS((1,1,0,1,0,0,1));\n\njulia> foreach(println, occupied_modes(f))\nFermiFSIndex(occnum=1, mode=1, offset=0)\nFermiFSIndex(occnum=1, mode=2, offset=1)\nFermiFSIndex(occnum=1, mode=4, offset=3)\nFermiFSIndex(occnum=1, mode=7, offset=6)\n\nSee also find_occupied_mode, SingleComponentFockAddress.\n\n\n\n\n\n","category":"function"},{"location":"addresses.html#Rimu.BitStringAddresses.onr","page":"BitString addresses","title":"Rimu.BitStringAddresses.onr","text":"occupation_number_representation(fs::SingleComponentFockAddress)\nonr(fs::SingleComponentFockAddress)\n\nCompute and return the occupation number representation of the Fock state fs as an SVector{M}, where M is the number of modes.\n\n\n\n\n\n","category":"function"},{"location":"addresses.html#Rimu.BitStringAddresses.@fs_str-Tuple{Any}","page":"BitString addresses","title":"Rimu.BitStringAddresses.@fs_str","text":"fs\"$(string)\"\n\nParse the compact representation of a Fock state. Useful for copying the printout from a vector to the REPL.\n\nExample\n\njulia> DVec(BoseFS{3,4}(0, 1, 2, 0) => 1)\nDVec{BoseFS{3, 4, BitString{6, 1, UInt8}},Int64} with 1 entry, style = IsStochasticInteger{Int64}()\n fs\"|0 1 2 0⟩\" => 1\n\njulia> fs\"|0 1 2 0⟩\" => 1 # Copied from above printout\nBoseFS{3,4}(0, 1, 2, 0) => 1\n\njulia> fs\"|1 2 3⟩⊗|0 1 0⟩\" # composite bosonic Fock state\nCompositeFS(\n BoseFS{6,3}(1, 2, 3),\n BoseFS{1,3}(0, 1, 0),\n)\n\njulia> fs\"|↑↓↑⟩\" # construct a fermionic Fock state\nCompositeFS(\n FermiFS{2,3}(1, 0, 1),\n FermiFS{1,3}(0, 1, 0),\n)\n\njulia> s = fs\"|0 1 2 0⟩{}\" # constructing OccupationNumberFS with default UInt8 container\nOccupationNumberFS{4, UInt8}(0, 1, 2, 0)\n\njulia> [s] # prints out with the signifcant number of bits specified in braces\n1-element Vector{OccupationNumberFS{4, UInt8}}:\n fs\"|0 1 2 0⟩{8}\"\n\nSee also FermiFS, BoseFS, CompositeFS, FermiFS2C, OccupationNumberFS.\n\n\n\n\n\n","category":"macro"},{"location":"addresses.html#Rimu.BitStringAddresses.BoseFS","page":"BitString addresses","title":"Rimu.BitStringAddresses.BoseFS","text":"BoseFS{N,M,S} <: SingleComponentFockAddress\n\nAddress type that represents a Fock state of N spinless bosons in M modes by wrapping a BitString, or a SortedParticleList. Which is wrapped is chosen automatically based on the properties of the address.\n\nConstructors\n\nBoseFS{[N,M]}(val::Integer...): Create BoseFS{N,M} from occupation numbers. This is type-stable if the number of modes M and the number of particles N are provided. Otherwise, M and N are inferred from the arguments.\nBoseFS{[N,M]}(onr): Create BoseFS{N,M} from occupation number representation, see onr. This is efficient if N and M are provided, and onr is a statically-sized collection, such as a Tuple or SVector.\nBoseFS{[N,M]}([M, ]pairs...): Provide the number of modes M and mode => occupation_number pairs. If M is provided as a type parameter, it should not be provided as the first argument. Useful for creating sparse addresses. pairs can be multiple arguments or an iterator of pairs.\nBoseFS{N,M,S}(bs::S): Unsafe constructor. Does not check whether the number of particles in bs is equal to N.\n@fs_str: Addresses are sometimes printed in a compact manner. This representation can also be used as a constructor. See the examples below.\n\nExamples\n\njulia> BoseFS{6,5}(0, 1, 2, 3, 0)\nBoseFS{6,5}(0, 1, 2, 3, 0)\n\njulia> BoseFS(abs(i - 3) ≤ 1 ? i - 1 : 0 for i in 1:5)\nBoseFS{6,5}(0, 1, 2, 3, 0)\n\njulia> BoseFS(5, 2 => 1, 3 => 2, 4 => 3)\nBoseFS{6,5}(0, 1, 2, 3, 0)\n\njulia> BoseFS{6,5}(i => i - 1 for i in 2:4)\nBoseFS{6,5}(0, 1, 2, 3, 0)\n\njulia> fs\"|0 1 2 3 0⟩\"\nBoseFS{6,5}(0, 1, 2, 3, 0)\n\njulia> fs\"|b 5: 2 3 3 4 4 4⟩\"\nBoseFS{6,5}(0, 1, 2, 3, 0)\n\nSee also: SingleComponentFockAddress, OccupationNumberFS, FermiFS, CompositeFS, FermiFS2C.\n\n\n\n\n\n","category":"type"},{"location":"addresses.html#Rimu.BitStringAddresses.bose_hubbard_interaction-Union{Tuple{BoseFS{<:Any, <:Any, A}}, Tuple{A}} where A<:BitString","page":"BitString addresses","title":"Rimu.BitStringAddresses.bose_hubbard_interaction","text":"bose_hubbard_interaction(address)\n\nReturn Σ_i n_i (n_i-1) for computing the Bose-Hubbard on-site interaction (without the U prefactor.)\n\nExample\n\njulia> Hamiltonians.bose_hubbard_interaction(BoseFS{4,4}((2,1,1,0)))\n2\njulia> Hamiltonians.bose_hubbard_interaction(BoseFS{4,4}((3,0,1,0)))\n6\n\n\n\n\n\n","category":"method"},{"location":"addresses.html#Rimu.BitStringAddresses.hopnextneighbour-Union{Tuple{A}, Tuple{M}, Tuple{N}, Tuple{BoseFS{N, M, A}, Any}} where {N, M, A<:BitString}","page":"BitString addresses","title":"Rimu.BitStringAddresses.hopnextneighbour","text":"new_address, value = hopnextneighbour(add, chosen, boundary_condition)\n\nCompute the new address of a hopping event for the Hubbard model. Returns the new address and the square root of product of occupation numbers of the involved modes multiplied by a term consistent with boundary condition as the value. The following boundary conditions are supported:\n\n:periodic: hopping over the boundary gives does not change the value.\n:twisted: hopping over the boundary flips the sign of the value.\n:hard_wall: hopping over the boundary gives a value of zero.\nθ <: Number: hopping over the boundary gives a value multiplied by exp(iθ) or exp(iθ) depending on the direction of hopping.\n\nThe off-diagonals are indexed as follows:\n\n(chosen + 1) ÷ 2 selects the hopping site.\nEven chosen indicates a hop to the left.\nOdd chosen indicates a hop to the right.\n\nExample\n\njulia> using Rimu.Hamiltonians: hopnextneighbour\n\njulia> hopnextneighbour(BoseFS(1, 0, 1), 3)\n(BoseFS{2,3}(2, 0, 0), 1.4142135623730951)\n\njulia> hopnextneighbour(BoseFS(1, 0, 1), 4)\n(BoseFS{2,3}(1, 1, 0), 1.0)\n\njulia> hopnextneighbour(BoseFS(1, 0, 1), 3, :twisted)\n(BoseFS{2,3}(2, 0, 0), -1.4142135623730951)\n\njulia> hopnextneighbour(BoseFS(1, 0, 1), 3, :hard_wall)\n(BoseFS{2,3}(2, 0, 0), 0.0)\n\njulia> hopnextneighbour(BoseFS(1, 0, 1), 3, π/4)\n(BoseFS{2,3}(2, 0, 0), 1.0000000000000002 + 1.0im)\n\n\n\n\n\n","category":"method"},{"location":"addresses.html#Rimu.BitStringAddresses.near_uniform-Union{Tuple{Type{<:BoseFS{N, M}}}, Tuple{M}, Tuple{N}} where {N, M}","page":"BitString addresses","title":"Rimu.BitStringAddresses.near_uniform","text":"near_uniform(BoseFS{N,M}) -> BoseFS{N,M}\n\nCreate bosonic Fock state with near uniform occupation number of M modes with a total of N particles.\n\nExamples\n\njulia> near_uniform(BoseFS{7,5})\nBoseFS{7,5}(2, 2, 1, 1, 1)\n\njulia> near_uniform(FermiFS{3,5})\nFermiFS{3,5}(1, 1, 1, 0, 0)\n\n\n\n\n\n","category":"method"},{"location":"addresses.html#Rimu.BitStringAddresses.FermiFS","page":"BitString addresses","title":"Rimu.BitStringAddresses.FermiFS","text":"FermiFS{N,M,S} <: SingleComponentFockAddress\n\nAddress type that represents a Fock state of N fermions of the same spin in M modes by wrapping a BitString, or a SortedParticleList. Which is wrapped is chosen automatically based on the properties of the address.\n\nConstructors\n\nFermiFS{[N,M]}(val::Integer...): Create FermiFS{N,M} from occupation numbers. This is type-stable if the number of modes M and the number of particles N are provided. Otherwise, M and N are inferred from the arguments.\nFermiFS{[N,M]}(onr): Create FermiFS{N,M} from occupation number representation, see onr. This is efficient if N and M are provided, and onr is a statically-sized collection, such as a Tuple{M} or SVector{M}.\nFermiFS{[N,M]}([M, ]pairs...): Provide the number of modes M and pairs of the form mode => 1. If M is provided as a type parameter, it should not be provided as the first argument. Useful for creating sparse addresses. pairs can be multiple arguments or an iterator of pairs.\nFermiFS{N,M,S}(bs::S): Unsafe constructor. Does not check whether the number of particles in bs is equal to N, or whether each mode only contains one particle.\n@fs_str: Addresses are sometimes printed in a compact manner. This representation can also be used as a constructor. See the examples below.\n\nExamples\n\njulia> FermiFS{3,5}(0, 1, 1, 1, 0)\nFermiFS{3,5}(0, 1, 1, 1, 0)\n\njulia> FermiFS([abs(i - 3) ≤ 1 for i in 1:5])\nFermiFS{3,5}(0, 1, 1, 1, 0)\n\njulia> FermiFS(5, 2 => 1, 3 => 1, 4 => 1)\nFermiFS{3,5}(0, 1, 1, 1, 0)\n\njulia> FermiFS{3,5}(i => 1 for i in 2:4)\nFermiFS{3,5}(0, 1, 1, 1, 0)\n\njulia> fs\"|⋅↑↑↑⋅⟩\"\nFermiFS{3,5}(0, 1, 1, 1, 0)\n\njulia> fs\"|f 5: 2 3 4⟩\"\nFermiFS{3,5}(0, 1, 1, 1, 0)\n\nSee also: SingleComponentFockAddress, BoseFS, CompositeFS, FermiFS2C, BitString, OccupationNumberFS.\n\n\n\n\n\n","category":"type"},{"location":"addresses.html#Rimu.BitStringAddresses.CompositeFS","page":"BitString addresses","title":"Rimu.BitStringAddresses.CompositeFS","text":"CompositeFS(addresses::SingleComponentFockAddress...) <: AbstractFockAddress\n\nUsed to encode addresses for multi-component models. All component addresses are expected have the same number of modes.\n\nSee also: BoseFS, FermiFS, SingleComponentFockAddress, num_modes, FermiFS2C, AbstractFockAddress.\n\n\n\n\n\n","category":"type"},{"location":"addresses.html#Rimu.BitStringAddresses.FermiFS2C","page":"BitString addresses","title":"Rimu.BitStringAddresses.FermiFS2C","text":"FermiFS2C <: AbstractFockAddress\nFermiFS2C(onr_a, onr_b)\n\nFock state address with two fermionic (spin) components. Alias for CompositeFS with two FermiFS components. Construct by specifying either two compatible FermiFSs, two onrs, or the number of modes followed by mode => occupation_number pairs, where occupation_number=1 will put a particle in the first component and occupation_number=-1 will put a particle in the second component. See examples below.\n\nExamples\n\njulia> FermiFS2C(FermiFS(1,0,0), FermiFS(0,1,1))\nCompositeFS(\n FermiFS{1,3}(1, 0, 0),\n FermiFS{2,3}(0, 1, 1),\n)\n\njulia> FermiFS2C((1,0,0), (0,1,1))\nCompositeFS(\n FermiFS{1,3}(1, 0, 0),\n FermiFS{2,3}(0, 1, 1),\n)\n\njulia> FermiFS2C(3, 1 => 1, 2 => -1, 3 => -1)\nCompositeFS(\n FermiFS{1,3}(1, 0, 0),\n FermiFS{2,3}(0, 1, 1),\n)\n\njulia> fs\"|↑↓↓⟩\"\nCompositeFS(\n FermiFS{1,3}(1, 0, 0),\n FermiFS{2,3}(0, 1, 1),\n)\n\n\n\n\n\n","category":"type"},{"location":"addresses.html#Rimu.BitStringAddresses.time_reverse-Union{Tuple{CompositeFS{2, N, M, T}}, Tuple{T}, Tuple{M}, Tuple{N}} where {N, M, T<:(Tuple{T, T} where T)}","page":"BitString addresses","title":"Rimu.BitStringAddresses.time_reverse","text":"time_reverse(addr)\n\nApply the time-reversal operation on a two-component Fock address that flips all the spins.\n\nRequires each component address to have the same type.\n\n\n\n\n\n","category":"method"},{"location":"addresses.html#Rimu.BitStringAddresses.OccupationNumberFS","page":"BitString addresses","title":"Rimu.BitStringAddresses.OccupationNumberFS","text":"OccupationNumberFS{M,T} <: SingleComponentFockAddress\n\nAddress type that stores the occupation numbers of a single component bosonic Fock state with M modes. The occupation numbers must fit into the type T <: Unsigned. The number of particles is runtime data, and can be retrieved with num_particles(address).\n\nConstructors\n\nOccupationNumberFS(val::Integer...): Construct from occupation numbers. Must be < 256 to fit into UInt8.\nOccupationNumberFS{[M,T]}(onr): Construct from collection onr with M occupation numbers with type T. If unspecified, the type T of the occupation numbers is inferred from the type of the arguments.\nOccupationNumberFS{M[,T]}(): Construct a vacuum state with M modes. If T is unspecified, UInt8 is used.\nOccupationNumberFS(fs::BoseFS): Construct from BoseFS.\nWith shortform macro @fs_str. Specify the number of significant bits in braces. See example below.\n\nExamples\n\njulia> ofs = OccupationNumberFS(1,2,3)\nOccupationNumberFS{3, UInt8}(1, 2, 3)\n\njulia> ofs == fs\"|1 2 3⟩{8}\"\ntrue\n\njulia> num_particles(ofs)\n6\n\njulia> OccupationNumberFS{5}() # vacuum state with 5 modes\nOccupationNumberFS{5, UInt8}(0, 0, 0, 0, 0)\n\njulia> OccupationNumberFS(i for i in 1:3) # use list comprehension\nOccupationNumberFS{3, UInt8}(1, 2, 3)\n\njulia> OccupationNumberFS(4, 1=>2, 3=>4) # sparse constructor\nOccupationNumberFS{4, UInt8}(2, 0, 4, 0)\n\n\n\n\n\n","category":"type"},{"location":"addresses.html#Rimu.BitStringAddresses.excitation-Union{Tuple{T}, Tuple{OccupationNumberFS{<:Any, T}, NTuple{var\"#s61\", Int64} where var\"#s61\", NTuple{var\"#s5\", Int64} where var\"#s5\"}} where T","page":"BitString addresses","title":"Rimu.BitStringAddresses.excitation","text":"excitation(addr::OccupationNumberFS, c::NTuple, d::NTuple)\n→ (nadd, α)\n\nGenerate an excitation on an OccupationNumberFS by applying the creation and destruction operators specified by the tuples of mode numbers c and d to the Fock state addr. The modes are indexed by integers (starting at 1), or by indices of type BoseFSIndex. The value of α is given by the square root of the product of mode occupations before destruction and after creation.\n\nThe number of particles may change by this type of excitation.\n\nExample\n\njulia> s = fs\"|1 2 3⟩{8}\"\nOccupationNumberFS{3, UInt8}(1, 2, 3)\n\njulia> num_particles(s)\n6\n\njulia> es, α = excitation(s, (1,1), (3,))\n(OccupationNumberFS{3, UInt8}(3, 2, 2), 4.242640687119285)\n\njulia> num_particles(es)\n7\n\n\n\n\n\n","category":"method"},{"location":"addresses.html#Internal-representations","page":"BitString addresses","title":"Internal representations","text":"","category":"section"},{"location":"addresses.html","page":"BitString addresses","title":"BitString addresses","text":"The atomic addresses, BoseFS and FermiFS, are implemented as either bitstrings or sorted lists of particles. Using these approaches over an occupation number representation makes the addresses much more space-efficient.","category":"page"},{"location":"addresses.html","page":"BitString addresses","title":"BitString addresses","text":"Therewhile OccupationNumberFS internally uses the occupation number representation, which allows it to handle excitation operations that change the particle number. This is fast but requires more storage space.","category":"page"},{"location":"addresses.html#Internal-APIs","page":"BitString addresses","title":"Internal APIs","text":"","category":"section"},{"location":"addresses.html","page":"BitString addresses","title":"BitString addresses","text":"Modules = [BitStringAddresses]\nPages = [\"bitstring.jl\", \"sortedparticlelist.jl\"]\nPrivate = false","category":"page"},{"location":"addresses.html#Rimu.BitStringAddresses.BitString","page":"BitString addresses","title":"Rimu.BitStringAddresses.BitString","text":"BitString{B,N,T<:Unsigned}\n\nType for storing bitstrings of static size. Holds B bits in N chunks, where each chunk is of type T.\n\nN is chosen automatically to accommodate B bits as efficiently as possible.\n\nConstructors\n\nBitString{B,N,T}(::SVector{N,T}): unsafe constructor. Does not check for ghost bits.\nBitString{B,N,T}(i::T): as above, but sets i as the rightmost chunk.\nBitString{B}(::Integer): Convert integer to BitString. Integer is truncated to the correct number of bits.\n\n\n\n\n\n","category":"type"},{"location":"addresses.html#Rimu.BitStringAddresses.SortedParticleList","page":"BitString addresses","title":"Rimu.BitStringAddresses.SortedParticleList","text":"SortedParticleList{N,M,T<:Unsigned}\n\nType for storing sparse Fock states. Stores the mode number of each particle as an entry with only its mode stored. The entries are always kept sorted.\n\nIterating over SortedParticleLists yields occupied modes as a tuple of occupation number, mode number, and position in list.\n\nConstructors\n\nSortedParticleList{N,M,T}(::SVector{N,T}): unsafe constructor. Does not sort input.\nSortedParticleList(arr::AbstractVector): convert ONR to SortedParticleList\n\n\n\n\n\n","category":"type"},{"location":"addresses.html#Index","page":"BitString addresses","title":"Index","text":"","category":"section"},{"location":"addresses.html","page":"BitString addresses","title":"BitString addresses","text":"Pages = [\"addresses.md\"]","category":"page"},{"location":"API.html#API","page":"API","title":"API","text":"","category":"section"},{"location":"API.html#Rimu","page":"API","title":"Rimu","text":"","category":"section"},{"location":"API.html","page":"API","title":"API","text":"Modules = [Rimu]","category":"page"},{"location":"API.html#Rimu.Rimu","page":"API","title":"Rimu.Rimu","text":"Rimu\n\nRandom integrators for many-body quantum systems\n\nWelcome to Rimu version 0.14.0. Read the documentation online.\n\n\n\n\n\n","category":"module"},{"location":"API.html#Rimu.PACKAGE_VERSION","page":"API","title":"Rimu.PACKAGE_VERSION","text":"Rimu.PACKAGE_VERSION\n\nConstant that contains the current VersionNumber of Rimu.\n\n\n\n\n\n","category":"constant"},{"location":"API.html#DataFrames.DataFrame-Tuple{Rimu.Report}","page":"API","title":"DataFrames.DataFrame","text":"DataFrame(report::Report)\n\nConvert the Report to a DataFrame. Metadata is added as metadata to the DataFrame.\n\n\n\n\n\n","category":"method"},{"location":"API.html#Rimu.AllOverlaps","page":"API","title":"Rimu.AllOverlaps","text":"AllOverlaps(n_replicas=2; operator=nothing, transform=nothing, vecnorm=true)\n <: ReplicaStrategy{n_replicas}\n\nRun n_replicas replicas and report overlaps between all pairs of replica vectors. If operator is not nothing, the overlap dot(c1, operator, c2) is reported as well. If operator is a tuple of operators, the overlaps are computed for all operators.\n\nColumn names in the report are of the form c{i}_dot_c{j} for vector-vector overlaps, and c{i}_Op{k}_c{j} for operator overlaps.\n\nSee ProjectorMonteCarloProblem, ReplicaStrategy and AbstractOperator (for an interface for implementing operators).\n\nTransformed Hamiltonians\n\nIf a transformed Hamiltonian G has been passed to ProjectorMonteCarloProblem then overlaps can be calculated by passing the same transformed Hamiltonian to AllOverlaps by setting transform=G. A warning is given if these two Hamiltonians do not match.\n\nImplemented transformations are:\n\nGutzwillerSampling\nGuidingVectorSampling\n\nIn the case of a transformed Hamiltonian the overlaps are defined as follows. For a similarity transformation G of the Hamiltonian (see e.g. GutzwillerSampling.)\n\n hatG = f hatH f^-1\n\nThe expectation value of an operator hatA is\n\n langle hatA rangle = langle psi hatA psi rangle\n = fraclangle phi f^-1 hatA f^-1 phi ranglelangle phi f^-2 phi rangle\n\nwhere\n\n phi rangle = f psi rangle\n\nis the (right) eigenvector of hatG and psi rangle is an eigenvector of hatH.\n\nFor a K-tuple of input operators (hatA_1 hatA_K), overlaps of langle phi f^-1 hatA f^-1 phi rangle are reported as c{i}_Op{k}_c{j}. The correct vector-vector overlap langle phi f^-2 phi rangle is reported last as c{i}_Op{K+1}_c{j}. This is in addition to the bare vector-vector overlap langle phi f^-2 phi rangle that is reported as c{i}_dot_c{j}.\n\nIn either case the c{i}_dot_c{j} overlap can be omitted with the flag vecnorm=false.\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.ConstantTimeStep","page":"API","title":"Rimu.ConstantTimeStep","text":"ConstantTimeStep <: TimeStepStrategy\n\nKeep time_step constant.\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.DefaultShiftParameters","page":"API","title":"Rimu.DefaultShiftParameters","text":"DefaultShiftParameters\n\nDefault mutable struct for storing the shift parameters.\n\nSee ShiftStrategy, initialise_shift_parameters.\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.DontUpdate","page":"API","title":"Rimu.DontUpdate","text":"DontUpdate(; target_walkers = 1_000) <: ShiftStrategy\n\nDon't update the shift. Return when target_walkers is reached.\n\nSee ShiftStrategy, ProjectorMonteCarloProblem.\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.DoubleLogProjected","page":"API","title":"Rimu.DoubleLogProjected","text":"DoubleLogProjected(; target, projector, ζ = 0.08, ξ = ζ^2/4) <: ShiftStrategy\n\nStrategy for updating the shift according to the log formula with damping parameter ζ and ξ after projecting onto projector.\n\nS^n+1 = S^n -fracζdτlnleft(fracPΨ^(n+1)PΨ^(n)right)-fracξdτlnleft(fracPΨ^(n+1)texttargetright)\n\nNote that adjusting the keyword maxlength in ProjectorMonteCarloProblem is advised as the default may not be appropriate.\n\nSee ShiftStrategy, ProjectorMonteCarloProblem.\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.DoubleLogSumUpdate","page":"API","title":"Rimu.DoubleLogSumUpdate","text":"DoubleLogSumUpdate(; target_walkers = 1000, ζ = 0.08, ξ = ζ^2/4, α = 1/2) <: ShiftStrategy\n\nStrategy for updating the shift according to the log formula with damping parameters ζ and ξ.\n\nS^n+1 = S^n -fracζdτlnleft(fracN_mathrmw^n+1N_mathrmw^nright)\n- fracξdτlnleft(fracN_mathrmw^n+1N_mathrmw^texttargetright)\n\nwhere N_mathrmw = (1-α)*walkernumber() + α*UniformProjector()⋅ψ computed with walkernumber() and UniformProjector(). When ξ = ζ^2/4 this corresponds to critical damping with a damping time scale T = 2/ζ.\n\nSee ShiftStrategy, ProjectorMonteCarloProblem.\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.DoubleLogUpdate","page":"API","title":"Rimu.DoubleLogUpdate","text":"DoubleLogUpdate(; target_walkers = 1_000, ζ = 0.08, ξ = ζ^2/4) <: ShiftStrategy\n\nStrategy for updating the shift according to the log formula with damping parameter ζ and ξ.\n\nS^n+1 = S^n -fracζdτlnleft(fracΨ_1^n+1Ψ_1^nright)-fracξdτlnleft(fracΨ_1^n+1Ψ_1^texttargetright)\n\nWhen ξ = ζ^2/4 this corresponds to critical damping with a damping time scale T = 2/ζ.\n\nSee ShiftStrategy, ProjectorMonteCarloProblem.\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.DoubleLogUpdateAfterTargetWalkers","page":"API","title":"Rimu.DoubleLogUpdateAfterTargetWalkers","text":"DoubleLogUpdateAfterTargetWalkers(target_walkers = 1_000, ζ = 0.08, ξ = ζ^2/4) <: ShiftStrategy\n\nStrategy for updating the shift: After target_walkers is reached, update the shift according to the log formula with damping parameter ζ and ξ.\n\nSee DoubleLogUpdate, ShiftStrategy, ProjectorMonteCarloProblem.\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.FCIQMC","page":"API","title":"Rimu.FCIQMC","text":"FCIQMC(; kwargs...) <: PMCAlgorithm\n\nAlgorithm for the full configuration interaction quantum Monte Carlo (FCIQMC) method. The default algorithm for ProjectorMonteCarloProblem.\n\nKeyword arguments and defaults:\n\nshift_strategy = DoubleLogUpdate(; targetwalkers = 1_000, ζ = 0.08, ξ = ζ^2/4): How to update the shift.\ntime_step_strategy = ConstantTimeStep(): Adjust time step or not.\n\nSee also ProjectorMonteCarloProblem, ShiftStrategy, TimeStepStrategy, DoubleLogUpdate, ConstantTimeStep.\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.FciqmcRunStrategy","page":"API","title":"Rimu.FciqmcRunStrategy","text":" FciqmcRunStrategy{T}\n\nAbstract type representing the strategy for running and terminating lomc!(). The type parameter T is relevant for reporting the shift and the norm.\n\nImplemented strategies:\n\nRunTillLastStep\n\nwarning: Warning\nThe use of this strategy is deprecated. Pass the relevant arguments directly to ProjectorMonteCarloProblem or to lomc!() instead.\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.FirstOrderTransitionOperator","page":"API","title":"Rimu.FirstOrderTransitionOperator","text":"FirstOrderTransitionOperator(hamiltonian, shift, time_step) <: AbstractHamiltonian\nFirstOrderTransitionOperator(sp::DefaultShiftParameters, hamiltonian)\n\nFirst order transition operator\n\n𝐓 = 1 + dτ(S - 𝐇)\n\nwhere 𝐇 is the hamiltonian, dτ the time_step and S is the shift.\n\n𝐓 represents the first order expansion of the exponential evolution operator of the imaginary-time Schrödinger equation (Euler step) and repeated application will project out the ground state eigenvector of the hamiltonian. It is the transition operator used in FCIQMC.\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.GramSchmidt","page":"API","title":"Rimu.GramSchmidt","text":"GramSchmidt(S; orthogonalization_interval = 1) <: SpectralStrategy{S}\n\nUse the Gram-Schmidt procedure to orthogonalize the excited states. A total of S spectral states are used in the simulation, and they are orthogonalized every orthogonalization_interval steps.\n\nUse with the keyword argument spectral_strategy in ProjectorMonteCarloProblem.\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.LogUpdate","page":"API","title":"Rimu.LogUpdate","text":"LogUpdate(ζ = 0.08) <: ShiftStrategy\n\nStrategy for updating the shift according to the log formula with damping parameter ζ.\n\nS^n+1 = S^n -fracζdτlnleft(fracΨ_1^n+1Ψ_1^nright)\n\nSee ShiftStrategy, ProjectorMonteCarloProblem.\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.LogUpdateAfterTargetWalkers","page":"API","title":"Rimu.LogUpdateAfterTargetWalkers","text":"LogUpdateAfterTargetWalkers(target_walkers = 1_000, ζ = 0.08) <: ShiftStrategy\n\nStrategy for updating the shift: After target_walkers is reached, update the shift according to the log formula with damping parameter ζ.\n\nSee LogUpdate, ShiftStrategy, ProjectorMonteCarloProblem.\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.MultiScalar","page":"API","title":"Rimu.MultiScalar","text":"MultiScalar\n\nWrapper over a tuple that supports +, *, min, and max. Used with MPI communication because SVectors are treated as arrays by MPI.Allreduce and Tuples do not support scalar operations.\n\nExample\n\nSuppose you want to compute the sum of a vector dv and also get the number of positive elements it has in a single pass. You can use MultiScalar:\n\njulia> dv = DVec(:a => 1, :b => -2, :c => 1);\n\njulia> s, p = mapreduce(+, values(dv)) do v\n Rimu.MultiScalar(v, Int(sign(v) == 1))\nend;\n\njulia> s, p\n(0, 2)\n\nNote that only MultiScalars with the same types can be operated on. This is a feature, as it forces type stability.\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.NoStats","page":"API","title":"Rimu.NoStats","text":"NoStats(N=1) <: ReplicaStrategy{N}\n\nThe default ReplicaStrategy. N replicas are run, but no statistics are collected.\n\nSee also ProjectorMonteCarloProblem.\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.PMCAlgorithm","page":"API","title":"Rimu.PMCAlgorithm","text":"PMCAlgorithm\n\nAbstract type for projector Monte Carlo algorithms.\n\nSee ProjectorMonteCarloProblem, FCIQMC.\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.PMCSimulation","page":"API","title":"Rimu.PMCSimulation","text":"PMCSimulation\n\nHolds the state and the results of a projector quantum Monte Carlo (PMC) simulation. Is returned by init(::ProjectorMonteCarloProblem) and solved with solve!(::PMCSimulation).\n\nObtain the results of a simulation sm as a DataFrame with DataFrame(sm).\n\nFields\n\nproblem::ProjectorMonteCarloProblem: The problem that was solved\nstate::Rimu.ReplicaState: The current state of the simulation\nreport::Rimu.Report: The report of the simulation\nmodified::Bool: Whether the simulation has been modified\naborted::Bool: Whether the simulation has been aborted\nsuccess::Bool: Whether the simulation has been completed successfully\nmessage::String: A message about the simulation status\nelapsed_time::Float64: The time elapsed during the simulation\n\nSee also state_vectors, ProjectorMonteCarloProblem, init, solve!.\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.PostStepStrategy","page":"API","title":"Rimu.PostStepStrategy","text":"PostStepStrategy\n\nSubtypes of PostStepStrategy can be used to perform arbitrary computation on a single state after an FCIQMC step is finished and report the results.\n\nImplemented strategies:\n\nProjectedEnergy\nProjector\nSignCoherence\nWalkerLoneliness\nTimer\n\nNote: A tuple of multiple strategies can be passed to ProjectorMonteCarloProblem. In that case, all reported column names must be distinct.\n\nInterface:\n\nA subtype of this type must implement post_step_action(::PostStepStrategy, ::SingleState, step::Int).\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.ProjectedEnergy","page":"API","title":"Rimu.ProjectedEnergy","text":"ProjectedEnergy(hamiltonian, projector; hproj=:hproj, vproj=:vproj) <: PostStepStrategy\n\nAfter every step, compute hproj = dot(projector, hamiltonian, dv) and vproj = dot(projector, dv), where dv is the instantaneous coefficient vector. projector can be an AbstractDVec, or an AbstractProjector.\n\nReports to columns hproj and vproj, which can be used to compute projective energy, e.g. with projected_energy. The keyword arguments hproj and vproj can be used to change the names of these columns. This can be used to make the names unique when computing projected energies with different projectors in the same run.\n\nSee also projected_energy, ratio_of_means, mixed_estimator, and PostStepStrategy.\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.Projector","page":"API","title":"Rimu.Projector","text":"Projector(name=projector) <: PostStepStrategy\n\nAfter each step, compute dot(projector, dv) and report it in the DataFrame under name. projector can be an AbstractDVec, or an AbstractProjector.\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.ProjectorMonteCarloProblem","page":"API","title":"Rimu.ProjectorMonteCarloProblem","text":"ProjectorMonteCarloProblem(hamiltonian::AbstractHamiltonian; kwargs...)\n\nDefines a problem to be solved by projector quantum Monte Carlo (QMC) methods, such as the the FCIQMC algorithm.\n\nCommon keyword arguments and defaults:\n\ntime_step = 0.01: Initial time step size.\nlast_step = 100: Controls the number of steps.\ntarget_walkers = 1_000: Target for the 1-norm of the coefficient vector.\nstart_at = starting_address(hamiltonian): Define the initial state vector(s). An r s matrix of state vectors can be passed where r is the number of replicas and s the number of spectral states. See also default_starting_vector.\nstyle = IsDynamicSemistochastic(): The StochasticStyle of the simulation.\ninitiator = false: Whether to use initiators. Can be true, false, or a valid InitiatorRule.\nthreading: Default is to use multithreading and/or MPI if available. Set to true to force PDVec for the starting vector, false for serial computation; may be overridden by start_at.\nreporting_strategy = ReportDFAndInfo(): How and when to report results, see ReportingStrategy.\npost_step_strategy = (): Extract observables (e.g. ProjectedEnergy), see PostStepStrategy.\nn_replicas = 1: Number of synchronised independent simulations.\nreplica_strategy = NoStats(n_replicas): Which results to report from replica simulations, see ReplicaStrategy.\nn_spectral = 1: Number of targeted spectral states. Set n_spectral > 1 to find excited states.\nspectral_strategy = GramSchmidt(n_spectral): The SpectralStrategy used for orthogonalizing spectral states.\n\nExample\n\njulia> hamiltonian = HubbardReal1D(BoseFS(1,2,3));\n\njulia> problem = ProjectorMonteCarloProblem(hamiltonian; target_walkers = 500, last_step = 100);\n\njulia> simulation = solve(problem);\n\njulia> simulation.success[]\ntrue\n\njulia> size(DataFrame(simulation))\n(100, 9)\n\nFurther keyword arguments:\n\nstarting_step = 1: Starting step of the simulation.\nwall_time = Inf: Maximum time allowed for the simulation.\nsimulation_plan = SimulationPlan(; starting_step, last_step, wall_time): Defines the duration of the simulation. Takes precedence over last_step and wall_time.\nζ = 0.08: Damping parameter for the shift update.\nξ = ζ^2/4: Forcing parameter for the shift update.\nshift_strategy = DoubleLogUpdate(; target_walkers, ζ, ξ): How to update the shift, see ShiftStrategy.\ntime_step_strategy = ConstantTimeStep(): Adjust time step or not, see TimeStepStrategy.\nalgorithm = FCIQMC(; shift_strategy, time_step_strategy): The algorithm to use. Currenlty only FCIQMC is implemented.\nshift: Initial shift value or collection of shift values. Determined by default from the Hamiltonian and the starting vectors.\ninitial_shift_parameters: Initial shift parameters or collection of initial shift parameters. Overrides shift if provided.\nmax_length = 2 * target_walkers + 100: Maximum length of the vectors.\ndisplay_name = \"PMCSimulation\": Name displayed in progress bar (via ProgressLogging).\nmetadata: User-supplied metadata to be added to the report. Must be an iterable of pairs or a NamedTuple, e.g. metadata = (\"key1\" => \"value1\", \"key2\" => \"value2\"). All metadata is converted to strings.\nrandom_seed = true: Provide and store a seed for the random number generator. If set to true, a new random seed is generated from RandomDevice(). If set to number, this number is used as the seed. This seed is used by solve (and init) to re-seed the default random number generator (consistently on each MPI rank) such that solveing the same ProjectorMonteCarloProblem twice will yield identical results. If set to false, no seed is used and consecutive random numbers are used.\nminimum_size = 2*num_spectral_states(spectral_strategy): The minimum size of the basis used to construct starting vectors for simulations of spectral states, if start_at is not provided.\n\nSee also init, solve.\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.ReplicaState","page":"API","title":"Rimu.ReplicaState","text":"ReplicaState <: AbstractMatrix{SingleState}\n\nHolds information about multiple replicas of SpectralStates. Indexing the ReplicaState state[i, j] returns a SingleState from the ith replica and jth spectral state.\n\nFields\n\nspectral_states: Tuple of SpectralStates\nmax_length::Ref{Int}: Maximum length of the simulation\nstep::Ref{Int}: Current step of the simulation\nsimulation_plan: Simulation plan\nreporting_strategy: Reporting strategy\npost_step_strategy: Post-step strategy\nreplica_strategy: Replica strategy\n\nSee also ReplicaStrategy, Rimu.SpectralState, Rimu.SingleState, Rimu.PMCSimulation.\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.ReplicaStrategy","page":"API","title":"Rimu.ReplicaStrategy","text":"ReplicaStrategy{N}\n\nSupertype for strategies that can be passed to ProjectorMonteCarloProblem and control how many replicas are used, and what information is computed and returned. The number of replicas is N.\n\nConcrete implementations\n\nNoStats: run (possibly one) replica(s), but don't report any additional info.\nAllOverlaps: report overlaps between all pairs of replica vectors.\n\nInterface\n\nA subtype of ReplicaStrategy{N} must implement the following function:\n\nRimu.replica_stats - return a tuple of Strings or Symbols of names for replica statistics and a tuple of the values. These will be reported to the DataFrame returned by ProjectorMonteCarloProblem.\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.Report","page":"API","title":"Rimu.Report","text":"Report()\nReport(df::DataFrame)\n\nInternal structure that holds the temporary reported values as well as metadata. It can be converted to a DataFrame with DataFrame(report::Report).\n\nSee report!, report_metadata!, get_metadata.\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.ReportDFAndInfo","page":"API","title":"Rimu.ReportDFAndInfo","text":"ReportDFAndInfo(; reporting_interval=1, info_interval=100, io=stdout, writeinfo=false) <: ReportingStrategy\n\nThe default ReportingStrategy for ProjectorMonteCarloProblem. Report every reporting_intervalth step to a DataFrame and write info message to io every info_intervalth reported step (unless writeinfo == false). The flag writeinfo is useful for controlling info messages in MPI codes, e.g. by setting writeinfo =is_mpi_root().\n\nSee also ProjectorMonteCarloProblem, ReportToFile.\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.ReportToFile","page":"API","title":"Rimu.ReportToFile","text":"ReportToFile(; kwargs...) <: ReportingStrategy\n\nReportingStrategy for ProjectorMonteCarloProblem that writes the report directly to a file in the Arrow format. Useful when dealing with long jobs or large numbers of replicas, when the report can incur a significant memory cost.\n\nThe arrow file can be read back in with load_df(filename) or using Arrow; Arrow.Table(filename).\n\nKeyword arguments\n\nfilename = \"out.arrow\": the file to report to. If the file already exists, a new file is created.\nreporting_interval = 1: interval between simulation steps that are reported.\nchunk_size = 1000: the size of each chunk that is written to the file. A DataFrame of this size is collected in memory and written to disk. When saving, an info message is also printed to io.\nsave_if =is_mpi_root(): if this value is true, save the report, otherwise ignore it.\nreturn_df = false: if this value is true, read the file and return the data frame at the end of computation. Otherwise, an empty DataFrame is returned.\nio = stdout: The IO to print messages to. Set to devnull if you don't want to see messages printed out.\ncompress = :zstd: compression algorithm to use. Can be :zstd, :lz4 or nothing.\n\nSee also load_df, save_df, ReportDFAndInfo, and ProjectorMonteCarloProblem.\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.ReportingStrategy","page":"API","title":"Rimu.ReportingStrategy","text":"ReportingStrategy\n\nAbstract type for strategies for reporting data during a simulation of a ProjectorMonteCarloProblem.\n\nImplemented strategies:\n\nReportDFAndInfo\nReportToFile\n\nExtended help\n\nInterface:\n\nA ReportingStrategy can define any of the following:\n\nRimu.refine_reporting_strategy\nRimu.report!\nRimu.report_after_step!\nRimu.finalize_report!\nRimu.reporting_interval\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.RunTillLastStep","page":"API","title":"Rimu.RunTillLastStep","text":"RunTillLastStep(step::Int = 0 # number of current/starting timestep\n laststep::Int = 100 # number of final timestep\n shiftMode::Bool = false # whether to adjust shift\n shift = 0.0 # starting/current value of shift\n dτ::Float64 = 0.01 # current value of time step\n) <: FciqmcRunStrategy\n\nParameters for running lomc!() for a fixed number of time steps. For alternative strategies, see FciqmcRunStrategy.\n\nwarning: Warning\nThe use of this strategy is deprecated. Pass the relevant arguments directly to ProjectorMonteCarloProblem or to lomc!() instead.\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.ShiftStrategy","page":"API","title":"Rimu.ShiftStrategy","text":"ShiftStrategy\n\nAbstract type for defining the strategy for controlling the norm, potentially by updating the shift. Passed as a parameter to ProjectorMonteCarloProblem or to FCIQMC.\n\nImplemented strategies:\n\nDontUpdate\nDoubleLogUpdate - default in ProjectorMonteCarloProblem()\nLogUpdate\nLogUpdateAfterTargetWalkers - FCIQMC standard\nDoubleLogUpdateAfterTargetWalkers\n\nExtended help\n\nInternally To implement a custom strategy, define a new subtype of Rimu.ShiftStrategy and implement methods for:\n\nRimu.update_shift_parameters! - to update the shift_parameters\nRimu.initialise_shift_parameters - (optional) to initialise and construct a custom implementation of the shift_parameters. The default implementation is Rimu.DefaultShiftParameters.\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.SignCoherence","page":"API","title":"Rimu.SignCoherence","text":"SignCoherence(reference[; name=:coherence]) <: PostStepStrategy\n\nAfter each step, compute the proportion of configurations that have the same sign as they do in the reference_dvec. Reports to a column named name, which defaults to coherence.\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.SimulationPlan","page":"API","title":"Rimu.SimulationPlan","text":"SimulationPlan(; starting_step = 1, last_step = 100, wall_time = Inf)\n\nDefines the duration of the simulation. The simulation ends when the last_step is reached or the wall_time is exceeded.\n\nSee ProjectorMonteCarloProblem, PMCSimulation.\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.SingleParticleDensity","page":"API","title":"Rimu.SingleParticleDensity","text":"SingleParticleDensity(; save_every=1, component) <: PostStepStrategy\n\nPostStepStrategy to compute the diagonal single_particle_density. It records a Tuple with the same eltype as the vector.\n\nComputing the density at every time step can be expensive. This cost can be reduced by setting the save_every argument to a higher value. If the value is set, a vector of zeros is recorded when the saving is skipped.\n\nIf the address type has multiple components, the component argument can be used to compute the density on a per-component basis.\n\nThe density is not normalized, and must be divided by the vector norm(⋅,2) squared.\n\nSee also\n\nsingle_particle_density\nDensityMatrixDiagonal\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.SingleState","page":"API","title":"Rimu.SingleState","text":"SingleState(hamiltonian, algorithm, v, wm, pnorm, params, id)\n\nStruct that holds a single state vector and all information needed for an independent run of the algorithm. Can be advanced a step forward with Rimu.advance!.\n\nFields\n\nhamiltonian: Hamiltonian\nalgorithm: Algorithm\nv: Vector\npv: Previous vector\nwm: Working memory\nshift_parameters: Shift parameters\nid::String: id is appended to column names\n\nSee also SpectralStrategy, ReplicaStrategy, Rimu.SpectralState, Rimu.ReplicaState, Rimu.replica_stats, Rimu.PMCSimulation.\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.SpectralState","page":"API","title":"Rimu.SpectralState","text":"SpectralState <: AbstractVector{SingleState}\n\nHolds one or several Rimu.SingleStates representing the ground state and excited states of a single replica. Indexing the SpectralState state[i] returns the ith SingleState.\n\nFields\n\nsingle_states: Tuple of SingleStates\nspectral_strategy: Strategy for computing the spectral states\nid::String: Identifies the replica\n\nSee also SpectralStrategy, Rimu.ReplicaState, Rimu.SingleState, Rimu.PMCSimulation.\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.SpectralStrategy","page":"API","title":"Rimu.SpectralStrategy","text":"SpectralStrategy{S}\n\nAbstract type for spectral strategies. The spectral strategy is used to control the number of spectral states used in the simulation.\n\nImplemented Strategies\n\nGramSchmidt: Orthogonalize the spectral states using the Gram-Schmidt procedure.\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.StateVectors","page":"API","title":"Rimu.StateVectors","text":"StateVectors <: AbstractMatrix{V}\n\nRepresents a matrix of configuration vectors from the state. Construct this object with state_vectors.\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.TimeStepStrategy","page":"API","title":"Rimu.TimeStepStrategy","text":"TimeStepStrategy\n\nAbstract type for strategies for updating the time step with update_time_step(). Implemented strategies:\n\nConstantTimeStep\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.Timer","page":"API","title":"Rimu.Timer","text":"Timer <: PostStepStrategy\n\nRecord current time after every step. See Base.Libc.time for information on what time is recorded.\n\n\n\n\n\n","category":"type"},{"location":"API.html#Rimu.WalkerLoneliness","page":"API","title":"Rimu.WalkerLoneliness","text":"WalkerLoneliness(threshold=1) <: PostStepStrategy\n\nAfter each step, compute the proportion of configurations that are occupied by at most threshold walkers. Reports to a column named loneliness.\n\n\n\n\n\n","category":"type"},{"location":"API.html#CommonSolve.init-Tuple{ProjectorMonteCarloProblem}","page":"API","title":"CommonSolve.init","text":"init(problem::ProjectorMonteCarloProblem; copy_vectors=true)::PMCSimulation\n\nInitialise a Rimu.PMCSimulation.\n\nSee also ProjectorMonteCarloProblem, solve!, solve, step!, Rimu.PMCSimulation.\n\n\n\n\n\n","category":"method"},{"location":"API.html#CommonSolve.solve","page":"API","title":"CommonSolve.solve","text":"solve(::ProjectorMonteCarloProblem)::PMCSimulation\n\nInitialize and solve a ProjectorMonteCarloProblem until the last step is completed or the wall time limit is reached.\n\nSee also init, solve!, step!, Rimu.PMCSimulation, and solve(::ExactDiagonalizationProblem).\n\n\n\n\n\n","category":"function"},{"location":"API.html#CommonSolve.solve!-Tuple{Rimu.PMCSimulation}","page":"API","title":"CommonSolve.solve!","text":"solve!(sm::PMCSimulation; kwargs...)::PMCSimulation\n\nSolve a Rimu.PMCSimulation until the last step is completed or the wall time limit is reached.\n\nTo continue a previously completed simulation, set a new last_step or wall_time using the keyword arguments. Optionally, changes can be made to the replica_strategy, the post_step_strategy, or the reporting_strategy.\n\nOptional keyword arguments:\n\nlast_step = nothing: Set the last step to a new value and continue the simulation.\nwall_time = nothing: Set the allowed wall time to a new value and continue the simulation.\nreset_time = false: Reset the elapsed_time counter and continue the simulation.\nempty_report = false: Empty the report before continuing the simulation.\nreplica_strategy = nothing: Change the replica strategy. Requires the number of replicas to match the number of replicas in the simulation sm. Implies empty_report = true.\npost_step_strategy = nothing: Change the post-step strategy. Implies empty_report = true.\nreporting_strategy = nothing: Change the reporting strategy. Implies empty_report = true.\nmetadata = nothing: Add metadata to the report.\n\nSee also ProjectorMonteCarloProblem, init, solve, step!, Rimu.PMCSimulation.\n\n\n\n\n\n","category":"method"},{"location":"API.html#CommonSolve.step!-Tuple{Rimu.PMCSimulation}","page":"API","title":"CommonSolve.step!","text":"step!(sm::PMCSimulation)::PMCSimulation\n\nAdvance the simulation by one step.\n\nCalling solve! will advance the simulation until the last step or the wall time is exceeded. When completing the simulation without calling solve!, the simulation report needs to be finalised by calling Rimu.finalize_report!.\n\nSee also ProjectorMonteCarloProblem, init, solve!, solve, Rimu.PMCSimulation.\n\n\n\n\n\n","category":"method"},{"location":"API.html#Rimu.advance!-Tuple{FCIQMC, Any, Rimu.ReplicaState, Rimu.SingleState}","page":"API","title":"Rimu.advance!","text":"advance!(algorithm::PMCAlgorithm, report::Report, state::ReplicaState, s_state::SingleState)\n\nAdvance the s_state by one step according to the algorithm. The state is used only to access the various strategies involved. Steps, stats, and computed quantities are written to the report.\n\nReturns true if the step was successful and calculation should proceed, false when it should terminate.\n\nSee also solve!, step!.\n\n\n\n\n\n","category":"method"},{"location":"API.html#Rimu.all_overlaps-Union{Tuple{B}, Tuple{N}, Tuple{Union{Tuple, Vector}, NTuple{N, AbstractDVec}, Any, Val{B}}} where {N, B}","page":"API","title":"Rimu.all_overlaps","text":"all_overlaps(operators, vectors, working_memories, vecnorm=true)\n\nGet all overlaps between vectors and operators. The flag vecnorm can disable the vector-vector overlap c{i}_dot_c{j}.\n\n\n\n\n\n","category":"method"},{"location":"API.html#Rimu.check_transform-Tuple{AllOverlaps, AbstractHamiltonian}","page":"API","title":"Rimu.check_transform","text":"check_transform(r::AllOverlaps, ham)\n\nCheck that the transformation provided to r::AllOverlaps matches the given Hamiltonian ham. Used as a sanity check before starting main ProjectorMonteCarloProblem loop.\n\n\n\n\n\n","category":"method"},{"location":"API.html#Rimu.clean_and_warn_if_others_present-Union{Tuple{names}, Tuple{NamedTuple{names}, Any}} where names","page":"API","title":"Rimu.clean_and_warn_if_others_present","text":"clean_and_warn_if_others_present(nt::NamedTuple{names}, keys) where {names}\n\nRemove keys from a NamedTuple that are not in keys and issue a warning if they are present.\n\n\n\n\n\n","category":"method"},{"location":"API.html#Rimu.default_logger-Tuple","page":"API","title":"Rimu.default_logger","text":"default_logger(args...)\n\nReset the global_logger to Logging.ConsoleLogger. Undoes the effect of smart_logger. Arguments are passed on to Logging.ConsoleLogger.\n\n\n\n\n\n","category":"method"},{"location":"API.html#Rimu.default_starting_vector-Tuple{AbstractHamiltonian}","page":"API","title":"Rimu.default_starting_vector","text":"default_starting_vector(hamiltonian::AbstractHamiltonian; kwargs...)\ndefault_starting_vector(\n address=starting_address(hamiltonian);\n style=IsDynamicSemistochastic(),\n initiator=NonInitiator(),\n threading=nothing,\n population=10\n)\n\nReturn a default starting vector for ProjectorMonteCarloProblem. The default choice for the starting vector is\n\nv = PDVec(address => population; style, initiator)\n\nif threading is available, or otherwise\n\nv = DVec(address => population; style)\n\nif initiator == NonInitiator(), and\n\nv = InitiatorDVec(address => population; style, initiator)\n\nif not. See PDVec, DVec, InitiatorDVec, StochasticStyle, and InitiatorRule.\n\n\n\n\n\n","category":"method"},{"location":"API.html#Rimu.delete_and_warn_if_present-Union{Tuple{names}, Tuple{NamedTuple{names}, Any}} where names","page":"API","title":"Rimu.delete_and_warn_if_present","text":"delete_and_warn_if_present(nt::NamedTuple, keys)\n\nDelete keys from a NamedTuple and issue a warning if they are present. This is useful for removing unused keyword arguments.\n\n\n\n\n\n","category":"method"},{"location":"API.html#Rimu.finalize_report!-Tuple{ReportingStrategy, Any}","page":"API","title":"Rimu.finalize_report!","text":"finalize_report!(::ReportingStrategy, report)\n\nFinalize the report. This function is called after all steps in solve! have finished.\n\n\n\n\n\n","category":"method"},{"location":"API.html#Rimu.get_metadata-Tuple{Rimu.Report, Any}","page":"API","title":"Rimu.get_metadata","text":"get_metadata(report::Report, key)\n\nGet metadata key from report. key is converted to a String.\n\nSee also report_metadata!, Report, report!.\n\n\n\n\n\n","category":"method"},{"location":"API.html#Rimu.initialise_shift_parameters","page":"API","title":"Rimu.initialise_shift_parameters","text":"initialise_shift_parameters(s::ShiftStrategy, shift, norm, time_step, counter=0, shift_mode=false)\n\nInitiatlise a struct to store the shift parameters.\n\nSee ShiftStrategy, update_shift_parameters!, DefaultShiftParameters.\n\n\n\n\n\n","category":"function"},{"location":"API.html#Rimu.is_mpi_root","page":"API","title":"Rimu.is_mpi_root","text":"is_mpi_root(root = mpi_root)\n\nReturns true if called from the root rank\n\n\n\n\n\n","category":"function"},{"location":"API.html#Rimu.lomc!-Tuple{Any, Any}","page":"API","title":"Rimu.lomc!","text":"lomc!(ham::AbstractHamiltonian, [v]; kwargs...) -> df, state\nlomc!(state::ReplicaState, [df]; kwargs...) -> df, state\n\nLinear operator Monte Carlo: Perform a projector quantum Monte Carlo simulation for determining the lowest eigenvalue of ham. The details of the simulation are controlled by the optional keyword arguments and by the type of the optional starting vector v. Alternatively, a ReplicaState can be passed in to continue a previous simulation.\n\nCommon keyword arguments and defaults:\n\nlaststep = 100 - controls the number of steps.\ndτ = 0.01 - time step.\ntargetwalkers = 1000 - target for the 1-norm of the coefficient vector.\naddress = starting_address(ham) - set starting address for default v and shift.\nstyle = IsStochasticInteger() - set StochasticStyle for default v; unused if v is specified.\ninitiator = NonInitiator() - set InitiatorRule for default v; unused if v is specified.\nthreading - default is to use multithreading and MPI if multiple threads are available. Set to true to force PDVec for the starting vector, false for serial computation; unused if v is specified.\nshift = diagonal_element(ham, address) - initial value of shift.\npost_step_strategy::NTuple{N,<:PostStepStrategy} = () - extract observables (e.g. ProjectedEnergy), see PostStepStrategy. (Deprecated: post_step is accepted as an alias for post_step_strategy.)\nreplica_strategy::ReplicaStrategy = NoStats(1) - run several synchronised simulations, see ReplicaStrategy. (Deprecated: replica is accepted as an alias for replica_strategy.)\nreporting_strategy::ReportingStrategy = ReportDFAndInfo() - how and when to report results, see ReportingStrategy. (Deprecated: r_strat is accepted as an alias for reporting_strategy.)\nname = \"lomc!\" - name displayed in progress bar (via ProgressLogging)\nmetadata - user-supplied metadata to be added to the report df. Must be an iterable of pairs or a NamedTuple, e.g. metadata = (\"key1\" => \"value1\", \"key2\" => \"value2\"). All metadata is converted to strings.\n\nSome metadata is automatically added to the report df including Rimu.PACKAGE_VERSION and data from state.\n\nReturn values\n\nlomc! returns a named tuple with the following fields:\n\ndf: a DataFrame with all statistics being reported.\nstate: a ReplicaState that can be used for continuations.\n\nExample\n\njulia> address = BoseFS(1,2,3);\n\njulia> hamiltonian = HubbardReal1D(address);\n\njulia> df1, state = @suppress lomc!(hamiltonian; targetwalkers=500, laststep=100);\n\njulia> df2, _ = @suppress lomc!(state, df1; laststep=200, metadata=(;info=\"cont\")); # Continuation run\n\njulia> size(df1)\n(100, 9)\n\njulia> size(df2)\n(200, 9)\n\njulia> using DataFrames; metadata(df2, \"info\") # retrieve custom metadata\n\"cont\"\n\njulia> metadata(df2, \"hamiltonian\") # some metadata is automatically added\n\"HubbardReal1D(fs\\\"|1 2 3⟩\\\"; u=1.0, t=1.0)\"\n\nFurther keyword arguments and defaults:\n\nτ_strat::TimeStepStrategy = ConstantTimeStep() - adjust time step or not, see TimeStepStrategy\ns_strat::ShiftStrategy = DoubleLogUpdate(; target_walkers=targetwalkers, ζ = 0.08, ξ = ζ^2/4) - how to update the shift, see ShiftStrategy.\nmaxlength = 2 * s_strat.target_walkers + 100 - upper limit on the length of v; when reached, lomc! will abort\nwm - working memory for re-use in subsequent calculations; is mutated.\ndf = DataFrame() - when called with AbstractHamiltonian argument, a DataFrame can be passed for merging with the report df.\n\nThe default choice for the starting vector is v = default_starting_vector(; address, style, threading, initiator). See default_starting_vector, PDVec, DVec, StochasticStyle, and InitiatorRule.\n\nwarning: Warning\nThe use of this lomc! is deprecated. Use ProjectorMonteCarloProblem and solve instead.\n\n\n\n\n\n","category":"method"},{"location":"API.html#Rimu.mpi_allprintln-Tuple","page":"API","title":"Rimu.mpi_allprintln","text":"mpi_allprintln(args...)\n\nPrint a message to stdout from each rank separately, in order. MPI synchronizing.\n\n\n\n\n\n","category":"method"},{"location":"API.html#Rimu.mpi_barrier","page":"API","title":"Rimu.mpi_barrier","text":"mpi_barrier(comm = mpi_comm())\n\nThe MPI barrier with optional argument. MPI syncronizing.\n\n\n\n\n\n","category":"function"},{"location":"API.html#Rimu.mpi_rank","page":"API","title":"Rimu.mpi_rank","text":"mpi_rank(comm = mpi_comm())\n\nReturn the current MPI rank.\n\n\n\n\n\n","category":"function"},{"location":"API.html#Rimu.mpi_seed!","page":"API","title":"Rimu.mpi_seed!","text":"mpi_seed!(seed = rand(Random.RandomDevice(), UInt))\n\nRe-seed the random number generators in an MPI-safe way. If seed is provided, the random numbers from rand will follow a deterministic sequence.\n\nIndependence of the random number generators on different MPI ranks is achieved by adding hash(mpi_rank()) to seed.\n\n\n\n\n\n","category":"function"},{"location":"API.html#Rimu.mpi_size","page":"API","title":"Rimu.mpi_size","text":"mpi_size(comm = mpi_comm())\n\nSize of MPI communicator.\n\n\n\n\n\n","category":"function"},{"location":"API.html#Rimu.num_replicas-Union{Tuple{ReplicaStrategy{N}}, Tuple{N}} where N","page":"API","title":"Rimu.num_replicas","text":"num_replicas(state_or_strategy)\n\nReturn the number of replicas used in the simulation.\n\n\n\n\n\n","category":"method"},{"location":"API.html#Rimu.num_spectral_states-Union{Tuple{Rimu.SpectralStrategy{S}}, Tuple{S}} where S","page":"API","title":"Rimu.num_spectral_states","text":"num_spectral_states(state_or_strategy)\n\nReturn the number of spectral states used in the simulation.\n\n\n\n\n\n","category":"method"},{"location":"API.html#Rimu.post_step_action","page":"API","title":"Rimu.post_step_action","text":"post_step_action(::PostStepStrategy, ::SingleState, step) -> kvpairs\n\nCompute statistics after FCIQMC step. Should return a tuple of :key => value pairs. This function is only called every reporting_interval steps, as defined by the ReportingStrategy.\n\nSee also PostStepStrategy, ReportingStrategy.\n\n\n\n\n\n","category":"function"},{"location":"API.html#Rimu.refine_reporting_strategy-Tuple{ReportingStrategy}","page":"API","title":"Rimu.refine_reporting_strategy","text":"refine_reporting_strategy(reporting_strategy::ReportingStrategy) -> reporting_strategy\n\nInitialize the reporting strategy. This can be used to set up filenames or other attributes that need to be unique for a run of FCIQMC.\n\n\n\n\n\n","category":"method"},{"location":"API.html#Rimu.replace_keys-Tuple{NamedTuple, Any}","page":"API","title":"Rimu.replace_keys","text":"replace_keys(nt::NamedTuple, (:old1 => :new1, :old2 => :new2, ...))\n\nReplace keys in a NamedTuple with new keys. This is useful for renaming fields in a NamedTuple. Ignores keys that are not present in the NamedTuple.\n\n\n\n\n\n","category":"method"},{"location":"API.html#Rimu.replica_stats","page":"API","title":"Rimu.replica_stats","text":"replica_stats(RS::ReplicaStrategy{N}, spectral_states::NTuple{N,SingleState}) -> (names, values)\n\nReturn the names and values of statistics related to N replica states consistent with the ReplicaStrategy RS. names should be a tuple of Symbols or Strings and values should be a tuple of the same length. This function will be called every reporting_interval steps from ProjectorMonteCarloProblem, or once per time step if reporting_interval is not defined.\n\nPart of the ReplicaStrategy interface. See also SingleState.\n\n\n\n\n\n","category":"function"},{"location":"API.html#Rimu.report!-Tuple{ReportingStrategy, Any, Vararg{Any}}","page":"API","title":"Rimu.report!","text":" report!(::ReportingStrategy, step, report::Report, keys, values, id=\"\")\n report!(::ReportingStrategy, step, report::Report, nt, id=\"\")\n\nReport keys and values to report, which will be converted to a DataFrame before ProjectorMonteCarloProblem exits. Alternatively, a nt::NamedTuple can be passed in place of keys and values. If id is specified, it is appended to all keys. This is used to differentiate between values reported by different replicas.\n\nTo overload this function for a new ReportingStrategy, overload report!(::ReportingStrategy, step, args...) and apply the report by calling report!(args...).\n\n\n\n\n\n","category":"method"},{"location":"API.html#Rimu.report!-Tuple{Rimu.Report, DataFrame}","page":"API","title":"Rimu.report!","text":"report!(report::Report, df::DataFrame)\n\nConvert the DataFrame df to a Report. This function does not copy the data.\n\n\n\n\n\n","category":"method"},{"location":"API.html#Rimu.report!-Tuple{Rimu.Report, Union{AbstractString, Symbol}, Any}","page":"API","title":"Rimu.report!","text":"report!(report, keys, values, id=\"\")\nreport!(report, pairs, id=\"\")\n\nWrite keys, values pairs to report that will be converted to a DataFrame later. Alternatively, a named tuple or a collection of pairs can be passed instead of keys and values.\n\nThe value of id is appended to the name of the column, e.g. report!(report, :key, value, :_1) will report value to a column named :key_1.\n\n\n\n\n\n","category":"method"},{"location":"API.html#Rimu.report_after_step!-Tuple{ReportingStrategy, Any, Any, Vararg{Any}}","page":"API","title":"Rimu.report_after_step!","text":"report_after_step!(::ReportingStrategy, step, report, state) -> report\n\nThis function is called at the very end of a step, after Rimu.reporting_interval steps. It may modify the report.\n\n\n\n\n\n","category":"method"},{"location":"API.html#Rimu.report_metadata!-Tuple{Rimu.Report, Any, Any}","page":"API","title":"Rimu.report_metadata!","text":"report_metadata!(report::Report, key, value)\nreport_metadata!(report::Report, kvpairs)\n\nSet metadata key to value in report. key and value are converted to Strings. Alternatively, an iterable of key-value pairs or a NamedTuple can be passed.\n\nSee also get_metadata, report!, Report.\n\n\n\n\n\n","category":"method"},{"location":"API.html#Rimu.reporting_interval-Tuple{ReportingStrategy}","page":"API","title":"Rimu.reporting_interval","text":"reporting_interval(::ReportingStrategy)\n\nGet the interval between steps for which non-essential statistics are reported. Defaults to 1 if chosen ReportingStrategy does not specify an interval.\n\n\n\n\n\n","category":"method"},{"location":"API.html#Rimu.set_up_initial_shift_parameters-Union{Tuple{S}, Tuple{R}, Tuple{FCIQMC, Any, StaticArraysCore.SMatrix{R, S}, Any, Any}} where {R, S}","page":"API","title":"Rimu.set_up_initial_shift_parameters","text":"set_up_initial_shift_parameters(\n algorithm::FCIQMC, hamiltonian, starting_vectors, shift, time_step, initial_shift_parameters\n)\n\nSet up the initial shift parameters for the FCIQMC algorithm.\n\n\n\n\n\n","category":"method"},{"location":"API.html#Rimu.single_particle_density-Tuple{Any}","page":"API","title":"Rimu.single_particle_density","text":"single_particle_density(dvec; component)\nsingle_particle_density(add; component)\n\nCompute the diagonal single particle density of vector dvec or address add. If the component argument is given, only that component of the addresses is taken into account. The result is always normalized so that sum(result) ≈ num_particles(address).\n\nExamples\n\njulia> v = DVec(fs\"|⋅↑⇅↓⋅⟩\" => 1.0, fs\"|↓↓⋅↑↑⟩\" => 0.5)\nDVec{FermiFS2C{2, 2, 5, 4, FermiFS{2, 5, BitString{5, 1, UInt8}}, FermiFS{2, 5, BitString{5, 1, UInt8}}},Float64} with 2 entries, style = IsDeterministic{Float64}()\n fs\"|↓↓⋅↑↑⟩\" => 0.5\n fs\"|⋅↑⇅↓⋅⟩\" => 1.0\n\njulia> single_particle_density(v)\n(0.2, 1.0, 1.6, 1.0, 0.2)\n\njulia> single_particle_density(v; component=1)\n(0.0, 0.8, 0.8, 0.2, 0.2)\n\nSee also\n\nSingleParticleDensity\n\n\n\n\n\n","category":"method"},{"location":"API.html#Rimu.smart_logger-Tuple","page":"API","title":"Rimu.smart_logger","text":"smart_logger(args...)\n\nEnable terminal progress bar during interactive use (i.e. unless running on CI or HPC). Arguments are passed on to the logger. This is run once during Rimu startup. Undo with default_logger or by setting Base.global_logger().\n\n\n\n\n\n","category":"method"},{"location":"API.html#Rimu.state_vectors-Tuple{R} where R<:Rimu.ReplicaState","page":"API","title":"Rimu.state_vectors","text":"state_vectors(state::ReplicaState)\nstate_vectors(sim::PMCSimulation)\n\nReturn an r×s AbstractMatrix of configuration vectors from the state, or the result of solve(::ProjectorMonteCarloProblem). The vectors can be accessed by indexing the resulting collection, where the row index corresponds to the replica index and the column index corresponds to the spectral state index.\n\nSee also ProjectorMonteCarloProblem, Rimu.PMCSimulation, Rimu.SingleState, Rimu.ReplicaState, Rimu.SpectralState.\n\n\n\n\n\n","category":"method"},{"location":"API.html#Rimu.update_shift_parameters!","page":"API","title":"Rimu.update_shift_parameters!","text":"update_shift_parameters!(\n s <: ShiftStrategy,\n shift_parameters,\n tnorm,\n v_new,\n v_old,\n step,\n report\n) -> shift_stats, proceed\n\nUpdate the shift_parameters according to strategy s. See ShiftStrategy. Returns a named tuple of the shift statistics and a boolean proceed indicating whether the simulation should proceed.\n\nSee initialise_shift_parameters, ShiftStrategy.\n\n\n\n\n\n","category":"function"},{"location":"API.html#Rimu.update_time_step-Tuple{ConstantTimeStep, Any, Vararg{Any}}","page":"API","title":"Rimu.update_time_step","text":"update_time_step(s<:TimeStepStrategy, time_step, tnorm) -> new_time_step\n\nUpdate the time step according to the strategy s.\n\n\n\n\n\n","category":"method"},{"location":"API.html#Rimu.@mpi_root-Tuple","page":"API","title":"Rimu.@mpi_root","text":"@mpi_root expr\n\nEvaluate expression only on the root rank. Extra care needs to be taken as expr must not contain any code that involves syncronising MPI operations, i.e. actions that would require syncronous action of all MPI ranks.\n\nExample:\n\nwn = walkernumber(dv) # an MPI syncronising function call that gathers\n # information from all MPI ranks\n@mpi_root @info \"The current walker number is\" wn # print info message on root only\n\n\n\n\n\n","category":"macro"},{"location":"API.html#Reexported-Submodules","page":"API","title":"Reexported Submodules","text":"","category":"section"},{"location":"API.html#ExactDiagonalization","page":"API","title":"ExactDiagonalization","text":"","category":"section"},{"location":"API.html","page":"API","title":"API","text":"See Exact Diagonalization","category":"page"},{"location":"API.html#Interfaces","page":"API","title":"Interfaces","text":"","category":"section"},{"location":"API.html","page":"API","title":"API","text":"See Module Interfaces","category":"page"},{"location":"API.html#StochasticStyles","page":"API","title":"StochasticStyles","text":"","category":"section"},{"location":"API.html","page":"API","title":"API","text":"See Module StochasticStyles","category":"page"},{"location":"API.html#Hamiltonians","page":"API","title":"Hamiltonians","text":"","category":"section"},{"location":"API.html","page":"API","title":"API","text":"See Module Hamiltonians","category":"page"},{"location":"API.html#BitStringAddresses","page":"API","title":"BitStringAddresses","text":"","category":"section"},{"location":"API.html","page":"API","title":"API","text":"See Module BitStringAddresses","category":"page"},{"location":"API.html#DictVectors","page":"API","title":"DictVectors","text":"","category":"section"},{"location":"API.html","page":"API","title":"API","text":"See Module DictVectors","category":"page"},{"location":"API.html#StatsTools","page":"API","title":"StatsTools","text":"","category":"section"},{"location":"API.html","page":"API","title":"API","text":"See Module StatsTools","category":"page"},{"location":"API.html#Index","page":"API","title":"Index","text":"","category":"section"},{"location":"API.html","page":"API","title":"API","text":"","category":"page"},{"location":"stochasticstyles.html#Module-StochasticStyles","page":"Stochastic styles","title":"Module StochasticStyles","text":"","category":"section"},{"location":"stochasticstyles.html","page":"Stochastic styles","title":"Stochastic styles","text":"StochasticStyles","category":"page"},{"location":"stochasticstyles.html#Rimu.StochasticStyles","page":"Stochastic styles","title":"Rimu.StochasticStyles","text":"This module provides concrete implementations of StochasticStyles, which specify the algorithm used by ProjectorMonteCarloProblem when performing stochastic matrix-vector multiplication.\n\nImplemented stochastic styles:\n\nStochasticStyle: abstract type for stochastic styles\nIsStochasticInteger\nIsDeterministic\nIsStochasticWithThreshold\nIsDynamicSemistochastic\nStyleUnknown\n\nThe offdiagonal spawning is defined in spawning.jl and is controlled by setting a SpawningStrategy.\n\nThe vector compression strategies are defined in compression.jl and are controlled by setting a CompressionStrategy.\n\n\n\n\n\n","category":"module"},{"location":"stochasticstyles.html#Available-StochasticStyles","page":"Stochastic styles","title":"Available StochasticStyles","text":"","category":"section"},{"location":"stochasticstyles.html","page":"Stochastic styles","title":"Stochastic styles","text":"StyleUnknown","category":"page"},{"location":"stochasticstyles.html#Rimu.Interfaces.StyleUnknown","page":"Stochastic styles","title":"Rimu.Interfaces.StyleUnknown","text":"StyleUnknown{T}() <: StochasticStyle\n\nTrait for value types not (currently) compatible with FCIQMC. This style makes it possible to construct dict vectors with unsupported valtypes.\n\nSee also StochasticStyle.\n\n\n\n\n\n","category":"type"},{"location":"stochasticstyles.html","page":"Stochastic styles","title":"Stochastic styles","text":"Modules = [StochasticStyles]\nPages = [\"styles.jl\"]","category":"page"},{"location":"stochasticstyles.html#Rimu.StochasticStyles.IsDeterministic","page":"Stochastic styles","title":"Rimu.StochasticStyles.IsDeterministic","text":"IsDeterministic{T=Float64}(compression=NoCompression()) <: StochasticStyle{T}\n\nPropagate with deterministic vector matrix multiplications. Stochastic compression of the resultant vector (after annihilations) can be triggered by setting the optional compression argument to a relevant CompressionStrategy.\n\nSee also StochasticStyle.\n\n\n\n\n\n","category":"type"},{"location":"stochasticstyles.html#Rimu.StochasticStyles.IsDynamicSemistochastic","page":"Stochastic styles","title":"Rimu.StochasticStyles.IsDynamicSemistochastic","text":"IsDynamicSemistochastic{T=Float64}(; kwargs...) <: StochasticStyle{T}\n\nQMC propagation with floating-point walker numbers and reduced noise. All possible spawns (offdiagonal elements in vector-matrix multiplication) are performed deterministically when number of walkers in a configuration is high, as controlled by the rel_spawning_threshold and abs_spawning_threshold keywords. Stochastic selection of spawns is controlled by the spawning keyword.\n\nBy default, a stochastic vector compression is applied after annihilations are completed. This behaviour can be changed to on-the-fly projection (as in IsStochasticInteger or IsStochasticWithThreshold) by setting late_compression=false, or modifying spawning and compression. See parameters below for a more detailed explanation.\n\nParameters:\n\nthreshold = 1.0: Values below this number are stochastically projected to this value or zero. See also ThresholdCompression.\nlate_compression = true: If this is set to true, stochastic vector compression is performed after all the spawns are performed. If it is set to false, values are stochastically projected as they are being spawned. late_compression=true is equivalent to setting compression=ThresholdCompression(threshold) and spawning=WithReplacement(). late_compression=false is equivalent to compression=NoCompression() and spawning=WithReplacement(threshold).\nrel_spawning_threshold = 1.0: If the walker number on a configuration times this threshold is greater than the number of offdiagonals, spawning is done deterministically. Should be set to 1 or more for best performance.\nabs_spawning_threshold = Inf: If the walker number on a configuration is greater than this value, spawning is done deterministically. Can be set to e.g. abs_spawning_threshold = 0.1 * target_walkers.\nspawning = WithReplacement(): SpawningStrategy to use for the non-exact spawns.\ncompression = ThresholdCompression(threshold): CompressionStrategy used to compress the vector after a step. Overrides threshold.\n\nSee also StochasticStyle.\n\n\n\n\n\n","category":"type"},{"location":"stochasticstyles.html#Rimu.StochasticStyles.IsStochastic2Pop","page":"Stochastic styles","title":"Rimu.StochasticStyles.IsStochastic2Pop","text":"IsStochastic2Pop{T=Complex{Int}}() <: StochasticStyle{T}\n\nStochastic propagation with complex walker numbers representing two populations of integer walkers.\n\nWhen using this style, make sure to set a complex number as target walkers in the ShiftStrategy!\n\nThis style is experimental.\n\nSee also StochasticStyle.\n\n\n\n\n\n","category":"type"},{"location":"stochasticstyles.html#Rimu.StochasticStyles.IsStochasticInteger","page":"Stochastic styles","title":"Rimu.StochasticStyles.IsStochasticInteger","text":"IsStochasticInteger{T=Int}() <: StochasticStyle{T}\n\nFCIQMC algorithm with integer walkers as in Booth et al. (2009). During the vector matrix product each individual diagonal and spawning step is rounded stochastically to a nearby integer value.\n\nSee also StochasticStyle.\n\n\n\n\n\n","category":"type"},{"location":"stochasticstyles.html#Rimu.StochasticStyles.IsStochasticWithThreshold","page":"Stochastic styles","title":"Rimu.StochasticStyles.IsStochasticWithThreshold","text":"IsStochasticWithThreshold{T=Float64}(threshold=1.0) <: StochasticStyle{T}\n\nStochastic propagation with floating point walker numbers. During the vector matrix product each individual diagonal and spawning result is rounded stochastically if smaller than threshold (before annihilations). For a more customizable stochastic style, see IsDynamicSemistochastic.\n\nSee also StochasticStyle.\n\n\n\n\n\n","category":"type"},{"location":"stochasticstyles.html#The-StochasticStyle-interface","page":"Stochastic styles","title":"The StochasticStyle interface","text":"","category":"section"},{"location":"stochasticstyles.html","page":"Stochastic styles","title":"Stochastic styles","text":"StochasticStyle\nstep_stats\napply_column!\ndefault_style","category":"page"},{"location":"stochasticstyles.html#Rimu.Interfaces.StochasticStyle","page":"Stochastic styles","title":"Rimu.Interfaces.StochasticStyle","text":"StochasticStyle(v)\n\nAbstract type. When called as a function it returns the native style of the generalised vector v that determines how simulations are to proceed.\n\nUsage\n\nConcrete StochasticStyles can be used for the style keyword argument of ProjectorMonteCarloProblem, DVec and PDVec. The following styles are available:\n\nIsStochasticInteger\nIsDeterministic\nIsStochasticWithThreshold\nIsDynamicSemistochastic\nStyleUnknown\n\nExtended Help\n\nInterface\n\nWhen defining a new StochasticStyle, subtype it as MyStyle<:StochasticStyle{T} where T is the concrete value type the style is designed to work with.\n\nFor it to work with ProjectorMonteCarloProblem, a StochasticStyle must define the following:\n\napply_column!(::StochasticStyle, w, H, address, value)\nstep_stats(::StochasticStyle)\n\nand optionally\n\nCompressionStrategy(::StochasticStyle) for vector compression after annihilations,\n\nSee also StochasticStyles, Interfaces.\n\n\n\n\n\n","category":"type"},{"location":"stochasticstyles.html#Rimu.Interfaces.step_stats","page":"Stochastic styles","title":"Rimu.Interfaces.step_stats","text":"step_stats(::StochasticStyle)\nstep_stats(::CompressionStrategy)\n\nReturn a tuple of stat names (Symbol or String) and a tuple of zeros of the same length. These will be reported as columns in the DataFrame returned by ProjectorMonteCarloProblem.\n\n\n\n\n\n","category":"function"},{"location":"stochasticstyles.html#Rimu.Interfaces.apply_column!","page":"Stochastic styles","title":"Rimu.Interfaces.apply_column!","text":"apply_column!(v, op, addr, num, boost=1) -> stats::Tuple\n\nApply the product of column addr of the operator op and the scalar num to the vector v according to the StochasticStyle of v. By expectation value this should be equivalent to\n\nv .+= op[:, add] .* num\n\nThis is used to perform the spawning step in FCIQMC and to implement operator-vector multiplications. Mutates v and reports spawning statistics.\n\nThe boost argument multiplicatively increases the number of spawns to be performed without affecting the expectation value of the procedure.\n\n\n\n\n\n","category":"function"},{"location":"stochasticstyles.html#Rimu.Interfaces.default_style","page":"Stochastic styles","title":"Rimu.Interfaces.default_style","text":"default_style(::Type)\n\nPick a StochasticStyle based on the value type. Returns StyleUnknown if no known default style is set.\n\n\n\n\n\n","category":"function"},{"location":"stochasticstyles.html#Compression-strategies","page":"Stochastic styles","title":"Compression strategies","text":"","category":"section"},{"location":"stochasticstyles.html","page":"Stochastic styles","title":"Stochastic styles","text":"CompressionStrategy\nNoCompression\nStochasticStyles.ThresholdCompression\ncompress!","category":"page"},{"location":"stochasticstyles.html#Rimu.Interfaces.CompressionStrategy","page":"Stochastic styles","title":"Rimu.Interfaces.CompressionStrategy","text":"CompressionStrategy\n\nThe CompressionStrategy controls how a vector is compressed after a step.\n\nDefault implementation:\n\nNoCompression: no vector compression\n\nUsage\n\nA subtype of CompressionStrategy can be passed as a keyword argument to the constructors for some StochasticStyles. Calling CompressionStrategy(s::StochasticStyle) returns a relevant subtype. The default is NoCompression.\n\nInterface\n\nWhen defining a new CompressionStrategy, subtype it as MyCompressionStrategy <: CompressionStrategy and define these methods:\n\ncompress!(s::CompressionStrategy, v)\ncompress!(s::CompressionStrategy, w, v)\nstep_stats(s::CompressionStrategy)\n\n\n\n\n\n","category":"type"},{"location":"stochasticstyles.html#Rimu.Interfaces.NoCompression","page":"Stochastic styles","title":"Rimu.Interfaces.NoCompression","text":"NoCompression <: CompressionStrategy end\n\nDefault CompressionStrategy. Leaves the vector intact.\n\n\n\n\n\n","category":"type"},{"location":"stochasticstyles.html#Rimu.StochasticStyles.ThresholdCompression","page":"Stochastic styles","title":"Rimu.StochasticStyles.ThresholdCompression","text":"ThresholdCompression(threshold=1) <: CompressionStrategy\n\nCompressionStrategy that compresses a vector by threshold projection. Every entry in the vector with a value below the threshold is either set to zero, or increased to the threshold. The probabilty of setting it to zero is equal to abs(value) / threshold.\n\n\n\n\n\n","category":"type"},{"location":"stochasticstyles.html#Rimu.Interfaces.compress!","page":"Stochastic styles","title":"Rimu.Interfaces.compress!","text":"compress!([::CompressionStrategy,] v) -> ::NTuple{N,::Symbol}, ::NTuple{N}\ncompress!([::CompressionStrategy,] w, v) -> ::NTuple{N,::Symbol}, ::NTuple{N}\n\nCompress the vector v. The one-argument version compresses the vector in-place. The two-argument vector stores the result in w. The CompressionStrategy associated with the StochasticStyle of v is used to determine the type of compression.\n\nReturns two tuples, containing the names and values of statistics that are to be reported.\n\n\n\n\n\n","category":"function"},{"location":"stochasticstyles.html#Spawning-strategies-and-convenience-functions","page":"Stochastic styles","title":"Spawning strategies and convenience functions","text":"","category":"section"},{"location":"stochasticstyles.html","page":"Stochastic styles","title":"Stochastic styles","text":"The following functions and types are unexported, but are useful when defining new styles.","category":"page"},{"location":"stochasticstyles.html","page":"Stochastic styles","title":"Stochastic styles","text":"Modules = [StochasticStyles]\nPages = [\"spawning.jl\"]\nOrder = [:function,:method,:type]","category":"page"},{"location":"stochasticstyles.html#Rimu.StochasticStyles.diagonal_step!","page":"Stochastic styles","title":"Rimu.StochasticStyles.diagonal_step!","text":"diagonal_step!(w, op, add, val, threshold=0) -> (clones, deaths, zombies)\n\nPerform diagonal step on a walker add => val. Optional argument threshold sets the projection threshold. If eltype(w) is an Integer, the val is rounded to the nearest integer stochastically.\n\n\n\n\n\n","category":"function"},{"location":"stochasticstyles.html#Rimu.StochasticStyles.projected_deposit!","page":"Stochastic styles","title":"Rimu.StochasticStyles.projected_deposit!","text":"projected_deposit!(w, add, val, parent, threshold=0)\n\nLike deposit!, but performs threshold projection before spawning. If eltype(w) is an Integer, values are stochastically rounded.\n\nReturns the value deposited.\n\n\n\n\n\n","category":"function"},{"location":"stochasticstyles.html#Rimu.StochasticStyles.spawn!","page":"Stochastic styles","title":"Rimu.StochasticStyles.spawn!","text":"spawn!(s::SpawningStrategy, w, op::AbstractHamiltonian, add, val, boost)\nspawn!(s::SpawningStrategy, w, offdiags::AbstractOffdiagonals, add, val, boost)\n\nPerform stochastic spawns to w from address add with val walkers. val * boost controls the number of spawns performed.\n\nThis function should be overloaded in the second form, with offdiags as an argument.\n\nSee SpawningStrategy.\n\n\n\n\n\n","category":"function"},{"location":"stochasticstyles.html#Rimu.StochasticStyles.Bernoulli","page":"Stochastic styles","title":"Rimu.StochasticStyles.Bernoulli","text":"Bernoulli(threshold=0.0) <: SpawningStrategy\n\nPerform Bernoulli sampling. A spawn is attempted on each offdiagonal element with a probability that results in an expected number of spawns equal to the number of walkers on the spawning configuration. This is significantly less efficient than WithReplacement.\n\nIf the number of spawn attempts is greater than the number of offdiagonals, this functions like Exact, but is less efficient. For best performance, this strategy is to be used as a substrategy of DynamicSemistochastic.\n\nParameters\n\nthreshold sets the projection threshold.\n\nspawn! with this strategy returns the number of spawn attempts and the number of spawns.\n\n\n\n\n\n","category":"type"},{"location":"stochasticstyles.html#Rimu.StochasticStyles.DynamicSemistochastic","page":"Stochastic styles","title":"Rimu.StochasticStyles.DynamicSemistochastic","text":"DynamicSemistochastic(; strat, rel_threshold, abs_threshold) <: SpawningStrategy\n\nSpawningStrategy that behaves like strat when the number of walkers is low, but performs exact steps when it is high. What \"high\" means is controlled by the two thresholds described below.\n\nParameters\n\nstrat = WithReplacement(): a SpawningStrategy to use when the multiplication is not performed exactly. If the strat has a threshold different from zero, all spawns will be projected to that threshold.\nrel_threshold = 1.0: When deciding on whether to perform an exact spawn, this value is multiplied to the number of walkers. Should be set to 1 or more for best performance. This threshold is affected by the boost argument to spawn!.\nabs_threshold = Inf: When deciding on whether to perform an exact spawn, min(abs_threshold, num_offdiagonals) is used. This threshold is not affected by the boost argument to spawn!.\n\nSee e.g. WithoutReplacement for a description of the strat.threshold parameter.\n\nspawn! with this strategy returns the numbers of exact and inexact spawns, the number of spawn attempts and the number of spawns.\n\n\n\n\n\n","category":"type"},{"location":"stochasticstyles.html#Rimu.StochasticStyles.Exact","page":"Stochastic styles","title":"Rimu.StochasticStyles.Exact","text":"Exact(threshold=0.0) <: SpawningStrategy\n\nPerform an exact spawning step.\n\nParameters\n\nthreshold sets the projection threshold. If set to zero, no projection is performed.\n\nspawn! with this strategy returns the number of spawn attempts and the number of spawns.\n\n\n\n\n\n","category":"type"},{"location":"stochasticstyles.html#Rimu.StochasticStyles.SingleSpawn","page":"Stochastic styles","title":"Rimu.StochasticStyles.SingleSpawn","text":"SingleSpawn(threshold=0.0) <: SpawningStrategy\n\nPerform a single spawn. Useful as a building block for other stochastic styles.\n\nParameters\n\nthreshold sets the projection threshold. If set to zero, no projection is performed.\n\nspawn! with this strategy returns the number of spawn attempts (always 1) and the number of spawns.\n\n\n\n\n\n","category":"type"},{"location":"stochasticstyles.html#Rimu.StochasticStyles.SpawningStrategy","page":"Stochastic styles","title":"Rimu.StochasticStyles.SpawningStrategy","text":"SpawningStrategy\n\nA SpawningStrategy is used to control how spawns (multiplies with off-diagonal part of the column vector) are performed and can be passed to some of the StochasticStyles as keyword arguments.\n\nThe following concrete implementations are provided:\n\nExact: Perform exact spawns. Used by IsDeterministic.\nWithReplacement: The default stochastic spawning strategy. Spawns are chosen with replacement.\nDynamicSemistochastic: Behave like Exact when the number of spawns performed is high, and like a different substrategy otherwise. Used by IsDynamicSemistochastic.\nSingleSpawn: Perform a single spawn only. Used as a building block for other strategies.\nWithoutReplacement: Similar to WithReplacement, but ensures each spawn is only performed once. Only to be used as a substrategy of DynamicSemistochastic.\nBernoulli: Each spawn is attempted with a fixed probability. Only to be used as a substrategy of DynamicSemistochastic.\n\nInterface\n\nIn order to implement a new SpawningStrategy, define a method for spawn!.\n\n\n\n\n\n","category":"type"},{"location":"stochasticstyles.html#Rimu.StochasticStyles.WithReplacement","page":"Stochastic styles","title":"Rimu.StochasticStyles.WithReplacement","text":"WithReplacement(threshold=0.0) <: SpawningStrategy\n\nSpawningStrategy where spawn targets are sampled with replacement. This is the default spawning strategy for most of the StochasticStyles.\n\nParameters\n\nthreshold sets the projection threshold. If set to zero, no projection is performed.\n\nspawn! with this strategy returns the number of spawn attempts and the number of spawns.\n\n\n\n\n\n","category":"type"},{"location":"stochasticstyles.html#Rimu.StochasticStyles.WithoutReplacement","page":"Stochastic styles","title":"Rimu.StochasticStyles.WithoutReplacement","text":"WithoutReplacement(threshold=0.0) <: SpawningStrategy\n\nSpawningStrategy where spawn targets are sampled without replacement. This strategy needs to allocate a temporary array during spawning, which makes it significantly less efficient than WithReplacement.\n\nIf the number of spawn attempts is greater than the number of offdiagonals, this functions like Exact, but is less efficient. For best performance, this strategy is to be used as a substrategy of DynamicSemistochastic.\n\nParameters\n\nthreshold sets the projection threshold. If set to zero, no projection is performed.\n\nspawn! with this strategy returns the number of spawn attempts and the number of spawns.\n\n\n\n\n\n","category":"type"},{"location":"stochasticstyles.html#Index","page":"Stochastic styles","title":"Index","text":"","category":"section"},{"location":"stochasticstyles.html","page":"Stochastic styles","title":"Stochastic styles","text":"Pages = [\"stochasticstyles.md\"]","category":"page"},{"location":"generated/BHM-example-mpi.html","page":"Rimu with MPI","title":"Rimu with MPI","text":"EditURL = \"../../../scripts/BHM-example-mpi.jl\"","category":"page"},{"location":"generated/BHM-example-mpi.html#Example-2:-Rimu-with-MPI","page":"Rimu with MPI","title":"Example 2: Rimu with MPI","text":"","category":"section"},{"location":"generated/BHM-example-mpi.html","page":"Rimu with MPI","title":"Rimu with MPI","text":"In this example, we will demonstrate using Rimu with MPI. MPI is a standard for parallel and distributed computing, and it is widely used in high-performance computing. Rimu provides support for MPI to enable parallel computations on multiple nodes.","category":"page"},{"location":"generated/BHM-example-mpi.html","page":"Rimu with MPI","title":"Rimu with MPI","text":"A runnable script for this example is located here. Run it with 2 MPI ranks with mpirun -n 2 julia BHM-example-mpi.jl.","category":"page"},{"location":"generated/BHM-example-mpi.html","page":"Rimu with MPI","title":"Rimu with MPI","text":"We start by importing Rimu.","category":"page"},{"location":"generated/BHM-example-mpi.html","page":"Rimu with MPI","title":"Rimu with MPI","text":"using Rimu","category":"page"},{"location":"generated/BHM-example-mpi.html","page":"Rimu with MPI","title":"Rimu with MPI","text":"Note that it is not necessary to initialise the MPI library, as this is already done automatically when Rimu is loaded.","category":"page"},{"location":"generated/BHM-example-mpi.html","page":"Rimu with MPI","title":"Rimu with MPI","text":"We will compute the ground state of a Bose-Hubbard model in momentum space with 10 particles in 10 sites.","category":"page"},{"location":"generated/BHM-example-mpi.html","page":"Rimu with MPI","title":"Rimu with MPI","text":"First, we define the Hamiltonian. We want to start from an address with zero momentum, which is located at mode 5 in the momentum grid. We put all 10 particles, all in the zero momentum mode.","category":"page"},{"location":"generated/BHM-example-mpi.html","page":"Rimu with MPI","title":"Rimu with MPI","text":"address = BoseFS(10, 5 => 10)","category":"page"},{"location":"generated/BHM-example-mpi.html","page":"Rimu with MPI","title":"Rimu with MPI","text":"BoseFS{10,10}(0, 0, 0, 0, 10, 0, 0, 0, 0, 0)","category":"page"},{"location":"generated/BHM-example-mpi.html","page":"Rimu with MPI","title":"Rimu with MPI","text":"We will set the interaction strength u to 6.0. The hopping strength t defaults to 1.0.","category":"page"},{"location":"generated/BHM-example-mpi.html","page":"Rimu with MPI","title":"Rimu with MPI","text":"H = HubbardMom1D(address; u=6.0)","category":"page"},{"location":"generated/BHM-example-mpi.html","page":"Rimu with MPI","title":"Rimu with MPI","text":"HubbardMom1D(fs\"|0 0 0 0 10 0 0 0 0 0⟩\"; u=6.0, t=1.0)","category":"page"},{"location":"generated/BHM-example-mpi.html","page":"Rimu with MPI","title":"Rimu with MPI","text":"We set a reporting strategy. We will use ReportToFile, which writes the reports directly to a file. This is useful for MPI calculations, as they will typically run non-interactively. The reports will be written to disk and can be inspected later. This has the additional benefit of reducing memory use in long-running jobs, as we don't need to keep the results in memory. It also allows us to inspect the results before the computation finishes and recover some data if it fails.","category":"page"},{"location":"generated/BHM-example-mpi.html","page":"Rimu with MPI","title":"Rimu with MPI","text":"The default settings will ensure that only the root MPI rank will write to the file, which is reasonable, and that data is saved in chunks of 1000 time steps. We choose to suppress progress messages with setting io=devnull.","category":"page"},{"location":"generated/BHM-example-mpi.html","page":"Rimu with MPI","title":"Rimu with MPI","text":"reporting_strategy = ReportToFile(\n filename=\"result.arrow\",\n io=devnull\n)","category":"page"},{"location":"generated/BHM-example-mpi.html","page":"Rimu with MPI","title":"Rimu with MPI","text":"ReportToFile{Symbol}(\"result.arrow\", 1, 1000, true, false, Base.DevNull(), :zstd, nothing)","category":"page"},{"location":"generated/BHM-example-mpi.html","page":"Rimu with MPI","title":"Rimu with MPI","text":"For running parallel computations with MPI, it is important that a compatible state vector is used. Here we explicitly set up an MPI-enabled state vector, PDVec, which is automatically MPI-distributed over the available number of MPI ranks. In addition, threading will be used with all threads available to Julia.","category":"page"},{"location":"generated/BHM-example-mpi.html","page":"Rimu with MPI","title":"Rimu with MPI","text":"initial_vector = PDVec(address => 1.0; style=IsDynamicSemistochastic())","category":"page"},{"location":"generated/BHM-example-mpi.html","page":"Rimu with MPI","title":"Rimu with MPI","text":"1-element PDVec: style = IsDynamicSemistochastic{Float64,ThresholdCompression,DynamicSemistochastic}()\n fs\"|0 0 0 0 10 0 0 0 0 0⟩\" => 1.0","category":"page"},{"location":"generated/BHM-example-mpi.html","page":"Rimu with MPI","title":"Rimu with MPI","text":"Now, we can set other parameters as usual. We will perform the computation with 10000 walkers and for 10000 time steps. We will also compute the projected energy by passing a ProjectedEnergy object as a post_step_strategy.","category":"page"},{"location":"generated/BHM-example-mpi.html","page":"Rimu with MPI","title":"Rimu with MPI","text":"problem = ProjectorMonteCarloProblem(H;\n start_at=initial_vector,\n reporting_strategy,\n post_step_strategy=ProjectedEnergy(H, initial_vector),\n target_walkers=10_000,\n time_step=1e-4,\n last_step=10_000\n);","category":"page"},{"location":"generated/BHM-example-mpi.html","page":"Rimu with MPI","title":"Rimu with MPI","text":"The @mpi_root macro performs an action on the root rank only, which is useful for printing.","category":"page"},{"location":"generated/BHM-example-mpi.html","page":"Rimu with MPI","title":"Rimu with MPI","text":"@mpi_root println(\"Running FCIQMC with \", mpi_size(), \" rank(s).\")","category":"page"},{"location":"generated/BHM-example-mpi.html","page":"Rimu with MPI","title":"Rimu with MPI","text":"Running FCIQMC with 1 rank(s).\n","category":"page"},{"location":"generated/BHM-example-mpi.html","page":"Rimu with MPI","title":"Rimu with MPI","text":"Finally, we can run the computation.","category":"page"},{"location":"generated/BHM-example-mpi.html","page":"Rimu with MPI","title":"Rimu with MPI","text":"simulation = solve(problem);\n\n@mpi_root println(\"Simulation success = \", simulation.success)","category":"page"},{"location":"generated/BHM-example-mpi.html","page":"Rimu with MPI","title":"Rimu with MPI","text":"Simulation success = true\n","category":"page"},{"location":"generated/BHM-example-mpi.html","page":"Rimu with MPI","title":"Rimu with MPI","text":"Once the calculation is done, the results are available in the arrow file on disk.","category":"page"},{"location":"generated/BHM-example-mpi.html","page":"Rimu with MPI","title":"Rimu with MPI","text":"In a typical workflow, the simulation results would be loaded from disk and analysed in the REPL or with a separate script. The arrow file can be loaded into a DataFrame with metadata using the load_df function.","category":"page"},{"location":"generated/BHM-example-mpi.html","page":"Rimu with MPI","title":"Rimu with MPI","text":"","category":"page"},{"location":"generated/BHM-example-mpi.html","page":"Rimu with MPI","title":"Rimu with MPI","text":"This page was generated using Literate.jl.","category":"page"},{"location":"index.html#Rimu.jl-Package-Guide","page":"Guide","title":"Rimu.jl Package Guide","text":"","category":"section"},{"location":"index.html","page":"Guide","title":"Guide","text":"Random Integrators for many-body quantum systems","category":"page"},{"location":"index.html","page":"Guide","title":"Guide","text":"The grand aim is to develop a toolbox for many-body quantum systems that can be represented by a Hamiltonian in second quantisation language. Currently supported features include:","category":"page"},{"location":"index.html#Interacting-with-quantum-many-body-models","page":"Guide","title":"Interacting with quantum many-body models","text":"","category":"section"},{"location":"index.html","page":"Guide","title":"Guide","text":"Full configuration interaction quantum Monte Carlo (FCIQMC), a flavour of projector quantum Monte Carlo for stochastically solving the time-independent Schrödinger equation. See References.\nMatrix-free exact diagonalisation of quantum Hamiltonians (with external package KrylovKit.jl).\nSparse matrix representation of quantum Hamiltonians for exact diagonalisation with sparse linear algebra package of your choice (fastest for small systems).","category":"page"},{"location":"index.html#Representing-quantum-many-body-models","page":"Guide","title":"Representing quantum many-body models","text":"","category":"section"},{"location":"index.html","page":"Guide","title":"Guide","text":"A composable and efficient type system for representing single- and multi-component Fock states of bosons, fermions, and mixtures thereof, to be used as a basis for representing Hamiltonians.\nAn interface for defining many-body Hamiltonians.\nPre-defined models include:\nHubbard model in real space for bosons and fermions and mixtures in 1, 2, and 3 spatial dimensions.\nHubbard and related lattice models in momentum space for bosons and fermions in one spatial dimension.\nTranscorrelated Hamiltonian for contact interactions in one dimension for fermions, as described in Jeszenski et al. arXiv:1806.11268.","category":"page"},{"location":"index.html#Statistical-analysis-of-Monte-Carlo-data","page":"Guide","title":"Statistical analysis of Monte Carlo data","text":"","category":"section"},{"location":"index.html","page":"Guide","title":"Guide","text":"Blocking analysis following Flyvberg & Peterson JCP (1989), and automated with hypothesis testing by Jonsson","category":"page"},{"location":"index.html","page":"Guide","title":"Guide","text":"PRE (2018).","category":"page"},{"location":"index.html","page":"Guide","title":"Guide","text":"Unbiased estimators for the ground state energy by re-reweighting following Nightingale & Blöte PRB (1986) and Umrigar et al. JCP (1993).","category":"page"},{"location":"index.html","page":"Guide","title":"Guide","text":"The code supports parallelisation with MPI (harnessing MPI.jl) as well as native Julia threading (experimental). In the future, we may add tools to solve the time-dependent Schrödinger equation and Master equations for open system time evolution.","category":"page"},{"location":"index.html","page":"Guide","title":"Guide","text":"Concept: Joachim Brand and Elke Pahl.","category":"page"},{"location":"index.html","page":"Guide","title":"Guide","text":"Contributors: Joachim Brand, Elke Pahl, Mingrui Yang, Matija Čufar, Chris Bradly.","category":"page"},{"location":"index.html","page":"Guide","title":"Guide","text":"Discussions, help, and additional contributions are acknowledged by Ali Alavi, Didier Adrien, Chris Scott (NeSI), Alexander Pletzer (NeSI).","category":"page"},{"location":"index.html#Installation","page":"Guide","title":"Installation","text":"","category":"section"},{"location":"index.html#Installing-Rimu-for-usage","page":"Guide","title":"Installing Rimu for usage","text":"","category":"section"},{"location":"index.html","page":"Guide","title":"Guide","text":"Rimu is a registered package and can be installed with the package manager. Hit the ] key at the Julia REPL to get into Pkg mode and type","category":"page"},{"location":"index.html","page":"Guide","title":"Guide","text":"pkg> add Rimu","category":"page"},{"location":"index.html","page":"Guide","title":"Guide","text":"Alternatively, use","category":"page"},{"location":"index.html","page":"Guide","title":"Guide","text":"julia> using Pkg; Pkg.add(name=\"Rimu\")","category":"page"},{"location":"index.html","page":"Guide","title":"Guide","text":"in order to install Rimu from a script.","category":"page"},{"location":"index.html#Installing-Rimu-for-development","page":"Guide","title":"Installing Rimu for development","text":"","category":"section"},{"location":"index.html","page":"Guide","title":"Guide","text":"In order to be able to edit the source code, push changes, change and make new git branches, etc., clone the git repository with git clone to a convenient location, e.g. ~/mygitpackagefolder/. Then hit the ] key at the Julia REPL to get into Pkg mode and type","category":"page"},{"location":"index.html","page":"Guide","title":"Guide","text":"pkg> develop ~/mygitpackagefolder/rimu.jl","category":"page"},{"location":"index.html","page":"Guide","title":"Guide","text":"where the file path has to be adjusted to the location of the cloned git repository.","category":"page"},{"location":"index.html#Usage","page":"Guide","title":"Usage","text":"","category":"section"},{"location":"index.html","page":"Guide","title":"Guide","text":"The package is now installed and can be imported with","category":"page"},{"location":"index.html","page":"Guide","title":"Guide","text":"julia> using Rimu","category":"page"},{"location":"index.html","page":"Guide","title":"Guide","text":"When planning to edit the code of the package it is advisable to use the Revise package by issuing","category":"page"},{"location":"index.html","page":"Guide","title":"Guide","text":"julia> using Revise","category":"page"},{"location":"index.html","page":"Guide","title":"Guide","text":"before using Rimu. This will track any changes made to the source code of Rimu and the changed package will be available after saving the source code (hopefully, and most of the time, without restarting the Julia REPL).","category":"page"},{"location":"index.html","page":"Guide","title":"Guide","text":"Rimu offers a number of tools for representing Hamiltonians (see Hamiltonians) and state vectors / wave functions (see DictVectors) as well as algorithms to find the ground state, e.g. ProjectorMonteCarloProblem, ExactDiagonalizationProblem.","category":"page"},{"location":"index.html#Scripts","page":"Guide","title":"Scripts","text":"","category":"section"},{"location":"index.html","page":"Guide","title":"Guide","text":"Rimu is written as a Julia package to be imported with using Rimu as described above. It supplies useful functions and types. Performing actual calculations and analysing the results is done with scripts. The folder scripts/ contains a collections of scripts that are either examples for use of the Rimu package or useful scripts for data analysis. In particular:","category":"page"},{"location":"index.html","page":"Guide","title":"Guide","text":"scripts/BHM-example.jl is an example script that runs fciqmc on the 1D Bose-Hubbard model. A data frame with results is written to the file fciqmcdata.arrow.\nscripts/BHM-example-mpi.jl demonstrates basic usage of Rimu with MPI.","category":"page"},{"location":"index.html#MPI","page":"Guide","title":"MPI","text":"","category":"section"},{"location":"index.html","page":"Guide","title":"Guide","text":"The Rimu package can run in parallel on different processes or node and distribute work by making use of MPI, or \"message passing interface\". For example, running","category":"page"},{"location":"index.html","page":"Guide","title":"Guide","text":"> julia scripts/BHM-example.jl","category":"page"},{"location":"index.html","page":"Guide","title":"Guide","text":"will run on one processor with the main computation (i.e. after package loading and compilation) completing in 2.69 seconds.","category":"page"},{"location":"index.html","page":"Guide","title":"Guide","text":"Running","category":"page"},{"location":"index.html","page":"Guide","title":"Guide","text":"> mpirun -np 4 julia scripts/BHM-example-mpi.jl","category":"page"},{"location":"index.html","page":"Guide","title":"Guide","text":"on the same hardware makes use of 4 cores and the main part completes in 1.04 seconds, a speedup factor of 2.6. This seems reasonable, given that extra work needs to be done for communicating between different processes.","category":"page"},{"location":"index.html","page":"Guide","title":"Guide","text":"Using MPI parallelism with Rimu is easy. Enabling MPI enabled automatically if PDVec is used to store a vector. In that case, data will be stored in a distributed fashion among the MPI ranks and only communicated between ranks when necessary.","category":"page"},{"location":"index.html#Compatibility","page":"Guide","title":"Compatibility","text":"","category":"section"},{"location":"index.html","page":"Guide","title":"Guide","text":"We recommend using Rimu with the latest Julia release version. Rimu requires at least julia v1.9.","category":"page"},{"location":"index.html#References","page":"Guide","title":"References","text":"","category":"section"},{"location":"index.html","page":"Guide","title":"Guide","text":"The code implements the FCIQMC algorithm originally described in","category":"page"},{"location":"index.html","page":"Guide","title":"Guide","text":"\"Fermion Monte Carlo without fixed nodes: A game of life, death, and annihilation in Slater determinant space\", G. H. Booth, A. J. W. Thom, A. Alavi, J. Chem. Phys. 131, 054106 (2009).\n\"Communications: Survival of the fittest: accelerating convergence in full configuration-interaction quantum Monte Carlo.\", D. Cleland, G. H. Booth, A. Alavi, J. Chem. Phys. 132, 041103 (2010).","category":"page"},{"location":"index.html","page":"Guide","title":"Guide","text":"Scientific papers describing additional features implemented in Rimu:","category":"page"},{"location":"index.html","page":"Guide","title":"Guide","text":"\"Improved walker population control for full configuration interaction quantum Monte Carlo\", M. Yang, E. Pahl, J. Brand, J. Chem. Phys. 153, 170143 (2020); arXiv:2008.01927.\n\"Stochastic differential equation approach to understanding the population control bias in full configuration interaction quantum Monte Carlo\", J. Brand, M. Yang, E. Pahl, arXiv:2103.07800 (2021).","category":"page"},{"location":"index.html","page":"Guide","title":"Guide","text":"Papers discussing results obtained with Rimu:","category":"page"},{"location":"index.html","page":"Guide","title":"Guide","text":"\"Polaron-Depleton Transition in the Yrast Excitations of a One-Dimensional Bose Gas with a Mobile Impurity\", M. Yang, M. Čufar, E. Pahl, J. Brand, Condens. Matter 7, 15 (2022).\n\"Magnetic impurity in a one-dimensional few-fermion system\", L. Rammelmüller, D. Huber, M. Čufar, J. Brand, A. Volosniev, arXiv:2204.01606 (2022).","category":"page"},{"location":"dictvectors.html#Module-DictVectors","page":"Dict vectors","title":"Module DictVectors","text":"","category":"section"},{"location":"dictvectors.html","page":"Dict vectors","title":"Dict vectors","text":"DictVectors\nAbstractDVec","category":"page"},{"location":"dictvectors.html#Rimu.DictVectors","page":"Dict vectors","title":"Rimu.DictVectors","text":"Module that provides concrete implementations of the AbstractDVec interface.\n\nDVec: basic AbstractDVec\nPDVec: parallel AbstractDVec with MPI and initiator support\nInitiatorDVec: allows storing information about initiator status\n\nSee Interfaces.\n\n\n\n\n\n","category":"module"},{"location":"dictvectors.html#Rimu.Interfaces.AbstractDVec","page":"Dict vectors","title":"Rimu.Interfaces.AbstractDVec","text":"AbstractDVec{K,V}\n\nAbstract data type for vector-like data structures with sparse storage. While conceptually AbstractDVecs represent elements of a vector space over a scalar type V, they are indexed by an arbitrary type K (could be non-integers) similar to dictionaries. They support the interface from VectorInterface.jl and are designed to work well for quantum Monte Carlo with ProjectorMonteCarloProblem and for matrix-free linear algebra with KrylovKit.\n\nConcrete implementations are available as PDVec, DVec, and InitiatorDVec.\n\nAbstractDVecs have a StochasticStyle which selects the spawning algorithm in FCIQMC. Looking up an element that is not stored in the AbstractDVec should return a zero, and setting a value to zero should remove it from the vector. To iterate over an AbstractDVec, use keys, pairs, or values. When possible, use reduction functions such as sum or mapreduce.\n\nInterface\n\nThe interface is similar to the AbstractDict interface, but with the changed behaviour as noted above. Implement what would be needed for the AbstractDict interface (pairs, keys, values, setindex!, getindex, delete!, length, empty, empty!) and, in addition:\n\nStochasticStyle\nstorage returns an AbstractDict storing the raw data with possibly different valtype than V.\ndeposit!\n\nA default implementation for the VectorInterface.jl interface is provided through the above functions.\n\nSee also DictVectors, Interfaces.\n\n\n\n\n\n","category":"type"},{"location":"dictvectors.html#Concrete-implementations","page":"Dict vectors","title":"Concrete implementations","text":"","category":"section"},{"location":"dictvectors.html","page":"Dict vectors","title":"Dict vectors","text":"DVec\nInitiatorDVec\nPDVec","category":"page"},{"location":"dictvectors.html#Rimu.DictVectors.DVec","page":"Dict vectors","title":"Rimu.DictVectors.DVec","text":"DVec{K,V,D<:AbstractDict{K,V},S}\n\nDictionary-based vector-like data structure for use with FCIQMC and KrylovKit. While mostly behaving like a Dict, it supports various linear algebra operations such as norm and dot. It has a StochasticStyle that is used to select an appropriate spawning strategy in the FCIQMC algorithm.\n\nSee also: AbstractDVec, InitiatorDVec, PDVec.\n\nConstructors\n\nDVec(dict::AbstractDict[; style, capacity]): create a DVec with dict for storage. Note that the data may or may not be copied.\nDVec(args...[; style, capacity]): args... are passed to the Dict constructor. The Dict is used for storage.\nDVec{K,V}([; style, capacity]): create an empty DVec{K,V}.\nDVec(dv::AbstractDVec[; style, capacity]): create a DVec with the same contents as adv. The style is inherited from dv by default.\n\nThe default style is selected based on the DVec's valtype (see default_style). If a style is given and the valtype does not match the style's eltype, the values are converted to an appropriate type.\n\nThe capacity argument is optional and sets the initial size of the DVec via Base.sizehint!.\n\nExamples\n\njulia> dv = DVec(:a => 1)\nDVec{Symbol,Int64} with 1 entry, style = IsStochasticInteger{Int64}()\n :a => 1\n\njulia> dv = DVec(:a => 2, :b => 3; style=IsDeterministic())\nDVec{Symbol,Float64} with 2 entries, style = IsDeterministic{Float64}()\n :a => 2.0\n :b => 3.0\n\n\n\n\n\n","category":"type"},{"location":"dictvectors.html#Rimu.DictVectors.InitiatorDVec","page":"Dict vectors","title":"Rimu.DictVectors.InitiatorDVec","text":"InitiatorDVec{K,V} <: AbstractDVec{K,V}\n\nDictionary-based vector-like data structure for use with ProjectorMonteCarloProblem and KrylovKit.jl. See AbstractDVec. Functionally identical to DVec, but contains InitiatorValues internally in order to facilitate initiator methods. Initiator methods for controlling the Monte Carlo sign problem were first introduced in J. Chem. Phys. 132, 041103 (2010). How the initiators are handled is controlled by specifying an InitiatorRule with the initiator keyword argument (see below).\n\nSee also: AbstractDVec, DVec, PDVec.\n\nConstructors\n\nInitiatorDVec(dict::AbstractDict[; style, initiator, capacity]): create an InitiatorDVec with dict for storage. Note that the data may or may not be copied.\nInitiatorDVec(args...[; style, initiator, capacity]): args... are passed to the Dict constructor. The Dict is used for storage.\nInitiatorDVec{K,V}([; style, initiator, capacity]): create an empty InitiatorDVec{K,V}.\nInitiatorDVec(dv::AbstractDVec[; style, initiator, capacity]): create an InitiatorDVec with the same contents as dv. The style is inherited from dv by default.\n\nKeyword arguments\n\nstyle: A valid StochasticStyle. The default is selected based on the InitiatorDVec's valtype (see default_style). If a style is given and the valtype does not match the style's eltype, the values are converted to an appropriate type.\ninitiator = Initiator(1): A valid InitiatorRule. See Initiator.\ncapacity: Indicative size as Int. Optional. Sets the initial size of the InitiatorDVec via Base.sizehint!.\n\n\n\n\n\n","category":"type"},{"location":"dictvectors.html#Rimu.DictVectors.PDVec","page":"Dict vectors","title":"Rimu.DictVectors.PDVec","text":"PDVec{K,V}(; kwargs...)\nPDVec(iter; kwargs...)\nPDVec(pairs...; kwargs...)\n\nDictionary-based vector-like data structure for use with FCIQMC and KrylovKit.jl. While mostly behaving like a Dict, it supports various linear algebra operations such as norm and dot, and the interface defined in VectorInterface.\n\nThe P in PDVec stands for parallel. PDVecs perform mapreduce, foreach, and various linear algebra operations in a threaded manner. If MPI is available, these operations are automatically distributed as well. As such it is not recommended to iterate over pairs, keys, or values directly unless explicitly performing them on the localpart of the vector.\n\nSee also: AbstractDVec, DVec, InitiatorDVec.\n\nKeyword arguments\n\nstyle =default_style(V): A StochasticStyle that is used to select the spawning strategy in the FCIQMC algorithm.\ninitiator =NonInitiator(): An InitiatorRule, used in FCIQMC to remove the sign problem.\ncommunicator: A Communicator that controls how operations are performed when using MPI. The defaults are NotDistributed when not using MPI and AllToAll when using MPI.\n\nExtended Help\n\nSegmentation\n\nThe vector is split into Threads.nthreads() subdictionaries called segments. Which dictionary a key-value pair is mapped to is determined by the hash of the key. The purpose of this segmentation is to allow parallel processing - functions such as mapreduce, add! or dot (full list below) process each subdictionary on a separate thread.\n\nSee also PDWorkingMemory.\n\nExample\n\njulia> add = FermiFS2C((1,1,0,0), (0,0,1,1));\n\njulia> op = HubbardMom1D(add; t=4/π^2, u=4);\n\njulia> pv = PDVec(add => 1.0)\n1-element PDVec: style = IsDeterministic{Float64}()\n fs\"|↑↑↓↓⟩\" => 1.0\n\njulia> pv = op * pv\n7-element PDVec: style = IsDeterministic{Float64}()\n fs\"|↑↓↑↓⟩\" => 1.0\n fs\"|↑↑↓↓⟩\" => 4.0\n fs\"|↓↑↓↑⟩\" => 1.0\n fs\"|↓↑↑↓⟩\" => -1.0\n fs\"|⇅⋅⋅⇅⟩\" => 1.0\n fs\"|↑↓↓↑⟩\" => -1.0\n fs\"|⋅⇅⇅⋅⟩\" => 1.0\n\njulia> scale!(pv, -1); pv\n7-element PDVec: style = IsDeterministic{Float64}()\n fs\"|↑↓↑↓⟩\" => -1.0\n fs\"|↑↑↓↓⟩\" => -4.0\n fs\"|↓↑↓↑⟩\" => -1.0\n fs\"|↓↑↑↓⟩\" => 1.0\n fs\"|⇅⋅⋅⇅⟩\" => -1.0\n fs\"|↑↓↓↑⟩\" => 1.0\n fs\"|⋅⇅⇅⋅⟩\" => -1.0\n\njulia> dest = similar(pv)\n0-element PDVec: style = IsDeterministic{Float64}()\n\njulia> map!(x -> x + 2, dest, values(pv))\n7-element PDVec: style = IsDeterministic{Float64}()\n fs\"|↑↓↑↓⟩\" => 1.0\n fs\"|↑↑↓↓⟩\" => -2.0\n fs\"|↓↑↓↑⟩\" => 1.0\n fs\"|↓↑↑↓⟩\" => 3.0\n fs\"|⇅⋅⋅⇅⟩\" => 1.0\n fs\"|↑↓↓↑⟩\" => 3.0\n fs\"|⋅⇅⇅⋅⟩\" => 1.0\n\njulia> sum(values(pv))\n-6.0\n\njulia> dot(dest, pv)\n10.0\n\njulia> dot(dest, op, pv)\n44.0\n\nMPI\n\nWhen MPI is active, all parallel reductions are automatically reduced across MPI ranks with a call to MPI.Allreduce!.\n\nIn a distributed setting, PDVec does not support iteration without first making it explicit the iteration is only to be performed on the local segments of the vector. This is done with localpart. In general, even when not using MPI, it is best practice to use localpart when explicit iteration is required.\n\nUse with KrylovKit\n\nPDVec is compatible with eigsolve from KrylovKit.jl. When used, the diagonalisation is performed in a threaded and distributed manner. Using multiple MPI ranks with this method does not distribute the memory load effectively, but does result in significant speedups.\n\nExample\n\njulia> using KrylovKit\n\njulia> add = BoseFS((0,0,5,0,0));\n\njulia> op = HubbardMom1D(add; u=6.0);\n\njulia> pv = PDVec(add => 1.0);\n\njulia> results = eigsolve(op, pv, 4, :SR);\n\njulia> results[1][1:4]\n4-element Vector{Float64}:\n -3.4311156892322234\n 1.1821748602612363\n 3.7377753753082823\n 6.996390417443125\n\nParallel functionality\n\nThe following functions are threaded and MPI-compatible:\n\nFrom Base: mapreduce and derivatives (sum, prod, reduce...), all, any,map! (on values only), +, -, *\nFrom LinearAlgebra: rmul!, lmul!, mul!, axpy!, axpby!, dot, norm, normalize, normalize!\nThe full interface defined in VectorInterface.jl\n\n\n\n\n\n","category":"type"},{"location":"dictvectors.html#Interface-functions","page":"Dict vectors","title":"Interface functions","text":"","category":"section"},{"location":"dictvectors.html","page":"Dict vectors","title":"Dict vectors","text":"deposit!\nstorage\nfreeze\nlocalpart\napply_operator!\nsort_into_targets!\nworking_memory\nmapreduce\nsum_mutating!","category":"page"},{"location":"dictvectors.html#Rimu.Interfaces.deposit!","page":"Dict vectors","title":"Rimu.Interfaces.deposit!","text":"deposit!(w::InitiatorDVec, add, val, p_add=>p_val)\n\nAdd val into w at address add as an AbstractInitiatorValue.\n\n\n\n\n\ndeposit!(w::AbstractDVec, add, val, parent::Pair)\n\nAdd val into w at address add, taking into account initiator rules if applicable. parent contains the address => value pair from which the pair add => val was created. InitiatorDVec can intercept this and add its own functionality.\n\n\n\n\n\n","category":"function"},{"location":"dictvectors.html#Rimu.Interfaces.storage","page":"Dict vectors","title":"Rimu.Interfaces.storage","text":"storage(dvec) -> AbstractDict\n\nReturn the raw storage associated with dvec as an AbstractDict. Used in MPI communication.\n\n\n\n\n\n","category":"function"},{"location":"dictvectors.html#OrderedCollections.freeze","page":"Dict vectors","title":"OrderedCollections.freeze","text":"freeze(dv)\n\nCreate a \"frozen\" version of dv which can no longer be modified or used in the conventional manner, but supports faster dot products.\n\n\n\n\n\n","category":"function"},{"location":"dictvectors.html#Rimu.Interfaces.localpart","page":"Dict vectors","title":"Rimu.Interfaces.localpart","text":"localpart(dv) -> AbstractDVec\n\nGet the part of dv that is located on this MPI rank. Returns dv itself for vectors that can't be MPI distributed (DVecs and InitiatorDVecs).\n\n\n\n\n\n","category":"function"},{"location":"dictvectors.html#Rimu.Interfaces.apply_operator!","page":"Dict vectors","title":"Rimu.Interfaces.apply_operator!","text":"apply_operator!(working_memory, target, source, operator, boost=1, compress=Val(true)) ->\n stat_names, stats, working_memory, target\n\nPerform a single matrix(/operator)-vector multiplication:\n\nv^(n + 1) = hatT v^(n) \n\nwhere hatT is the operator, v^(n+1) is the target and v^(n) is the source. The working_memory can be used as temporary storage.\n\nThe boost argument is passed to apply_column! and increases the number of spawns performed. For the operator to be applied without compressing the vector after, set compress to Val(false).\n\nWhether the operation is performed in a stochastic, semistochastic, or determistic way is controlled by the trait StochasticStyle(target). See StochasticStyle.\n\nReturns the step stats generated by the StochasticStyle, the working memory and the target vector. target and working_memory may be mutated and/or swapped.\n\n\n\n\n\n","category":"function"},{"location":"dictvectors.html#Rimu.Interfaces.sort_into_targets!","page":"Dict vectors","title":"Rimu.Interfaces.sort_into_targets!","text":"sort_into_targets!(target, source, stats) -> target, source, agg_stats\n\nAggregate coefficients from source to target and from stats to agg_stats according to thread- or MPI-level parallelism.\n\nReturns the new target and source, as the sorting process may involve swapping them.\n\n\n\n\n\n","category":"function"},{"location":"dictvectors.html#Rimu.Interfaces.working_memory","page":"Dict vectors","title":"Rimu.Interfaces.working_memory","text":"working_memory(dv::AbstractDVec)\n\nCreate a working memory instance compatible with dv. The working memory must be compatible with sort_into_targets! and apply_operator!.\n\n\n\n\n\n","category":"function"},{"location":"dictvectors.html#Base.mapreduce","page":"Dict vectors","title":"Base.mapreduce","text":"mapreduce(f, op, keys(::PDVec); [init])\nmapreduce(f, op, values(::PDVec); [init])\nmapreduce(f, op, pairs(::PDVec); [init])\n\nPerform a parallel reduction operation on PDVecs. MPI-compatible. Is used in the definition of various functions from Base such as reduce, sum, prod, etc.\n\ninit, if provided, must be a neutral element for op.\n\n\n\n\n\n","category":"function"},{"location":"dictvectors.html#Rimu.Interfaces.sum_mutating!","page":"Dict vectors","title":"Rimu.Interfaces.sum_mutating!","text":"sum_mutating!(accumulator, [f! = add!], keys(::PDVec); [init])\nsum_mutating!(accumulator, [f! = add!], values(::PDVec); [init])\nsum_mutating!(accumulator, [f! = add!], pairs(::PDVec); [init])\n\nPerform a parallel sum on PDVecs for vector-valued results while minimizing allocations. The result of the sum will be added to accumulator and stored in accumulator. MPI-compatible. If f! is provided, it must accept two arguments, the first being the accumulator and the second the element of the iterator. Otherwise,add! is used.\n\nIf provided, init must be a neutral element for + and of the same type as accumulator.\n\nSee also mapreduce.\n\n\n\n\n\nsum_mutating!(accumulator, [f! = add!], iterator)\n\nAdd the sum of elements in iterator to accumulator, storing the result in accumulator. If f! is provided, it must accept two arguments, the first being the accumulator and the second the element of the iterator. Otherwise, add! is used.\n\nSee also mapreduce.\n\n\n\n\n\n","category":"function"},{"location":"dictvectors.html#Supported-operations","page":"Dict vectors","title":"Supported operations","text":"","category":"section"},{"location":"dictvectors.html","page":"Dict vectors","title":"Dict vectors","text":"AbstractDVecs generally support most operations that are defined on Vectors and Dicts. This includes the interface from VectorInterface.jl, and many functions from the LinearAlgebra standard library.","category":"page"},{"location":"dictvectors.html","page":"Dict vectors","title":"Dict vectors","text":"A significant difference between AbstractDVecs, Vectors, and Dicts, is that iteration on them is disabled by default. Iteration must be explicitly performed on keys, values, or pairs, however, it is highly recommended you use mapreduce, reduce, or similar functions when performing reductions, as that will make the operations compatible with MPI.","category":"page"},{"location":"dictvectors.html","page":"Dict vectors","title":"Dict vectors","text":"In addition, Rimu defines the following function.","category":"page"},{"location":"dictvectors.html","page":"Dict vectors","title":"Dict vectors","text":"walkernumber\nwalkernumber_and_length\ndot_from_right","category":"page"},{"location":"dictvectors.html#Rimu.DictVectors.walkernumber","page":"Dict vectors","title":"Rimu.DictVectors.walkernumber","text":"walkernumber(v)\n\nCompute the number of walkers in v. It is used for updating the shift. Overload this function for modifying population control.\n\nIn most cases walkernumber(v) is identical to norm(v, 1). For AbstractDVecs with complex coefficients it reports the one norm separately for the real and the imaginary part as a ComplexF64. See Norm1ProjectorPPop.\n\n\n\n\n\n","category":"function"},{"location":"dictvectors.html#Rimu.DictVectors.walkernumber_and_length","page":"Dict vectors","title":"Rimu.DictVectors.walkernumber_and_length","text":"walkernumber_and_length(v)\n\nCompute walkernumber and length at the same time. When MPI is used, this is more efficient than calling them separately.\n\n\n\n\n\n","category":"function"},{"location":"dictvectors.html#Rimu.Interfaces.dot_from_right","page":"Dict vectors","title":"Rimu.Interfaces.dot_from_right","text":"dot_from_right(w, op::AbstractObservable, v)\n\nInternal function evaluates the 3-argument dot() function in order from right to left.\n\n\n\n\n\n","category":"function"},{"location":"dictvectors.html#Projectors","page":"Dict vectors","title":"Projectors","text":"","category":"section"},{"location":"dictvectors.html","page":"Dict vectors","title":"Dict vectors","text":"AbstractProjector\nNormProjector\nNorm2Projector\nUniformProjector\nNorm1ProjectorPPop\nRimu.DictVectors.FrozenDVec\nRimu.DictVectors.FrozenPDVec","category":"page"},{"location":"dictvectors.html#Rimu.DictVectors.AbstractProjector","page":"Dict vectors","title":"Rimu.DictVectors.AbstractProjector","text":"Abstract supertype for projectors to be used in in lieu of DVecs or Vectors in dot products. Implemented subtypes:\n\nUniformProjector\nNormProjector\nNorm2Projector\nNorm1ProjectorPPop\n\nSee also PostStepStrategy for use of projectors in ProjectorMonteCarloProblem.\n\nInterface\n\nDefine a method for LinearAlgebra.dot(projector, v).\n\n\n\n\n\n","category":"type"},{"location":"dictvectors.html#Rimu.DictVectors.NormProjector","page":"Dict vectors","title":"Rimu.DictVectors.NormProjector","text":"NormProjector() <: AbstractProjector\n\nResults in computing the one-norm when used in dot(). E.g.\n\ndot(NormProjector(),x)\n-> norm(x,1)\n\nNormProjector() thus represents the vector sign.(x).\n\nSee also PostStepStrategy, and AbstractProjector for use of projectors in ProjectorMonteCarloProblem.\n\n\n\n\n\n","category":"type"},{"location":"dictvectors.html#Rimu.DictVectors.Norm2Projector","page":"Dict vectors","title":"Rimu.DictVectors.Norm2Projector","text":"Norm2Projector() <: AbstractProjector\n\nResults in computing the two-norm when used in dot(). E.g.\n\ndot(NormProjector(),x)\n-> norm(x,2) # with type Float64\n\nSee also PostStepStrategy, and AbstractProjector for use of projectors in ProjectorMonteCarloProblem.\n\n\n\n\n\n","category":"type"},{"location":"dictvectors.html#Rimu.DictVectors.UniformProjector","page":"Dict vectors","title":"Rimu.DictVectors.UniformProjector","text":"UniformProjector() <: AbstractProjector\n\nRepresents a vector with all elements 1. To be used with dot(). Minimizes memory allocations.\n\nUniformProjector()⋅v == sum(v)\ndot(UniformProjector(), LO, v) == sum(LO*v)\n\nSee also PostStepStrategy, and AbstractProjector for use of projectors in ProjectorMonteCarloProblem.\n\n\n\n\n\n","category":"type"},{"location":"dictvectors.html#Rimu.DictVectors.Norm1ProjectorPPop","page":"Dict vectors","title":"Rimu.DictVectors.Norm1ProjectorPPop","text":"Norm1ProjectorPPop() <: AbstractProjector\n\nResults in computing the one-norm per population when used in dot(). E.g.\n\ndot(Norm1ProjectorPPop(),x)\n-> norm(real.(x),1) + im*norm(imag.(x),1)\n\nSee also PostStepStrategy, and AbstractProjector for use of projectors in ProjectorMonteCarloProblem.\n\n\n\n\n\n","category":"type"},{"location":"dictvectors.html#Rimu.DictVectors.FrozenDVec","page":"Dict vectors","title":"Rimu.DictVectors.FrozenDVec","text":"FrozenDVec\n\nA frozen DVec(s) can't be modified or used in the conventional manner, but support faster dot products. See: freeze.\n\n\n\n\n\n","category":"type"},{"location":"dictvectors.html#Rimu.DictVectors.FrozenPDVec","page":"Dict vectors","title":"Rimu.DictVectors.FrozenPDVec","text":"FrozenPDVec\n\nParallel version of FrozenDVec. See: freeze, PDVec.\n\n\n\n\n\n","category":"type"},{"location":"dictvectors.html#Initiator-rules","page":"Dict vectors","title":"Initiator rules","text":"","category":"section"},{"location":"dictvectors.html","page":"Dict vectors","title":"Dict vectors","text":"Rimu.DictVectors.InitiatorRule\nRimu.DictVectors.AbstractInitiatorValue\nRimu.DictVectors.InitiatorValue\nRimu.DictVectors.initiator_valtype\nRimu.DictVectors.to_initiator_value\nRimu.DictVectors.from_initiator_value\nRimu.DictVectors.Initiator\nRimu.DictVectors.SimpleInitiator\nRimu.DictVectors.CoherentInitiator\nRimu.DictVectors.NonInitiator\nRimu.DictVectors.NonInitiatorValue","category":"page"},{"location":"dictvectors.html#Rimu.DictVectors.InitiatorRule","page":"Dict vectors","title":"Rimu.DictVectors.InitiatorRule","text":"InitiatorRule{V}\n\nAbstract type for defining initiator rules for InitiatorDVec. Concrete implementations:\n\nInitiator\nSimpleInitiator\nCoherentInitiator\nNonInitiator\n\nExtended Help\n\nInitiatorRules define how to store and retrieve data from associated AbstractInitiatorValues. When defining a new InitiatorRule, also define the following:\n\ninitiator_valtype\nfrom_initiator_value\nto_initiator_value\n\n\n\n\n\n","category":"type"},{"location":"dictvectors.html#Rimu.DictVectors.AbstractInitiatorValue","page":"Dict vectors","title":"Rimu.DictVectors.AbstractInitiatorValue","text":"abstract type AbstractInitiatorValue{V}\n\nA value equipped with additional information that enables a variation of the initiator approximation. To be used with PDVec, InitiatorDVec and InitiatorRules.\n\nMust define:\n\nBase.zero, Base.:+, Base.:-, Base.:*\nfrom_initiator_value and to_initiator_value\n\n\n\n\n\n","category":"type"},{"location":"dictvectors.html#Rimu.DictVectors.InitiatorValue","page":"Dict vectors","title":"Rimu.DictVectors.InitiatorValue","text":"InitiatorValue{V}(; safe::V, unsafe::V, initiator::V) where V\n\nComposite \"walker\" with three fields. For use with InitiatorDVecs.\n\n\n\n\n\n","category":"type"},{"location":"dictvectors.html#Rimu.DictVectors.initiator_valtype","page":"Dict vectors","title":"Rimu.DictVectors.initiator_valtype","text":"initiator_valtype(rule::InitiatorRule, T)\n\nReturn the AbstractInitiatorValue{T} that is employed by the rule.\n\n\n\n\n\n","category":"function"},{"location":"dictvectors.html#Rimu.DictVectors.to_initiator_value","page":"Dict vectors","title":"Rimu.DictVectors.to_initiator_value","text":"to_initiator_value(::InitiatorRule, k::K, v::V, parent)\n\nConvert v to an AbstractInitiatorValue, taking the initiator rule and the parent that spawned it into account.\n\n\n\n\n\n","category":"function"},{"location":"dictvectors.html#Rimu.DictVectors.from_initiator_value","page":"Dict vectors","title":"Rimu.DictVectors.from_initiator_value","text":"from_initiator_value(i::InitiatorRule, v::AbstractInitiatorValue)\n\nConvert the AbstractInitiatorValue v into a scalar value according to the InitiatorRule i.\n\n\n\n\n\n","category":"function"},{"location":"dictvectors.html#Rimu.DictVectors.Initiator","page":"Dict vectors","title":"Rimu.DictVectors.Initiator","text":"Initiator(threshold = 1.0) <: InitiatorRule\n\nInitiator rule to be passed to PDVec or InitiatorDVec. An initiator is a configuration add with a coefficient with magnitude abs(v[add]) > threshold. The threshold can be passed as a keyword argument. Rules:\n\nInitiators can spawn anywhere.\nNon-initiators can spawn to initiators.\n\nSee InitiatorRule.\n\n\n\n\n\n","category":"type"},{"location":"dictvectors.html#Rimu.DictVectors.SimpleInitiator","page":"Dict vectors","title":"Rimu.DictVectors.SimpleInitiator","text":"SimpleInitiator(threshold = 1.0) <: InitiatorRule\n\nInitiator rule to be passed to PDVec or InitiatorDVec. An initiator is a configuration add with a coefficient with magnitude abs(v[add]) > threshold. The threshold can be passed as a keyword argument. Rules:\n\nInitiators can spawn anywhere.\nNon-initiators cannot spawn.\n\nSee InitiatorRule.\n\n\n\n\n\n","category":"type"},{"location":"dictvectors.html#Rimu.DictVectors.CoherentInitiator","page":"Dict vectors","title":"Rimu.DictVectors.CoherentInitiator","text":"CoherentInitiator(threshold = 1.0) <: InitiatorRule\n\nInitiator rule to be passed to PDVec or InitiatorDVec. An initiator is a configuration add with a coefficient with magnitude abs(v[add]) > threshold. The threshold can be passed as a keyword argument. Rules:\n\nInitiators can spawn anywhere.\nNon-initiators can spawn to initiators.\nMultiple non-initiators can spawn to a single non-initiator if their contributions add up to a value greater than the initiator threshold.\n\nSee InitiatorRule.\n\n\n\n\n\n","category":"type"},{"location":"dictvectors.html#Rimu.DictVectors.NonInitiator","page":"Dict vectors","title":"Rimu.DictVectors.NonInitiator","text":"NonInitiator() <: InitiatorRule\n\nInitiator rule that disables the approximation. This is the default setting for PDVec.\n\nSee InitiatorRule.\n\n\n\n\n\n","category":"type"},{"location":"dictvectors.html#Rimu.DictVectors.NonInitiatorValue","page":"Dict vectors","title":"Rimu.DictVectors.NonInitiatorValue","text":"NonInitiatorValue{V}\n\nValue that does not contain any additional information - used with NonInitiator, the default initiator rule for PDVec.\n\n\n\n\n\n","category":"type"},{"location":"dictvectors.html#PDVec-internals","page":"Dict vectors","title":"PDVec internals","text":"","category":"section"},{"location":"dictvectors.html#Working-memory","page":"Dict vectors","title":"Working memory","text":"","category":"section"},{"location":"dictvectors.html","page":"Dict vectors","title":"Dict vectors","text":"Modules = [DictVectors]\nPages = [\"pdworkingmemory.jl\"]","category":"page"},{"location":"dictvectors.html#Rimu.DictVectors.FirstColumnIterator","page":"Dict vectors","title":"Rimu.DictVectors.FirstColumnIterator","text":"FirstColumnIterator{W,D} <: AbstractVector{D}\n\nIterates segments in the first column of a working memory that belong to a specified rank.\n\nSee PDWorkingMemory, remote_segments and local_segments.\n\n\n\n\n\n","category":"type"},{"location":"dictvectors.html#Rimu.DictVectors.PDWorkingMemory","page":"Dict vectors","title":"Rimu.DictVectors.PDWorkingMemory","text":"PDWorkingMemory(t::PDVec)\n\nThe working memory that handles threading and MPI distribution for operations that involve operators, such as FCIQMC propagation, operator-vector multiplication and three-way dot products with PDVecs.\n\nThe working memory is structured as a two-dimensional array of segments, which themselves are Dicts (see PDVec). The number of rows in this array is equal to the number of segments across all MPI ranks (covering the entire address space), while the number of columns corresponds to the number of segments in the current MPI rank (i.e. column corresponds to the part of the address space that is local to the current rank).\n\nThe purpose of this organisation is to allow spawning in parallel without using locks or atomic operations. The spawning is performed by applying the following sequence of operations:\n\nperform_spawns!: each segment in the PDVec is multiplied by the operator independently, with the results being stored in a column of the working memory.\ncollect_local!: the rows of the working memory are summed to the first column.\nsynchronize_remote!: the segments corresponding to other MPI ranks are distributed and transferred to the first column.\nmove_and_compress!: the results are stochastically compressed and moved to the result PDVec\n\nWhen used with three-argument dot products, a full copy of the left-hand side vector is materialized in the first column of the working memory on all ranks.\n\n\n\n\n\n","category":"type"},{"location":"dictvectors.html#Rimu.DictVectors.PDWorkingMemoryColumn","page":"Dict vectors","title":"Rimu.DictVectors.PDWorkingMemoryColumn","text":"PDWorkingMemoryColumn\n\nA column in PDWorkingMemory. Supports getindex, deposit! and StochasticStyle and acts as a target for spawning. Can be used as a target in a three-way dot-product.\n\n\n\n\n\n","category":"type"},{"location":"dictvectors.html#Rimu.DictVectors.collect_local!-Tuple{PDWorkingMemory}","page":"Dict vectors","title":"Rimu.DictVectors.collect_local!","text":"collect_local!(w::PDWorkingMemory)\n\nSum each row in w and store the result in the first column. This step must be performed before using local_segments or remote_segments to move the values elsewhere.\n\nSee PDWorkingMemory.\n\n\n\n\n\n","category":"method"},{"location":"dictvectors.html#Rimu.DictVectors.first_column-Union{Tuple{PDWorkingMemory{K, V, W, S}}, Tuple{S}, Tuple{W}, Tuple{V}, Tuple{K}} where {K, V, W, S}","page":"Dict vectors","title":"Rimu.DictVectors.first_column","text":"first_column(::PDWorkingMemory)\n\nReturn the first column of the working memory. This is where the vectors are collected with collect_local!, synchronize_remote!, copy_to_local!.\n\nSee PDWorkingMemory.\n\n\n\n\n\n","category":"method"},{"location":"dictvectors.html#Rimu.DictVectors.local_segments-Tuple{PDWorkingMemory}","page":"Dict vectors","title":"Rimu.DictVectors.local_segments","text":"local_segments(w::PDWorkingMemory)\n\nReturns iterator over the segments in the first column of w on the current rank. Iterates Dicts.\n\nSee PDWorkingMemory.\n\n\n\n\n\n","category":"method"},{"location":"dictvectors.html#Rimu.DictVectors.move_and_compress!-Tuple{PDVec, PDWorkingMemory}","page":"Dict vectors","title":"Rimu.DictVectors.move_and_compress!","text":"move_and_compress!(dst::PDVec, src::PDWorkingMemory)\nmove_and_compress!(::CompressionStrategy, dst::PDVec, src::PDWorkingMemory)\n\nMove the values in src to dst, compressing the according to the CompressionStrategy on the way. This step can only be performed after collect_local! and synchronize_remote!.\n\nSee PDWorkingMemory.\n\n\n\n\n\n","category":"method"},{"location":"dictvectors.html#Rimu.DictVectors.num_columns-Tuple{PDWorkingMemory}","page":"Dict vectors","title":"Rimu.DictVectors.num_columns","text":"num_columns(w::PDWorkingMemory) -> Int\n\nNumber of columns in the working memory. The number of rows is equal to the number of segments in the local MPI rank.\n\nSee PDWorkingMemory.\n\n\n\n\n\n","category":"method"},{"location":"dictvectors.html#Rimu.DictVectors.num_rows-Tuple{PDWorkingMemory}","page":"Dict vectors","title":"Rimu.DictVectors.num_rows","text":"num_rows(w::PDWorkingMemory) -> Int\n\nNumber of rows in the working memory. The number of rows is equal to the number of segments accross all MPI ranks.\n\nSee PDWorkingMemory.\n\n\n\n\n\n","category":"method"},{"location":"dictvectors.html#Rimu.DictVectors.perform_spawns!-Tuple{PDWorkingMemory, PDVec, Any, Any}","page":"Dict vectors","title":"Rimu.DictVectors.perform_spawns!","text":"perform_spawns!(w::PDWorkingMemory, v::PDVec, ham, boost)\n\nPerform spawns from v through ham to w. boost increases the number of spawns without affecting the expectation value of the process.\n\nSee PDVec and PDWorkingMemory.\n\n\n\n\n\n","category":"method"},{"location":"dictvectors.html#Rimu.DictVectors.remote_segments-Tuple{PDWorkingMemory, Any}","page":"Dict vectors","title":"Rimu.DictVectors.remote_segments","text":"remote_segments(w::PDWorkingMemory, rank_id)\n\nReturns iterator over the segments in the first column of w that belong to rank rank_id. Iterates Dicts.\n\nSee PDWorkingMemory.\n\n\n\n\n\n","category":"method"},{"location":"dictvectors.html#Rimu.DictVectors.synchronize_remote!-Tuple{PDWorkingMemory}","page":"Dict vectors","title":"Rimu.DictVectors.synchronize_remote!","text":"synchronize_remote!([::Communicator,] w::PDWorkingMemory) -> names, values\n\nSynchronize non-local segments across MPI and add the results to the first column. Controlled by the Communicator. This can only be perfomed after collect_local!.\n\nShould return a Tuple of names and a Tuple of values to report.\n\nSee PDWorkingMemory.\n\n\n\n\n\n","category":"method"},{"location":"dictvectors.html#Communicators","page":"Dict vectors","title":"Communicators","text":"","category":"section"},{"location":"dictvectors.html","page":"Dict vectors","title":"Dict vectors","text":"Modules = [DictVectors]\nPages = [\"communicators.jl\"]","category":"page"},{"location":"dictvectors.html#Rimu.DictVectors.AllToAll","page":"Dict vectors","title":"Rimu.DictVectors.AllToAll","text":"AllToAll{K,V}(; mpi_comm, n_segments, report) <: Communicator\n\nCommunicator that uses collective communication using MPI.Alltoall[v]!.\n\nKeyword arguments\n\nmpi_comm=MPI.COMM_WORLD: the MPI communicator to use.\nn_segments=Threads.nthreads(): the number of segments per rank to use. Should match the PDVec the communicator is used with.\nreport=false: if set to true, report MPI communication times during a projector Monte Carlo run.\n\nSee also: Communicator.\n\n\n\n\n\n","category":"type"},{"location":"dictvectors.html#Rimu.DictVectors.Communicator","page":"Dict vectors","title":"Rimu.DictVectors.Communicator","text":"abstract type Communicator\n\nCommunicators are used to handle MPI communication when using PDVecs. Currently, three implementations are provided, NotDistributed, AllToAll and PointToPoint. The communicator is picked automatically according to the number of MPI ranks available.\n\nWhen implementing a communicator, use local_segments and remote_segments.\n\nInterface\n\nsynchronize_remote!\nmpi_rank\nmpi_size\nmpi_comm\n\nOptional interface\n\nis_distributed: defaults to returning true.\nmerge_remote_reductions: defaults to using MPI.Allreduce.\ntotal_num_segments: defaults to n * mpi_size.\ntarget_segment: defaults to selecting using fastrange to pick the segment.\n\nSee also: PDVec, PDWorkingMemory.\n\n\n\n\n\n","category":"type"},{"location":"dictvectors.html#Rimu.DictVectors.LocalPart","page":"Dict vectors","title":"Rimu.DictVectors.LocalPart","text":"LocalPart <: Communicator\n\nWhen localpart is used, the vector's Communicator is replaced with this. This allows iteration and local reductions.\n\n\n\n\n\n","category":"type"},{"location":"dictvectors.html#Rimu.DictVectors.NestedSegmentedBuffer","page":"Dict vectors","title":"Rimu.DictVectors.NestedSegmentedBuffer","text":"NestedSegmentedBuffer{T}(nrows) <: AbstractMatrix{AbstractVector{T}}\n\nMatrix of vectors stored in a single buffer with collective MPI communication support. The number of rows in the matrix is fixed to nrows.\n\nUsed in the AllToAll communication strategy, where each column corresponds to an MPI rank and each row corresponds to a segment in the PDVec.\n\nSupported operations\n\nappend_collections!: add a column to the matrix.\nappend_empty_column!: add an empty column to the matrix.\nmpi_exchange_alltoall!: each rank sends the i-th column of the matrix to the (i-1)-st rank.\nmpi_exchange_allgather!: each rank sends the 1-st column of the matrix to all ranks.\n\nSee also: SegmentedBuffer.\n\n\n\n\n\n","category":"type"},{"location":"dictvectors.html#Rimu.DictVectors.NotDistributed","page":"Dict vectors","title":"Rimu.DictVectors.NotDistributed","text":"NotDistributed <: Communicator\n\nThis Communicator is used when MPI is not available.\n\n\n\n\n\n","category":"type"},{"location":"dictvectors.html#Rimu.DictVectors.PointToPoint","page":"Dict vectors","title":"Rimu.DictVectors.PointToPoint","text":"PointToPoint{K,V}(; mpi_comm, report) <: Communicator\n\nMPI Communicator that uses circular communication using MPI.Isend and MPI.Recv!.\n\nKeyword arguments\n\nmpi_comm=MPI.COMM_WORLD: the MPI communicator to use.\nreport=false: if set to true, report MPI communication times during a projector Monte Carlo run.\n\n\n\n\n\n","category":"type"},{"location":"dictvectors.html#Rimu.DictVectors.SegmentedBuffer","page":"Dict vectors","title":"Rimu.DictVectors.SegmentedBuffer","text":"SegmentedBuffer{T}() <: AbstractVector{AbstractVector{T}}\n\nBehaves like a vector of vectors, but is stored in a single buffer. It can be sent/received over MPI keeping its structure intact. Used in the PointToPoint communication strategy.\n\nSupported operations\n\nreplace_collections!: insert data into the buffers\nmpi_send: send the contents of a buffer to a given rank\nmpi_recv_any!: receive a message sent by mpi_send from any rank, storing the contents in this buffer\n\nSee also: NestedSegmentedBuffer.\n\n\n\n\n\n","category":"type"},{"location":"dictvectors.html#Rimu.DictVectors.append_collections!-Tuple{Rimu.DictVectors.NestedSegmentedBuffer, Any}","page":"Dict vectors","title":"Rimu.DictVectors.append_collections!","text":"append_collections!(buf::NestedSegmentedBuffer, iters)\n\nAdd a column to buf. The length of iters should match buf.nrows.\n\nSee also: NestedSegmentedBuffer, append_empty_column!.\n\n\n\n\n\n","category":"method"},{"location":"dictvectors.html#Rimu.DictVectors.append_empty_column!-Tuple{Rimu.DictVectors.NestedSegmentedBuffer}","page":"Dict vectors","title":"Rimu.DictVectors.append_empty_column!","text":"append_empty_column!(buf::NestedSegmentedBuffer)\n\nLike append_collections!, but adds an empty column.\n\nSee also: NestedSegmentedBuffer, append_collections!.\n\n\n\n\n\n","category":"method"},{"location":"dictvectors.html#Rimu.DictVectors.copy_to_local!","page":"Dict vectors","title":"Rimu.DictVectors.copy_to_local!","text":"copy_to_local!([::Communicator,] w::PDWorkingMemory, t::PDVec) -> PDVec\n\nCopy pairs in t from all ranks and return them as a (possibly) new PDVec, possibly using the PDWorkingMemory as temporary storage.\n\nSee also: PDVec, PDWorkingMemory, Communicator.\n\n\n\n\n\n","category":"function"},{"location":"dictvectors.html#Rimu.DictVectors.is_distributed-Tuple{Rimu.DictVectors.Communicator}","page":"Dict vectors","title":"Rimu.DictVectors.is_distributed","text":"is_distributed(::Communicator)\n\nReturn true if Communicator operates over MPI.\n\n\n\n\n\n","category":"method"},{"location":"dictvectors.html#Rimu.DictVectors.merge_remote_reductions-Tuple{Rimu.DictVectors.Communicator, Any, Any}","page":"Dict vectors","title":"Rimu.DictVectors.merge_remote_reductions","text":"merge_remote_reductions(c::Communicator, op, x)\n\nMerge the results of reductions over MPI. By default, it uses MPI.Allreduce.\n\nSee also: Communicator.\n\n\n\n\n\n","category":"method"},{"location":"dictvectors.html#Rimu.DictVectors.mpi_exchange_allgather!-Tuple{Rimu.DictVectors.NestedSegmentedBuffer, Rimu.DictVectors.NestedSegmentedBuffer, Any}","page":"Dict vectors","title":"Rimu.DictVectors.mpi_exchange_allgather!","text":"mpi_exchange_allgather!(src::NestedSegmentedBuffer, dst::NestedSegmentedBuffer, comm)\n\nThe first and only column in src will be sent to all ranks. The data from all ranks will be gethered in dst. After this operation, dst will contain the same data on all ranks.\n\nSee also NestedSegmentedBuffer, mpi_exchange_alltoall!.\n\n\n\n\n\n","category":"method"},{"location":"dictvectors.html#Rimu.DictVectors.mpi_exchange_alltoall!-Tuple{Rimu.DictVectors.NestedSegmentedBuffer, Rimu.DictVectors.NestedSegmentedBuffer, Any}","page":"Dict vectors","title":"Rimu.DictVectors.mpi_exchange_alltoall!","text":"mpi_exchange_alltoall!(src::NestedSegmentedBuffer, dst::NestedSegmentedBuffer, comm)\n\nThe n-th column from src will be sent to rank n-1. The data sent from rank r will be stored in the (r+1)-st column of dst.\n\nSee also: NestedSegmentedBuffer, mpi_exchange_allgather!.\n\n\n\n\n\n","category":"method"},{"location":"dictvectors.html#Rimu.DictVectors.mpi_recv_any!-Tuple{Rimu.DictVectors.SegmentedBuffer, Any}","page":"Dict vectors","title":"Rimu.DictVectors.mpi_recv_any!","text":"mpi_recv_any!(buf::SegmentedBuffer, comm::MPI_Comm) -> Int\n\nFind a source that is ready to send a buffer and receive from it. Return the rank ID of the sender.\n\n\n\n\n\n","category":"method"},{"location":"dictvectors.html#Rimu.DictVectors.mpi_send-Tuple{Rimu.DictVectors.SegmentedBuffer, Any, Any}","page":"Dict vectors","title":"Rimu.DictVectors.mpi_send","text":"mpi_send(buf::SegmentedBuffer, dest, comm::MPI.Comm)\n\nSend the buffer to rank with id dest.\n\n\n\n\n\n","category":"method"},{"location":"dictvectors.html#Rimu.DictVectors.replace_collections!-Tuple{Rimu.DictVectors.SegmentedBuffer, Any}","page":"Dict vectors","title":"Rimu.DictVectors.replace_collections!","text":"replace_collections!(buf::SegmentedBuffer, iters)\n\nInsert collections in iters into a SegmentedBuffer.\n\njulia> using Rimu.DictVectors: SegmentedBuffer\n\njulia> buf = SegmentedBuffer{Int}()\n0-element SegmentedBuffer{Int64}\n\njulia> Rimu.DictVectors.replace_collections!(buf, [[1,2,3], [4,5]])\n2-element SegmentedBuffer{Int64}:\n [1, 2, 3]\n [4, 5]\n\njulia> Rimu.DictVectors.replace_collections!(buf, [[1], [2,3], [4]])\n3-element SegmentedBuffer{Int64}:\n [1]\n [2, 3]\n [4]\n\n\n\n\n\n","category":"method"},{"location":"dictvectors.html#Rimu.DictVectors.target_segment-Tuple{Rimu.DictVectors.Communicator, Any, Any}","page":"Dict vectors","title":"Rimu.DictVectors.target_segment","text":"target_segment(c::Communicator, k, num_segments) -> target, is_local\n\nThis function is used to determine where in the PDVec a key should be stored. If the key is local (stored on the same MPI rank), return its segment index and true. If the key is non-local, return any value and false.\n\nSee also: PDVec, Communicator.\n\n\n\n\n\n","category":"method"},{"location":"dictvectors.html#Rimu.DictVectors.total_num_segments-Tuple{Rimu.DictVectors.Communicator, Any}","page":"Dict vectors","title":"Rimu.DictVectors.total_num_segments","text":"total_num_segments(c::Communicator, n) -> Int\n\nReturn the total number of segments, including the remote ones, where n is number of local segments.\n\nSee also: PDVec, Communicator.\n\n\n\n\n\n","category":"method"},{"location":"dictvectors.html#Rimu.mpi_comm","page":"Dict vectors","title":"Rimu.mpi_comm","text":"mpi_comm(::Communicator) -> MPI.Comm\n\nReturn the MPI.Comm that the Communicator operates on.\n\n\n\n\n\n","category":"function"},{"location":"dictvectors.html#Rimu.mpi_rank","page":"Dict vectors","title":"Rimu.mpi_rank","text":"mpi_rank(::Communicator) -> Int\n\nReturn the MPI rank of the Communicator.\n\n\n\n\n\n","category":"function"},{"location":"dictvectors.html#Rimu.mpi_size","page":"Dict vectors","title":"Rimu.mpi_size","text":"mpi_size(::Communicator) -> Int\n\nReturn the total number of MPI ranks in the Communicator.\n\n\n\n\n\n","category":"function"},{"location":"dictvectors.html#Index","page":"Dict vectors","title":"Index","text":"","category":"section"},{"location":"dictvectors.html","page":"Dict vectors","title":"Dict vectors","text":"Pages = [\"dictvectors.md\"]","category":"page"},{"location":"custom_hamiltonians.html#Advanced-operator-usage-and-custom-Hamiltonians","page":"Custom Hamiltonians","title":"Advanced operator usage and custom Hamiltonians","text":"","category":"section"},{"location":"custom_hamiltonians.html","page":"Custom Hamiltonians","title":"Custom Hamiltonians","text":"Rimu can be used to work with custom Hamiltonians and observables that are user-defined and not part of the Rimu.jl package. To make this possible and reliable, Rimu exposes a number of interfaces and provides helper functions to test compliance with the interfaces through the submodule Rimu.InterfaceTests, see Interface tests. This section covers the relevant interfaces, the interface functions as well as potentially useful helper functions.","category":"page"},{"location":"custom_hamiltonians.html","page":"Custom Hamiltonians","title":"Custom Hamiltonians","text":"In order to define custom Hamiltonians or observables it is useful to know how the operator type hierarchy works in Rimu. For an example of how to implement custom Hamiltonians that are not part of the Rimu.jl package, see RimuLegacyHamiltonians.jl.","category":"page"},{"location":"custom_hamiltonians.html#Operator-type-hierarchy","page":"Custom Hamiltonians","title":"Operator type hierarchy","text":"","category":"section"},{"location":"custom_hamiltonians.html","page":"Custom Hamiltonians","title":"Custom Hamiltonians","text":"Rimu offers a hierarchy of abstract types that define interfaces with different requirements for operators:","category":"page"},{"location":"custom_hamiltonians.html","page":"Custom Hamiltonians","title":"Custom Hamiltonians","text":"AbstractHamiltonian <: AbstractOperator <: AbstractObservable","category":"page"},{"location":"custom_hamiltonians.html","page":"Custom Hamiltonians","title":"Custom Hamiltonians","text":"The different abstract types have different requirements and are meant to be used for different purposes. ","category":"page"},{"location":"custom_hamiltonians.html","page":"Custom Hamiltonians","title":"Custom Hamiltonians","text":"AbstractHamiltonians are fully featured models that define a Hilbert space and a linear operator over a scalar field. They can be passed as a Hamiltonian into ProjectorMonteCarloProblem or ExactDiagonalizationProblem.\nAbstractOperator and AbstractObservable are supertypes of AbstractHamiltonian with less stringent conditions. They are useful for defining observables that can be used in a three-way dot product, or passed as observables into a ReplicaStrategy that can be inserted with the keyword replica_strategy into a ProjectorMonteCarloProblem.","category":"page"},{"location":"custom_hamiltonians.html#Hamiltonians-interface","page":"Custom Hamiltonians","title":"Hamiltonians interface","text":"","category":"section"},{"location":"custom_hamiltonians.html","page":"Custom Hamiltonians","title":"Custom Hamiltonians","text":"Behind the implementation of a particular model is a more abstract interface for defining Hamiltonians. If you want to define a new model you should make use of this interface. A new model Hamiltonian should subtype to AbstractHamiltonian and implement the relevant methods.","category":"page"},{"location":"custom_hamiltonians.html","page":"Custom Hamiltonians","title":"Custom Hamiltonians","text":"AbstractHamiltonian\noffdiagonals\ndiagonal_element\nstarting_address","category":"page"},{"location":"custom_hamiltonians.html#Rimu.Interfaces.AbstractHamiltonian","page":"Custom Hamiltonians","title":"Rimu.Interfaces.AbstractHamiltonian","text":"AbstractHamiltonian{T} <: AbstractOperator{T}\n\nSupertype that provides an interface for linear operators over a linear space with scalar type T that are suitable for FCIQMC (with ProjectorMonteCarloProblem). Indexing is done with addresses (typically not integers) from an address space that may be large (and will not need to be completely generated).\n\nAbstractHamiltonian instances operate on vectors of type AbstractDVec from the module DictVectors and work well with addresses of type AbstractFockAddress from the module BitStringAddresses. The type works well with the external package KrylovKit.jl.\n\nFor available implementations see Hamiltonians.\n\nInterface\n\nBasic interface methods to implement:\n\nstarting_address(::AbstractHamiltonian)\ndiagonal_element(::AbstractHamiltonian, address)\nnum_offdiagonals(::AbstractHamiltonian, address)\nget_offdiagonal(::AbstractHamiltonian, address, chosen::Integer) (optional, see below)\n\nOptional additional methods to implement:\n\nLOStructure(::Type{typeof(lo)}): defaults to AdjointUnknown\ndimension(::AbstractHamiltonian, addr): defaults to dimension of address space\nallows_address_type(h::AbstractHamiltonian, type): defaults to type :< typeof(starting_address(h))\nmomentum(::AbstractHamiltonian): no default\n\nProvides the following functions and methods:\n\noffdiagonals: iterator over reachable off-diagonal matrix elements\nrandom_offdiagonal: function to generate random off-diagonal matrix element\n*(H, v): deterministic matrix-vector multiply (allocating)\nH(v): equivalent to H * v.\nmul!(w, H, v): mutating matrix-vector multiply.\ndot(x, H, v): compute x⋅(H*v) minimizing allocations.\nH[address1, address2]: indexing with getindex() - mostly for testing purposes (slow!)\nBasisSetRepresentation: construct a basis set repesentation\nsparse, Matrix: construct a (sparse) matrix representation\n\nAlternatively to the above, offdiagonals can be implemented instead of get_offdiagonal. Sometimes this can be done efficiently. In this case num_offdiagonals should provide an upper bound on the number of elements obtained when iterating offdiagonals.\n\nSee also Hamiltonians, Interfaces, AbstractOperator, AbstractObservable.\n\n\n\n\n\n","category":"type"},{"location":"custom_hamiltonians.html#Rimu.Interfaces.offdiagonals","page":"Custom Hamiltonians","title":"Rimu.Interfaces.offdiagonals","text":"offdiagonals(h::AbstractHamiltonian, address)\n\nReturn an iterator over nonzero off-diagonal matrix elements of h in the same column as address. Will iterate over pairs (newaddress, matrixelement).\n\nExample\n\njulia> address = BoseFS(3,2,1);\n\n\njulia> H = HubbardReal1D(address);\n\n\njulia> h = offdiagonals(H, address)\n6-element Rimu.Hamiltonians.Offdiagonals{BoseFS{6, 3, BitString{8, 1, UInt8}}, Float64, HubbardReal1D{Float64, BoseFS{6, 3, BitString{8, 1, UInt8}}, 1.0, 1.0}}:\n (fs\"|2 3 1⟩\", -3.0)\n (fs\"|2 2 2⟩\", -2.449489742783178)\n (fs\"|3 1 2⟩\", -2.0)\n (fs\"|4 1 1⟩\", -2.8284271247461903)\n (fs\"|4 2 0⟩\", -2.0)\n (fs\"|3 3 0⟩\", -1.7320508075688772)\n\nPart of the AbstractHamiltonian interface.\n\nExtemded help\n\noffdiagonals return and iterator of type <:AbstractOffdiagonals. It defaults to returning Offdiagonals(h, a)\n\nSee also Offdiagonals, AbstractOffdiagonals.\n\n\n\n\n\n","category":"function"},{"location":"custom_hamiltonians.html#Rimu.Interfaces.diagonal_element","page":"Custom Hamiltonians","title":"Rimu.Interfaces.diagonal_element","text":"diagonal_element(ham, address)\n\nCompute the diagonal matrix element of the linear operator ham at address address.\n\nExample\n\njulia> address = BoseFS((3, 2, 1));\n\n\njulia> H = HubbardMom1D(address);\n\n\njulia> diagonal_element(H, address)\n8.666666666666664\n\nPart of the AbstractHamiltonian interface.\n\n\n\n\n\n","category":"function"},{"location":"custom_hamiltonians.html#Rimu.Interfaces.starting_address","page":"Custom Hamiltonians","title":"Rimu.Interfaces.starting_address","text":"starting_address(h)\n\nReturn the starting address for Hamiltonian h. When called on an AbstractMatrix, starting_address returns the index of the lowest diagonal element.\n\nExample\n\njulia> address = BoseFS((3, 2, 1));\n\n\njulia> H = HubbardMom1D(address);\n\n\njulia> address == starting_address(H)\ntrue\n\nPart of the AbstractHamiltonian interface.\n\n\n\n\n\n","category":"function"},{"location":"custom_hamiltonians.html","page":"Custom Hamiltonians","title":"Custom Hamiltonians","text":"The following functions may be implemented instead of offdiagonals.","category":"page"},{"location":"custom_hamiltonians.html","page":"Custom Hamiltonians","title":"Custom Hamiltonians","text":"num_offdiagonals\nget_offdiagonal","category":"page"},{"location":"custom_hamiltonians.html#Rimu.Interfaces.num_offdiagonals","page":"Custom Hamiltonians","title":"Rimu.Interfaces.num_offdiagonals","text":"num_offdiagonals(ham, address)\n\nCompute the number of number of reachable configurations from address address.\n\nExample\n\njulia> address = BoseFS((3, 2, 1));\n\n\njulia> H = HubbardMom1D(address);\n\n\njulia> num_offdiagonals(H, address)\n10\n\nPart of the AbstractHamiltonian interface.\n\n\n\n\n\n","category":"function"},{"location":"custom_hamiltonians.html#Rimu.Interfaces.get_offdiagonal","page":"Custom Hamiltonians","title":"Rimu.Interfaces.get_offdiagonal","text":"newadd, me = get_offdiagonal(ham, address, chosen)\n\nCompute value me and new address newadd of a single (off-diagonal) matrix element in a Hamiltonian ham. The off-diagonal element is in the same column as address address and is indexed by integer index chosen.\n\nExample\n\njulia> addr = BoseFS(3, 2, 1);\n\njulia> H = HubbardMom1D(addr);\n\njulia> get_offdiagonal(H, addr, 3)\n(BoseFS{6,3}(2, 1, 3), 1.0)\n\nPart of the AbstractHamiltonian interface.\n\n\n\n\n\n","category":"function"},{"location":"custom_hamiltonians.html","page":"Custom Hamiltonians","title":"Custom Hamiltonians","text":"The following functions come with default implementations, but may be customized.","category":"page"},{"location":"custom_hamiltonians.html","page":"Custom Hamiltonians","title":"Custom Hamiltonians","text":"random_offdiagonal\nHamiltonians.LOStructure\ndimension\nhas_adjoint\nallows_address_type\nBase.eltype\nVectorInterface.scalartype\nmul!","category":"page"},{"location":"custom_hamiltonians.html#Rimu.Interfaces.random_offdiagonal","page":"Custom Hamiltonians","title":"Rimu.Interfaces.random_offdiagonal","text":"random_offdiagonal(offdiagonals::AbstractOffdiagonals)\nrandom_offdiagonal(ham::AbstractHamiltonian, address)\n-> newaddress, probability, matrixelement\n\nGenerate a single random excitation, i.e. choose from one of the accessible off-diagonal elements in the column corresponding to address in the Hamiltonian matrix represented by ham. Alternatively, pass as argument an iterator over the accessible matrix elements.\n\nPart of the AbstractHamiltonian interface.\n\n\n\n\n\n","category":"function"},{"location":"custom_hamiltonians.html#Rimu.Interfaces.LOStructure","page":"Custom Hamiltonians","title":"Rimu.Interfaces.LOStructure","text":"LOStructure(op::AbstractHamiltonian)\nLOStructure(typeof(op))\n\nReturn information about the structure of the linear operator op. LOStructure is used as a trait to speficy symmetries or other properties of the linear operator op that may simplify or speed up calculations. Implemented instances are:\n\nIsDiagonal(): The operator is diagonal.\nIsHermitian(): The operator is complex and Hermitian or real and symmetric.\nAdjointKnown(): The operator is not Hermitian, but its adjoint is implemented.\nAdjointUnknown(): adjoint for this operator is not implemented.\n\nPart of the AbstractHamiltonian interface.\n\nIn order to define this trait for a new linear operator type, define a method for LOStructure(::Type{<:MyNewLOType}) = ….\n\n\n\n\n\n","category":"type"},{"location":"custom_hamiltonians.html#Rimu.Hamiltonians.dimension","page":"Custom Hamiltonians","title":"Rimu.Hamiltonians.dimension","text":"dimension(h::AbstractHamiltonian, addr=starting_address(h))\ndimension(h::AbstractObservable, addr)\ndimension(addr::AbstractFockAddress)\ndimension(::Type{<:AbstractFockAddress})\n\nReturn the estimated dimension of Hilbert space. May return a BigInt number.\n\nWhen called on an address or address type, the dimension of the linear space spanned by the address type is returned. When called on an AbstractHamiltonian, an upper bound on the dimension of the matrix representing the Hamiltonian is returned.\n\nExamples\n\njulia> dimension(OccupationNumberFS(1,2,3))\n16777216\n\njulia> dimension(HubbardReal1D(OccupationNumberFS(1,2,3)))\n28\n\njulia> dimension(BoseFS{200,100})\n1386083821086188248261127842108801860093488668581216236221011219101585442774669540\n\njulia> Float64(ans)\n1.3860838210861882e81\n\nPart of the AbstractHamiltonian interface. See also BasisSetRepresentation.\n\nExtended Help\n\nThe default fallback for dimension called on an AbstractHamiltonian is to return the dimension of the address space, which provides an upper bound. For new Hamiltonians a tighter bound can be provided by defining a custom method.\n\nWhen extending AbstractHamiltonian, define a method for the two-argument form dimension(h::MyNewHamiltonian, addr). For number-conserving Hamiltonians, the function Hamiltonians.number_conserving_dimension may be useful.\n\nWhen extending AbstractFockAddress, define a method for dimension(::Type{MyNewFockAddress}).\n\n\n\n\n\n","category":"function"},{"location":"custom_hamiltonians.html#Rimu.Interfaces.has_adjoint","page":"Custom Hamiltonians","title":"Rimu.Interfaces.has_adjoint","text":"has_adjoint(op)\n\nReturn true if adjoint is defined on op.\n\nPart of the AbstractHamiltonian interface.\n\nSee also LOStructure.\n\n\n\n\n\n","category":"function"},{"location":"custom_hamiltonians.html#Rimu.Interfaces.allows_address_type","page":"Custom Hamiltonians","title":"Rimu.Interfaces.allows_address_type","text":"allows_address_type(operator, addr_or_type)\n\nReturns true if addr_or_type is a valid address for operator. Otherwise, returns false.\n\nPart of the AbstractHamiltonian interface.\n\nExtended help\n\nDefaults to addr_or_type <: typeof(starting_address(operator)). Overload this function if the operator can be used with addresses of different types.\n\n\n\n\n\n","category":"function"},{"location":"custom_hamiltonians.html#Base.eltype","page":"Custom Hamiltonians","title":"Base.eltype","text":"eltype(op::AbstractObservable)\n\nReturn the type of the elements of the operator. This can be a vector value. For the underlying scalar type use scalartype.\n\nPart of the AbstractObservable interface.\n\nnote: Note\nNew types do not have to implement this method explicitly. An implementation is provided based on the AbstractObservable's type parameter.\n\n\n\n\n\n","category":"function"},{"location":"custom_hamiltonians.html#VectorInterface.scalartype","page":"Custom Hamiltonians","title":"VectorInterface.scalartype","text":"scalartype(op::AbstractObservable)\n\nReturn the type of the underlying scalar field of the operator. This may be different from the element type of the operator returned by eltype, which can be a vector value.\n\nPart of the AbstractObservable interface.\n\nnote: Note\nNew types do not have to implement this method explicitly. An implementation is provided based on the AbstractObservable's type parameter.\n\n\n\n\n\n","category":"function"},{"location":"custom_hamiltonians.html#LinearAlgebra.mul!","page":"Custom Hamiltonians","title":"LinearAlgebra.mul!","text":"LinearAlgebra.mul!(w::AbstractDVec, op::AbstractOperator, v::AbstractDVec)\n\nIn place multiplication of op with v and storing the result in w. The result is returned. Note that w needs to have a valtype that can hold a product of instances of eltype(op) and valtype(v). Moreover, the StochasticStyle of w needs to be <:IsDeterministic.\n\nPart of the AbstractOperator interface.\n\nThe default implementation relies of diagonal_element and offdiagonals to access the elements of the operator. The function can be overloaded for custom operators.\n\n\n\n\n\n","category":"function"},{"location":"custom_hamiltonians.html","page":"Custom Hamiltonians","title":"Custom Hamiltonians","text":"This interface relies on unexported functionality, including","category":"page"},{"location":"custom_hamiltonians.html","page":"Custom Hamiltonians","title":"Custom Hamiltonians","text":"Hamiltonians.adjoint\nHamiltonians.dot\nHamiltonians.AbstractOffdiagonals\nHamiltonians.Offdiagonals\nHamiltonians.check_address_type\nHamiltonians.number_conserving_dimension\nHamiltonians.number_conserving_bose_dimension\nHamiltonians.number_conserving_fermi_dimension","category":"page"},{"location":"custom_hamiltonians.html#Base.adjoint","page":"Custom Hamiltonians","title":"Base.adjoint","text":"adjoint(::LOStructure, op::AbstractObservable)\n\nRepresent the adjoint of an AbstractObservable. Extend this method to define custom adjoints.\n\n\n\n\n\n","category":"function"},{"location":"custom_hamiltonians.html#LinearAlgebra.dot","page":"Custom Hamiltonians","title":"LinearAlgebra.dot","text":"dot(w, op::AbstractObservable, v)\n\nEvaluate w⋅op(v) minimizing memory allocations.\n\n\n\n\n\n","category":"function"},{"location":"custom_hamiltonians.html#Rimu.Hamiltonians.AbstractOffdiagonals","page":"Custom Hamiltonians","title":"Rimu.Hamiltonians.AbstractOffdiagonals","text":"AbstractOffdiagonals{A,T}<:AbstractVector{Tuple{A,T}}\n\nIterator over new address and matrix elements for reachable off-diagonal matrix elements of a linear operator.\n\nSee Offdiagonals for a default implementation.\n\nMethods to define\n\noffdiagonals(h, a)::AbstractOffdiagonals: This function is used to construct the correct type of offdiagonals for a given combination of Hamiltonian h and Fock address a.\nBase.getindex(::AbstractOffdiagonals, i): should be equivalent to get_offdiagonal(h, a, i).\nBase.size(::AbstractOffdiagonals): should be equivalent to num_offdiagonals(h, a).\n\nSee also offdiagonals, AbstractHamiltonian, AbstractOperator.\n\n\n\n\n\n","category":"type"},{"location":"custom_hamiltonians.html#Rimu.Hamiltonians.Offdiagonals","page":"Custom Hamiltonians","title":"Rimu.Hamiltonians.Offdiagonals","text":"Offdiagonals(h, address) <: AbstractOffdiagonals\n\nIterator over new address and matrix element for reachable off-diagonal matrix elements of linear operator h from address address. Represents an abstract vector containing the non-zero off-diagonal matrix elements of the column of h indexed by address. To construct this iterator use offdiagonals.\n\nThis is the default implementation of AbstractOffdiagonals defined in terms of num_offdiagonals and get_offdiagonal.\n\nSee also offdiagonals, AbstractHamiltonian, AbstractOperator.\n\n\n\n\n\n","category":"type"},{"location":"custom_hamiltonians.html#Rimu.Hamiltonians.check_address_type","page":"Custom Hamiltonians","title":"Rimu.Hamiltonians.check_address_type","text":"check_address_type(h::AbstractObservable, addr_or_type)\n\nThrow an ArgumentError if addr_or_type is not compatible with h, otherwise return true. Acceptable arguments are either an address or an address type, or a tuple or array thereof.\n\nSee also allows_address_type.\n\n\n\n\n\n","category":"function"},{"location":"custom_hamiltonians.html#Rimu.Hamiltonians.number_conserving_dimension","page":"Custom Hamiltonians","title":"Rimu.Hamiltonians.number_conserving_dimension","text":"number_conserving_dimension(address <: AbstractFockAddress)\n\nReturn the dimension of the Fock space spanned by the address type assuming particle number conservation.\n\nSee also number_conserving_bose_dimension, number_conserving_fermi_dimension, dimension.\n\n\n\n\n\n","category":"function"},{"location":"custom_hamiltonians.html#Rimu.Hamiltonians.number_conserving_bose_dimension","page":"Custom Hamiltonians","title":"Rimu.Hamiltonians.number_conserving_bose_dimension","text":"number_conserving_bose_dimension(n, m)\n\nReturn the dimension of the number-conserving Fock space for n bosons in m modes: binomial(n + m - 1, n).\n\nSee also number_conserving_fermi_dimension, number_conserving_dimension.\n\n\n\n\n\n","category":"function"},{"location":"custom_hamiltonians.html#Rimu.Hamiltonians.number_conserving_fermi_dimension","page":"Custom Hamiltonians","title":"Rimu.Hamiltonians.number_conserving_fermi_dimension","text":"number_conserving_fermi_dimension(n, m)\n\nReturn the dimension of the number-conserving Fock space for n fermions in m modes: binomial(m, n).\n\nSee also number_conserving_bose_dimension, number_conserving_dimension.\n\n\n\n\n\n","category":"function"},{"location":"custom_hamiltonians.html#Operator-and-observable-interface","page":"Custom Hamiltonians","title":"Operator and observable interface","text":"","category":"section"},{"location":"custom_hamiltonians.html","page":"Custom Hamiltonians","title":"Custom Hamiltonians","text":"AbstractObservable\nAbstractOperator","category":"page"},{"location":"custom_hamiltonians.html#Rimu.Interfaces.AbstractObservable","page":"Custom Hamiltonians","title":"Rimu.Interfaces.AbstractObservable","text":"AbstractObservable{T}\n\nMost permissive supertype for operators in the type hierarchy:\n\nAbstractHamiltonian{T} <: AbstractOperator{T} <: AbstractObservable{T}\n\nAbstractObservable provides an interface for operators that can appear in a three-way dot product dot(x, op, y) with two vectors of type AbstractDVec. The result is a value of type T, which is also returned by the eltype function. This may be a vector type associated with a scalar type returned by the scalartype function.\n\nThe AbstractObservable type is useful for defining observables that can be calculated in the context of a ProjectorMonteCarloProblem using AllOverlaps.\n\nInterface\n\nBasic interface methods to implement:\n\nInterfaces.dot_from_right(x, op, y)\nallows_address_type(op, type)\n\nOptional additional methods to implement:\n\nVectorInterface.scalartype(op): defaults to eltype(eltype(op))\nLOStructure(::Type{typeof(op)}): defaults to AdjointUnknown\n\nSee also AbstractOperator, AbstractHamiltonian, Interfaces.\n\n\n\n\n\n","category":"type"},{"location":"custom_hamiltonians.html#Rimu.Interfaces.AbstractOperator","page":"Custom Hamiltonians","title":"Rimu.Interfaces.AbstractOperator","text":"AbstractOperator{T} <: AbstractObservable{T}\n\nSupertype that provides an interface for linear operators over a linear space with elements of type T (returned by eltype) and general (custom type) indices called 'addresses'.\n\nAbstractOperator instances operate on vectors of type AbstractDVec from the module DictVectors and work well with addresses of type AbstractFockAddress from the module BitStringAddresses.\n\nThe defining feature of an AbstractOperator is that it can be applied to a vector with mul!(y, op, x) and that three-way dot products can be calculated with dot(x, op, y).\n\nThe AbstractOperator type is useful for defining operators that are not necessarily Hamiltonians, but that can be used in the context of a ProjectorMonteCarloProblem as observable operators in a ReplicaStrategy, e.g. for defining correlation functions. In contrast to AbstractHamiltonians, AbstractOperators do not need to have a starting_address. Moreover, the eltype of an AbstractOperator can be a vector value whereas AbstractHamiltonians requre a scalar eltype.\n\nAbstractHamiltonian{T} <: AbstractOperator{T} <: AbstractObservable{T}\n\nThe AbstractOperator type is part of the AbstractObservable hierarchy. It is more restrictive than AbstractObservable in that it requires the interface for the generation of diagonal and off-diagonal elements.\n\nFor concrete implementations see Hamiltonians. In order to implement a Hamiltonian for use in ProjectorMonteCarloProblem or ExactDiagonalizationProblem use the type AbstractHamiltonian instead.\n\nInterface\n\nBasic interface methods to implement:\n\nallows_address_type(op, type)\ndiagonal_element(op, address)\nnum_offdiagonals(op, address) and\nget_offdiagonal(op, address, chosen) or offdiagonals\n\nOptional additional methods to implement:\n\nVectorInterface.scalartype(op): defaults to eltype(eltype(op))\nLOStructure(::Type{typeof(op)}): defaults to AdjointUnknown\ndimension(op, addr): defaults to dimension of address space\n\nIn order to calculate observables efficiently, it may make sense to implement custom methods for Interfaces.dot_from_right(x, op, y) and LinearAlgebra.mul!(y, op, x).\n\nSee also AbstractHamiltonian, Interfaces.\n\n\n\n\n\n","category":"type"},{"location":"custom_hamiltonians.html#Interface-tests","page":"Custom Hamiltonians","title":"Interface tests","text":"","category":"section"},{"location":"custom_hamiltonians.html","page":"Custom Hamiltonians","title":"Custom Hamiltonians","text":"Helper functions that can be used for testing the various interfaces are provided in the (unexported) submodule Rimu.InterfaceTests. ","category":"page"},{"location":"custom_hamiltonians.html","page":"Custom Hamiltonians","title":"Custom Hamiltonians","text":"Rimu.InterfaceTests","category":"page"},{"location":"custom_hamiltonians.html#Rimu.InterfaceTests","page":"Custom Hamiltonians","title":"Rimu.InterfaceTests","text":"The module Rimu.InterfaceTests provides functions to test compliance with the AbstractObservable, AbstractOperator, and AbstractHamiltonian interfaces. Load the module with using Rimu.InterfaceTests.\n\nThe module exports the following functions:\n\ntest_observable_interface\ntest_operator_interface\ntest_hamiltonian_interface\ntest_hamiltonian_structure\n\n\n\n\n\n","category":"module"},{"location":"custom_hamiltonians.html#Testing-functions","page":"Custom Hamiltonians","title":"Testing functions","text":"","category":"section"},{"location":"custom_hamiltonians.html","page":"Custom Hamiltonians","title":"Custom Hamiltonians","text":"Rimu.InterfaceTests.test_hamiltonian_interface\nRimu.InterfaceTests.test_hamiltonian_structure\nRimu.InterfaceTests.test_observable_interface\nRimu.InterfaceTests.test_operator_interface","category":"page"},{"location":"custom_hamiltonians.html#Rimu.InterfaceTests.test_hamiltonian_interface","page":"Custom Hamiltonians","title":"Rimu.InterfaceTests.test_hamiltonian_interface","text":"test_hamiltonian_interface(h, addr=starting_address(h); test_spawning=true)\n\nThe main purpose of this test function is to check that all required methods of the AbstractHamiltonian interface are defined and work as expected.\n\nSet test_spawning=false to skip tests that require offdiagonals to return an AbstractVector.\n\nThis function also tests the following properties of the Hamiltonian:\n\ndimension(h) ≥ dimension(h, addr)\nscalartype(h) === eltype(h)\nHamiltonian action on a vector <: AbstractDVec\nstarting_address returns an allows_address_type address\nLOStructure is one of IsDiagonal, IsHermitian, AdjointKnown\nthe AbstractOperator interface is tested\nthe AbstractObservable interface is tested\n\nExample\n\njulia> using Rimu.InterfaceTests\n\njulia> test_hamiltonian_interface(HubbardRealSpace(BoseFS(2,0,3,1)));\nTest Summary: | Pass Total Time\nObservable interface: HubbardRealSpace | 4 4 0.0s\nTest Summary: | Pass Total Time\nallows_address_type | 1 1 0.0s\nTest Summary: | Pass Total Time\nOperator interface: HubbardRealSpace | 9 9 0.0s\nTest Summary: | Pass Total Time\nallows_address_type | 1 1 0.0s\nTest Summary: | Pass Total Time\nHamiltonians-only tests with HubbardRealSpace | 6 6 0.0s\n\nSee also test_operator_interface, test_observable_interface.\n\n\n\n\n\n","category":"function"},{"location":"custom_hamiltonians.html#Rimu.InterfaceTests.test_hamiltonian_structure","page":"Custom Hamiltonians","title":"Rimu.InterfaceTests.test_hamiltonian_structure","text":"test_hamiltonian_structure(h::AbstractHamiltonian; sizelim=20)\n\nTest the LOStructure of a small Hamiltonian h by instantiating it as a sparse matrix and checking whether the structure of the matrix is constistent with the result of LOStructure(h) and the eltype is consistent with eltype(h).\n\nThis function is intended to be used in automated test for small Hamiltonians where instantiating the matrix is quick. A warning will print if the dimension of the Hamiltonian is larger than 20.\n\nExample\n\njulia> using Rimu.InterfaceTests\n\njulia> test_hamiltonian_structure(HubbardRealSpace(BoseFS(2,0,1)));\nTest Summary: | Pass Total Time\nstructure | 4 4 0.0s\n\n\n\n\n\n","category":"function"},{"location":"custom_hamiltonians.html#Rimu.InterfaceTests.test_observable_interface","page":"Custom Hamiltonians","title":"Rimu.InterfaceTests.test_observable_interface","text":"test_observable_interface(obs, addr)\n\nThis function tests compliance with the AbstractObservable interface for an observable obs at address addr (typically <: AbstractFockAddress) by checking that all required methods are defined.\n\nThe following properties are tested:\n\ndot(v, obs, v) returns a value of the same type as the eltype of the observable\nLOStructure is set consistently\n\nExample\n\njulia> using Rimu.InterfaceTests\n\njulia> test_observable_interface(ReducedDensityMatrix(2), FermiFS(1,0,1,1));\nTest Summary: | Pass Total Time\nObservable interface: ReducedDensityMatrix | 4 4 0.0s\n\nSee also AbstractObservable, test_operator_interface, test_hamiltonian_interface.\n\n\n\n\n\n","category":"function"},{"location":"custom_hamiltonians.html#Rimu.InterfaceTests.test_operator_interface","page":"Custom Hamiltonians","title":"Rimu.InterfaceTests.test_operator_interface","text":"test_operator_interface(op, addr; test_spawning=true)\n\nThis function tests compliance with the AbstractOperator interface for an operator op at address addr (typically <: AbstractFockAddress) by checking that all required methods are defined.\n\nIf test_spawning is true, tests are performed that require offdiagonals to return an Hamiltonians.AbstractOffDiagonals, which is a prerequisite for using the spawn! function. Otherwise, the spawning tests are skipped.\n\nThe following properties are tested:\n\ndiagonal_element returns a value of the same type as the eltype of the operator\noffdiagonals behaves like an AbstractVector\nnum_offdiagonals returns the correct number of offdiagonals\nrandom_offdiagonal returns a tuple with the correct types\nmul! and dot work as expected\ndimension returns a consistent value\nthe AbstractObservable interface is tested\n\nExample\n\njulia> using Rimu.InterfaceTests\n\njulia> test_operator_interface(SuperfluidCorrelator(3), BoseFS(1, 2, 3, 1));\nTest Summary: | Pass Total Time\nObservable interface: SuperfluidCorrelator | 4 4 0.0s\nTest Summary: | Pass Total Time\nallows_address_type | 1 1 0.0s\nTest Summary: | Pass Total Time\nOperator interface: SuperfluidCorrelator | 9 9 0.0s\n\nSee also AbstractOperator, test_observable_interface, test_hamiltonian_interface.\n\n\n\n\n\n","category":"function"},{"location":"custom_hamiltonians.html#Utilities-for-harmonic-oscillator-models","page":"Custom Hamiltonians","title":"Utilities for harmonic oscillator models","text":"","category":"section"},{"location":"custom_hamiltonians.html","page":"Custom Hamiltonians","title":"Custom Hamiltonians","text":"Useful utilities for harmonic oscillator in Cartesian basis, see HOCartesianContactInteractions and HOCartesianEnergyConservedPerDim.","category":"page"},{"location":"custom_hamiltonians.html","page":"Custom Hamiltonians","title":"Custom Hamiltonians","text":"get_all_blocks\nfock_to_cart","category":"page"},{"location":"custom_hamiltonians.html#Rimu.Hamiltonians.get_all_blocks","page":"Custom Hamiltonians","title":"Rimu.Hamiltonians.get_all_blocks","text":"get_all_blocks(h::Union{HOCartesianContactInteractions,HOCartesianEnergyConservedPerDim};\n target_energy = nothing,\n max_energy = nothing,\n max_blocks = nothing,\n method = :vertices,\n kwargs...) -> df\n\nFind all distinct blocks of h. Returns a DataFrame with columns\n\nblock_id: index of block in order found\nblock_E0: noninteracting energy of all elements in the block\nblock_size: number of elements in the block\naddr: first address that generates the block with e.g. BasisSetRepresentation\nindices: tuple of mode indices that allow recreation of the generating address addr; in this case use e.g. BoseFS(M; indices .=> 1) This is useful when the DataFrame is loaded from file since Arrow.jl converts custom types to NamedTuples.\nt_basis: time to generate the basis for each block\n\nKeyword arguments:\n\ntarget_energy: only blocks with this noninteracting energy are found\nmax_energy: only blocks with noninteracting energy less than this are found\nmax_blocks: exit after finding this many blocks\nmethod: Choose between :vertices and :comb for method of enumerating tuples of quantum numbers\nsave_to_file=nothing: if set then the DataFrame recording blocks is saved after each new block is found\nadditional kwargs: passed to isapprox for comparing block energies. Useful for anisotropic traps\n\nNote: If h was constructed with option block_by_level = false then the block seeds addr are determined by parity. In this case the blocks are not generated; t_basis will be zero, and block_size will be an estimate. Pass the seed addresses to BasisSetRepresentation with an appropriate filter to generate the blocks.\n\n\n\n\n\n","category":"function"},{"location":"custom_hamiltonians.html#Rimu.Hamiltonians.fock_to_cart","page":"Custom Hamiltonians","title":"Rimu.Hamiltonians.fock_to_cart","text":"fock_to_cart(addr, S; zero_index = true)\n\nConvert a Fock state address addr to Cartesian harmonic oscillator basis indices n_xn_yldots. These indices are bounded by S which is a tuple of the maximum number of states in each dimension. By default the groundstate in each dimension is indexed by 0, but this can be changed by setting zero_index = false.\n\n\n\n\n\n","category":"function"},{"location":"custom_hamiltonians.html","page":"Custom Hamiltonians","title":"Custom Hamiltonians","text":"Underlying integrals for the interaction matrix elements are implemented in the following unexported functions","category":"page"},{"location":"custom_hamiltonians.html","page":"Custom Hamiltonians","title":"Custom Hamiltonians","text":"Hamiltonians.four_oscillator_integral_general\nHamiltonians.ho_delta_potential\nHamiltonians.log_abs_oscillator_zero","category":"page"},{"location":"custom_hamiltonians.html#Rimu.Hamiltonians.four_oscillator_integral_general","page":"Custom Hamiltonians","title":"Rimu.Hamiltonians.four_oscillator_integral_general","text":"four_oscillator_integral_general(i, j, k, l; max_level = typemax(Int))\n\nIntegral of four one-dimensional harmonic oscillator functions,\n\n mathcalI(ijkl) = int_-infty^infty dx \n phi_i(x) phi_j(x) phi_k(x) phi_l(x)\n\nIndices i,j,k,l start at 0 for the groundstate.\n\nThis integral has a closed form in terms of the hypergeometric _3F_2 function, and is non-zero unless i+j+k+l is odd. See e.g. Titchmarsh (1948). This is a generalisation of the closed form in Papenbrock (2002), which is is the special case where i+j == k+l, but is numerically unstable for large arguments. Used in HOCartesianContactInteractions and HOCartesianEnergyConservedPerDim.\n\n\n\n\n\n","category":"function"},{"location":"custom_hamiltonians.html#Rimu.Hamiltonians.ho_delta_potential","page":"Custom Hamiltonians","title":"Rimu.Hamiltonians.ho_delta_potential","text":"ho_delta_potential(S, i, j; [vals])\n\nReturns the matrix element of a delta potential at the centre of a trap, i.e. the product of two harmonic oscillator functions evaluated at the origin,\n\n v_ij = phi_mathbfn_i(0) phi_mathbfn_j(0)\n\nwhich is only non-zero for even-parity states. The ith single particle state corresponds to a D-tuple of harmonic oscillator indices mathbfn_i. S defines the bounds of Cartesian harmonic oscillator indices for each dimension. The optional keyword argument vals allows passing pre-computed values of phi_i(0) to speed-up the calculation. The values can be calculated with log_abs_oscillator_zero.\n\nSee also HOCartesianCentralImpurity.\n\n\n\n\n\n","category":"function"},{"location":"custom_hamiltonians.html#Rimu.Hamiltonians.log_abs_oscillator_zero","page":"Custom Hamiltonians","title":"Rimu.Hamiltonians.log_abs_oscillator_zero","text":"log_abs_oscillator_zero(n)\n\nCompute the logarithm of the absolute value of the n^mathrmth 1D harmonic oscillator function evaluated at the origin. The overall sign is determined when the matrix element is evaluated in ho_delta_potential.\n\n\n\n\n\n","category":"function"},{"location":"custom_hamiltonians.html#Index","page":"Custom Hamiltonians","title":"Index","text":"","category":"section"},{"location":"custom_hamiltonians.html","page":"Custom Hamiltonians","title":"Custom Hamiltonians","text":"Pages = [\"custom_hamiltonians.md\"]","category":"page"}] } diff --git a/previews/PR308/statstools.html b/previews/PR308/statstools.html index b09711642..d6c5a7680 100644 --- a/previews/PR308/statstools.html +++ b/previews/PR308/statstools.html @@ -1,6 +1,6 @@ -StatsTools · Rimu.jl

Module StatsTools

The module StatsTools contains helper function for analysis and post processing of Monte Carlo data.

Blocking analysis

After equilibration, FCIQMC produces information about observables through correlated time series. In order to estimate the statistical errors the time series need to be decorrelated. The main workhorse for achieving this is the blocking_analysis, which is based on the paper by Flyvberg and Peterson JCP (1989), and automated with the M test of Jonsson PRE (2018).

Analysing the stochastic errors of observables obtained from the ratio of sample means is done with ratio_of_means, where error propagation of correlated uncertainties is done with the help of the package MonteCarloMeasurements.

Many convenience functions are implemented for directly analysing data obtained from solve as a DataFrame. See, e.g., shift_estimator and projected_energy. Asymptotically unbiased estimators are implemented as mixed_estimator, growth_estimator and rayleigh_replica_estimator.

Exported

Rimu.StatsTools.blocking_analysisMethod
blocking_analysis(v::AbstractVector; α = 0.01, corrected = true, skip=0, warn=true)
--> BlockingResult(mean, err, err_err, p_cov, k, blocks)

Compute the sample mean mean and estimate the standard deviation of the mean (standard error) err of a correlated time series. It uses the blocking algorithm from Flyvberg and Peterson JCP (1989) and the M test of Jonsson PRE (2018) at significance level $1-α$.

Use skip to skip the first skip elements in v. corrected controls whether bias correction for variances is used. If decorrelating the time series fails according to the M test, NaN is returned as the standard error and -1 for k. The keyword argument warn controls whether a warning message is logged.

The summary result is returned as a BlockingResult. k - 1 is the number of blocking transformations required to pass the hypothesis test for an uncorrelated time series and err_err the estimated standard error or err.

The detailed results from each reblocking step can be obtained with blocking_analysis_data.

See BlockingResult, shift_estimator, ratio_of_means, blocking_analysis_data.

source
Rimu.StatsTools.blocking_analysis_dataMethod
blocking_analysis_data(v::AbstractVector; kwargs...) ->
+StatsTools · Rimu.jl

Module StatsTools

The module StatsTools contains helper function for analysis and post processing of Monte Carlo data.

Blocking analysis

After equilibration, FCIQMC produces information about observables through correlated time series. In order to estimate the statistical errors the time series need to be decorrelated. The main workhorse for achieving this is the blocking_analysis, which is based on the paper by Flyvberg and Peterson JCP (1989), and automated with the M test of Jonsson PRE (2018).

Analysing the stochastic errors of observables obtained from the ratio of sample means is done with ratio_of_means, where error propagation of correlated uncertainties is done with the help of the package MonteCarloMeasurements.

Many convenience functions are implemented for directly analysing data obtained from solve as a DataFrame. See, e.g., shift_estimator and projected_energy. Asymptotically unbiased estimators are implemented as mixed_estimator, growth_estimator and rayleigh_replica_estimator.

Exported

Rimu.StatsTools.blocking_analysisMethod
blocking_analysis(v::AbstractVector; α = 0.01, corrected = true, skip=0, warn=true)
+-> BlockingResult(mean, err, err_err, p_cov, k, blocks)

Compute the sample mean mean and estimate the standard deviation of the mean (standard error) err of a correlated time series. It uses the blocking algorithm from Flyvberg and Peterson JCP (1989) and the M test of Jonsson PRE (2018) at significance level $1-α$.

Use skip to skip the first skip elements in v. corrected controls whether bias correction for variances is used. If decorrelating the time series fails according to the M test, NaN is returned as the standard error and -1 for k. The keyword argument warn controls whether a warning message is logged.

The summary result is returned as a BlockingResult. k - 1 is the number of blocking transformations required to pass the hypothesis test for an uncorrelated time series and err_err the estimated standard error or err.

The detailed results from each reblocking step can be obtained with blocking_analysis_data.

See BlockingResult, shift_estimator, ratio_of_means, blocking_analysis_data.

source
Rimu.StatsTools.blocking_analysis_dataMethod
blocking_analysis_data(v::AbstractVector; kwargs...) ->
 (; br::BlockingResult, df::DataFrame)

Perform a blocking_analysis and return the summary result br as well as a DataFrame df with information about the standard error in each blocking step.

For a description of the keyword arguments see blocking_analysis.

Example

julia> data = smoothen(rand(10_000), 2^6); # generate correlated data
 
 julia> br, df = blocking_analysis_data(data)
@@ -53,9 +53,9 @@
                │⠀⠒⠉⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⠀│
    -0.00012335 │⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠧⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤│
                └────────────────────────────────────────┘
-               ⠀0.64⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀k⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀13.36⠀

A vertical line at k==8 indicates the blocking step identified by hypothesis testing to decorrelate the time series data. The decorrelation length can thus be estimated at $2^{k-1} = 2^7 = 128$. Note that the data was correlated with a sliding window of $2^6$ steps.

See blocking_analysis, BlockingResult.

source
Statistics.covMethod
cov(r::BlockingResult{<:Complex})

Return the covariance matrix of the multivariate normal distribution approximating the uncertainty of the blocking result r of a complex time series. See (https://en.wikipedia.org/wiki/Complexnormaldistribution).

source
Rimu.StatsTools.ratio_of_meansMethod
ratio_of_means(num, denom; α=0.01, corrected=true, mc_samples=nothing, skip=0, warn=true)
--> r::RatioBlockingResult

Estimate the ratio of mean(num)/mean(denom) assuming that num and denom are possibly correlated time series, skipping the first skip elements. A blocking analysis with m-test is used to uncorrelate the time series, see blocking_analysis. The remaining standard error and correlation of the means is propagated using MonteCarloMeasurements. The results are reported as a RatioBlockingResult.

Robust estimates for the ratio are obtained from pmedian(r) and confidence intervals from pquantile(), e.g. pquantile(r, [0.025, 0.975]) for the 95% confidence interval.

Estimates from linear uncertainty propagation are returned as r.f and r.σ_f using x_by_y_linear. The standard error estimate r.σ_f should only be trusted when the coefficient of variation std(denom)/mean(denom) is small: abs(r.δ_y) < 0.1. Under this condition can the ratio be approximated as a normal distribution. See wikipedia and Díaz-Francés, Rubio (2013)

The keyword mc_samples controls the number of samples used for error propagation by MonteCarloMeasurements. Use nothing for the default and Val(1000) to set the number to 1000 samples in a type-consistent way.

The keyword warn controls whether warning messages are logged when blocking fails or noisy denominators are encountered.

Note: to compute statistics on the RatioBlockingResult, use functions pmedian, pquantile, pmiddle, piterate, pextrema, pminimum, pmaximum, pmean, and pcov.

source
Rimu.StatsTools.val_and_errsMethod
val_and_errs(x; n=1, p=nothing, name=:val) -> (;val, val_l, val_u)

Return the median and the lower and upper error bar for the uncertain value x as a NamedTuple. This is useful for plotting scripts. The interval [val - val_l, val + val_u] represents the confidence interval at level n*σ, or at probability p. Setting p overrides n. Supports MonteCarloMeasurements and Measurements. The names in the NamedTuple can be changed with name.

Example:

julia> results = [blocking_analysis(i:0.1:2i+20) for i in 1:3]; # mock results
+               ⠀0.64⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀k⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀13.36⠀

A vertical line at k==8 indicates the blocking step identified by hypothesis testing to decorrelate the time series data. The decorrelation length can thus be estimated at $2^{k-1} = 2^7 = 128$. Note that the data was correlated with a sliding window of $2^6$ steps.

See blocking_analysis, BlockingResult.

source
Statistics.covMethod
cov(r::BlockingResult{<:Complex})

Return the covariance matrix of the multivariate normal distribution approximating the uncertainty of the blocking result r of a complex time series. See (https://en.wikipedia.org/wiki/Complexnormaldistribution).

source
Rimu.StatsTools.ratio_of_meansMethod
ratio_of_means(num, denom; α=0.01, corrected=true, mc_samples=nothing, skip=0, warn=true)
+-> r::RatioBlockingResult

Estimate the ratio of mean(num)/mean(denom) assuming that num and denom are possibly correlated time series, skipping the first skip elements. A blocking analysis with m-test is used to uncorrelate the time series, see blocking_analysis. The remaining standard error and correlation of the means is propagated using MonteCarloMeasurements. The results are reported as a RatioBlockingResult.

Robust estimates for the ratio are obtained from pmedian(r) and confidence intervals from pquantile(), e.g. pquantile(r, [0.025, 0.975]) for the 95% confidence interval.

Estimates from linear uncertainty propagation are returned as r.f and r.σ_f using x_by_y_linear. The standard error estimate r.σ_f should only be trusted when the coefficient of variation std(denom)/mean(denom) is small: abs(r.δ_y) < 0.1. Under this condition can the ratio be approximated as a normal distribution. See wikipedia and Díaz-Francés, Rubio (2013)

The keyword mc_samples controls the number of samples used for error propagation by MonteCarloMeasurements. Use nothing for the default and Val(1000) to set the number to 1000 samples in a type-consistent way.

The keyword warn controls whether warning messages are logged when blocking fails or noisy denominators are encountered.

Note: to compute statistics on the RatioBlockingResult, use functions pmedian, pquantile, pmiddle, piterate, pextrema, pminimum, pmaximum, pmean, and pcov.

source
Rimu.StatsTools.val_and_errsMethod
val_and_errs(x; n=1, p=nothing, name=:val) -> (;val, val_l, val_u)

Return the median and the lower and upper error bar for the uncertain value x as a NamedTuple. This is useful for plotting scripts. The interval [val - val_l, val + val_u] represents the confidence interval at level n*σ, or at probability p. Setting p overrides n. Supports MonteCarloMeasurements and Measurements. The names in the NamedTuple can be changed with name.

Example:

julia> results = [blocking_analysis(i:0.1:2i+20) for i in 1:3]; # mock results
 
 julia> v = val_and_errs.(results, name="res"); # Vector of NamedTuple's with standard errors
 
@@ -66,14 +66,14 @@
 ─────┼───────────────────────────
    1 │    11.5  1.7282   1.7282
    2 │    13.0  1.7282   1.7282
-   3 │    14.5  1.78885  1.78885

See NamedTuple, val, errs, BlockingResult, RatioBlockingResult.

source
Rimu.StatsTools.growth_witnessFunction
growth_witness(df::DataFrame, [b];
     shift=:shift,
     norm=:norm,
     time_step=determine_constant_time_step(df),
     skip=0
 )
-growth_witness(sim::PMCSimulation, [b]; kwargs...)

Calculate the growth witness directly from the result (DataFrame or PMCSimulation) of solveing a ProjectorMonteCarloProblem. The keyword arguments shift and norm can be used to change the names of the relevant columns.

source
Rimu.StatsTools.growth_witnessMethod
growth_witness(shift::AbstractArray, norm::AbstractArray, dt, [b]; skip=0)

Compute the growth witness

\[G^{(n)} = S^{(n)} - \frac{\vert\mathbf{c}^{(n+1)}\vert - - \vert\mathbf{c}^{(n)}\vert}{\vert\mathbf{c}^{(n)}\vert d\tau},\]

where S is the shift and $\vert\mathbf{c}^{(n)}\vert ==$ norm[n, 1]. Setting b ≥ 1 a sliding average over b time steps is computed using smoothen(). The first skip time steps are skipped. mean(growth_witness) is approximately the same as growth_estimator with h=0.

See also growth_estimator.

source
Rimu.StatsTools.smoothenMethod
smoothen(noisy::AbstractVector, b)

Smoothen the array noisy by averaging over a sliding window of length b and wrapping noisy periodically. The mean(noisy) is preserved.

source
Rimu.StatsTools.growth_witnessMethod
growth_witness(shift::AbstractArray, norm::AbstractArray, dt, [b]; skip=0)

Compute the growth witness

\[G^{(n)} = S^{(n)} - \frac{\vert\mathbf{c}^{(n+1)}\vert - + \vert\mathbf{c}^{(n)}\vert}{\vert\mathbf{c}^{(n)}\vert d\tau},\]

where S is the shift and $\vert\mathbf{c}^{(n)}\vert ==$ norm[n, 1]. Setting b ≥ 1 a sliding average over b time steps is computed using smoothen(). The first skip time steps are skipped. mean(growth_witness) is approximately the same as growth_estimator with h=0.

See also growth_estimator.

source
Rimu.StatsTools.smoothenMethod
smoothen(noisy::AbstractVector, b)

Smoothen the array noisy by averaging over a sliding window of length b and wrapping noisy periodically. The mean(noisy) is preserved.

source
Rimu.StatsTools.growth_estimatorMethod
growth_estimator(
     shift, wn, h, time_step;
     skip = 0,
     E_r = mean(shift[skip+1:end]),
@@ -91,7 +91,7 @@
 growth_estimator(sim::PMCSimulation; kwargs...)
 -> r::RatioBlockingResult

Compute the growth estimator with reference energy E_r by the reweighting technique described in Umrigar et al. (1993), see Eq. (20). shift and wn are equal length vectors containing the shift and walker number time series, respectively. Reweighting is done over h time steps and length(shift) - skip time steps are used for the blocking analysis done with ratio_of_means. weights is a function that calulates the weights. See w_exp and w_lin.

\[E_{gr} = E_r - \frac{1}{dτ}\ln \frac{\sum_n w_{h+1}^{(n+1)} N_\mathrm{w}^{(n+1)}} - {\sum_m w_{h}^{(m)} N_\mathrm{w}^{(m)}} ,\]

where $dτ$ is the time_step

When h is greater than the autocorrelation time scale of the shift, then E_gr (returned as r.ratio) is an unbiased but approximate estimator for the ground state energy $E_0$ with an error $\mathcal{O}(dτ^2)$ and potentially increased confidence intervals compared to the (biased) shift estimator. Error propagation is done with MonteCarloMeasurements. Propagation through the logarithm can be modified by setting change_type to to_measurement in order to avoid NaN results from negative outliers.

If success==true the blocking analysis was successful in k-1 steps, using blocks uncorrelated data points.

The second method calculates the growth estimator directly from a PMCSimulation or DataFrame returned by solve. The keyword arguments shift_name and norm_name can be used to change the names of the relevant columns.

See also mixed_estimator and RatioBlockingResult.

source
Rimu.StatsTools.growth_estimator_analysisMethod
growth_estimator_analysis(df::DataFrame; kwargs...)
+        {\sum_m w_{h}^{(m)} N_\mathrm{w}^{(m)}} ,\]

where $dτ$ is the time_step

When h is greater than the autocorrelation time scale of the shift, then E_gr (returned as r.ratio) is an unbiased but approximate estimator for the ground state energy $E_0$ with an error $\mathcal{O}(dτ^2)$ and potentially increased confidence intervals compared to the (biased) shift estimator. Error propagation is done with MonteCarloMeasurements. Propagation through the logarithm can be modified by setting change_type to to_measurement in order to avoid NaN results from negative outliers.

If success==true the blocking analysis was successful in k-1 steps, using blocks uncorrelated data points.

The second method calculates the growth estimator directly from a PMCSimulation or DataFrame returned by solve. The keyword arguments shift_name and norm_name can be used to change the names of the relevant columns.

See also mixed_estimator and RatioBlockingResult.

source
Rimu.StatsTools.growth_estimator_analysisMethod
growth_estimator_analysis(df::DataFrame; kwargs...)
 growth_estimator_analysis(sim::PMCSimulation; kwargs...)
 -> (; df_ge, correlation_estimate, se, se_l, se_u)

Compute the growth_estimator on a DataFrame df or PMCSimulation sim. repeatedly over a range of reweighting depths.

Returns a NamedTuple with the fields

  • df_ge: DataFrame with reweighting depth and growth_estiamator data. See example below.
  • correlation_estimate: estimated correlation time from blocking analysis
  • se, se_l, se_u: shift_estimator and error

Keyword arguments

  • h_range: The default is about h_values values from 0 to twice the estimated correlation time
  • h_values = 100: minimum number of reweighting depths
  • skip = 0: initial time steps to exclude from averaging
  • threading = Threads.nthreads() > 1: if false a progress meter is displayed
  • shift_name = :shift name of column in df with shift data
  • norm_name = :norm name of column in df with walkernumber data
  • time_step = determine_constant_time_step(df) the time step
  • warn = true whether to log warning messages when blocking fails or denominators are small

Example

sim = solve(...)
 df_ge, correlation_estimate, se, se_l, se_u = growth_estimator_analysis(sim; skip=5_000)
@@ -99,7 +99,7 @@
 using StatsPlots
 @df df_ge plot(_ -> se, :h, ribbon = (se_l, se_u), label = "⟨S⟩") # constant line and ribbon for shift estimator
 @df df_ge plot!(:h, :val, ribbon = (:val_l, :val_u), label="E_gr") # growth estimator as a function of reweighting depth
-xlabel!("h")

See also: growth_estimator, mixed_estimator_analysis.

source
Rimu.StatsTools.mixed_estimatorMethod
mixed_estimator(
     hproj, vproj, shift, h, time_step;
     skip = 0,
     E_r = mean(shift[skip+1:end]),
@@ -116,7 +116,7 @@
 )
 mixed_estimator(sim::PMCSimulation, h; kwargs...)
 -> r::RatioBlockingResult

Compute the mixed estimator by the reweighting technique described in Umrigar et al. (1993), Eq. (19)

\[E_\mathrm{mix} = \frac{\sum_n w_{h}^{(n)} (Ĥ'\mathbf{v})⋅\mathbf{c}^{(n)}} - {\sum_m w_{h}^{(m)} \mathbf{v}⋅\mathbf{c}^{(m)}} ,\]

where the time series hproj == $(Ĥ'\mathbf{v})⋅\mathbf{c}^{(n)}$ and vproj == $\mathbf{v}⋅\mathbf{c}^{(m)}$ have the same length as shift (See ProjectedEnergy on how to set these up). Reweighting is done over h time steps and length(shift) - skip time steps are used for the blocking analysis done with ratio_of_means. weights is a function that calulates the weights. See w_exp and w_lin. Additional keyword arguments are passed on to ratio_of_means.

When h is greater than the autocorrelation time scale of the shift, then r.ratio is an unbiased but approximate estimator for the ground state energy $E_0$ with an error $\mathcal{O}(dτ^2)$, where $dτ$ is the time_step, and potentially increased confidence intervals compared to the unweighted ratio. Error propagation is done with MonteCarloMeasurements. Results are returned as RatioBlockingResult.

The second method calculates the mixed energy estimator directly from a DataFrame or PMCSimulation returned by solve. The keyword arguments hproj_name, vproj_name, and shift_name can be used to change the names of the relevant columns.

See also growth_estimator.

source
Rimu.StatsTools.mixed_estimator_analysisMethod
mixed_estimator_analysis(df::DataFrame; kwargs...)
+        {\sum_m w_{h}^{(m)}  \mathbf{v}⋅\mathbf{c}^{(m)}} ,\]

where the time series hproj == $(Ĥ'\mathbf{v})⋅\mathbf{c}^{(n)}$ and vproj == $\mathbf{v}⋅\mathbf{c}^{(m)}$ have the same length as shift (See ProjectedEnergy on how to set these up). Reweighting is done over h time steps and length(shift) - skip time steps are used for the blocking analysis done with ratio_of_means. weights is a function that calulates the weights. See w_exp and w_lin. Additional keyword arguments are passed on to ratio_of_means.

When h is greater than the autocorrelation time scale of the shift, then r.ratio is an unbiased but approximate estimator for the ground state energy $E_0$ with an error $\mathcal{O}(dτ^2)$, where $dτ$ is the time_step, and potentially increased confidence intervals compared to the unweighted ratio. Error propagation is done with MonteCarloMeasurements. Results are returned as RatioBlockingResult.

The second method calculates the mixed energy estimator directly from a DataFrame or PMCSimulation returned by solve. The keyword arguments hproj_name, vproj_name, and shift_name can be used to change the names of the relevant columns.

See also growth_estimator.

source
Rimu.StatsTools.mixed_estimator_analysisMethod
mixed_estimator_analysis(df::DataFrame; kwargs...)
 mixed_estimator_analysis(sim::PMCSimulation; kwargs...)
 -> (; df_me, correlation_estimate, se, se_l, se_u)

Compute the mixed_estimator on a DataFrame df or PMCSimulation sim returned from solve repeatedly over a range of reweighting depths.

Returns a NamedTuple with the fields

  • df_me: DataFrame with reweighting depth and mixed_estiamator data. See example below.
  • correlation_estimate: estimated correlation time from blocking analysis
  • se, se_l, se_u: shift_estimator and error

Keyword arguments

  • h_range: The default is about h_values values from 0 to twice the estimated correlation time
  • h_values = 100: minimum number of reweighting depths
  • skip = 0: initial time steps to exclude from averaging
  • threading = Threads.nthreads() > 1: if false a progress meter is displayed
  • shift_name = :shift name of column in df with shift data
  • hproj_name = :hproj name of column in df with operator overlap data
  • vproj_name = :vproj name of column in df with projector overlap data
  • time_step = determine_constant_time_step(df) the time step
  • warn = true whether to log warning messages when blocking fails or denominators are small

Example

sim = solve(...)
 df_me, correlation_estimate, se, se_l, se_u = mixed_estimator_analysis(sim; skip=5_000)
@@ -124,10 +124,10 @@
 using StatsPlots
 @df df_me plot(_ -> se, :h, ribbon = (se_l, se_u), label = "⟨S⟩") # constant line and ribbon for shift estimator
 @df df_me plot!(:h, :val, ribbon = (:val_l, :val_u), label="E_mix") # mixed estimator as a function of reweighting depth
-xlabel!("h")

See also: mixed_estimator, growth_estimator_analysis.

source
Rimu.StatsTools.projected_energyMethod
projected_energy(df::DataFrame; skip=0, hproj=:hproj, vproj=:vproj, kwargs...)
 projected_energy(sim::PMCSimulation; kwargs...)
 -> r::RatioBlockingResult

Compute the projected energy estimator

\[E_\mathrm{p} = \frac{\sum_n \mathbf{v}⋅Ĥ\mathbf{c}^{(n)}} - {\sum_m \mathbf{v}⋅\mathbf{c}^{(m)}} ,\]

where the time series df.hproj == $\mathbf{v}⋅Ĥ\mathbf{c}^{(n)}$ and df.vproj == $\mathbf{v}⋅\mathbf{c}^{(m)}$ are taken from df, skipping the first skip entries (use post_step_strategy =ProjectedEnergy(...) to set these up in ProjectorMonteCarloProblem). projected_energy is equivalent to mixed_estimator with h=0.

The keyword arguments hproj and vproj can be used to change the names of the relevant columns. Other kwargs are passed on to ratio_of_means. Returns a RatioBlockingResult.

See NamedTuple, val_and_errs, val, errs for processing results.

source
Rimu.StatsTools.rayleigh_replica_estimatorMethod
rayleigh_replica_estimator(
+        {\sum_m \mathbf{v}⋅\mathbf{c}^{(m)}} ,\]

where the time series df.hproj == $\mathbf{v}⋅Ĥ\mathbf{c}^{(n)}$ and df.vproj == $\mathbf{v}⋅\mathbf{c}^{(m)}$ are taken from df, skipping the first skip entries (use post_step_strategy =ProjectedEnergy(...) to set these up in ProjectorMonteCarloProblem). projected_energy is equivalent to mixed_estimator with h=0.

The keyword arguments hproj and vproj can be used to change the names of the relevant columns. Other kwargs are passed on to ratio_of_means. Returns a RatioBlockingResult.

See NamedTuple, val_and_errs, val, errs for processing results.

source
Rimu.StatsTools.rayleigh_replica_estimatorMethod
rayleigh_replica_estimator(
     op_ol, vec_ol, shift, h, time_step;
     skip = 0,
     E_r = mean(shift[skip+1:end]),
@@ -147,7 +147,7 @@
 rayleigh_replica_estimator(sim::PMCSimulation; kwargs...)
 -> r::RatioBlockingResult

Compute the estimator of a Rayleigh quotient of operator $\hat{A}$ with reweighting,

\[A_\mathrm{est}(h) = \frac{\sum_{a<b} \sum_n w_{h,a}^{(n)} w_{h,b}^{(n)} \mathbf{c}_a^{(n)} \cdot \hat{A} \cdot \mathbf{c}_b^{(n)}} - {\sum_{a<b} \sum_n w_{h,a}^{(n)} w_{h,b}^{(n)} \mathbf{c}_a^{(n)} \cdot \mathbf{c}_b^{(n)}},\]

using data from multiple replicas.

Argument op_ol holds data for the operator overlap $\mathbf{c}_a^{(n)} \hat{A} \mathbf{c}_b^{(n)}$ and vec_ol holds data for the vector overlap $\mathbf{c}_a^{(n)} \mathbf{c}_b^{(n)}$. They are of type Vector{Vector}, with each element Vector holding the data for a pair of replicas. Argument shift is of type Vector{Vector}, with each element Vector holding the shift data for each individual replica.

The second method computes the Rayleigh quotient directly from a DataFrame or PMCSimulation returned by solve. The keyword arguments shift_name, op_name and vec_name can be used to change the names of the relevant columns, see AllOverlaps for default formatting. The operator overlap data can be scaled by a prefactor Anorm. A specific reweighting depth can be set with keyword argument h. The default is h = 0 which calculates the Rayleigh quotient without reweighting.

The reweighting is an extension of the mixed estimator using the reweighting technique described in Umrigar et al. (1993). Reweighting is done over h time steps and length(shift) - skip time steps are used for the blocking analysis done with ratio_of_means. weights is a function that calulates the weights. See w_exp and w_lin. Additional keyword arguments are passed on to ratio_of_means.

Error propagation is done with MonteCarloMeasurements. Results are returned as RatioBlockingResult.

See also mixed_estimator, growth_estimator.

source
Rimu.StatsTools.rayleigh_replica_estimator_analysisMethod
rayleigh_replica_estimator_analysis(df::DataFrame; kwargs...)
+    {\sum_{a<b} \sum_n w_{h,a}^{(n)} w_{h,b}^{(n)} \mathbf{c}_a^{(n)} \cdot \mathbf{c}_b^{(n)}},\]

using data from multiple replicas.

Argument op_ol holds data for the operator overlap $\mathbf{c}_a^{(n)} \hat{A} \mathbf{c}_b^{(n)}$ and vec_ol holds data for the vector overlap $\mathbf{c}_a^{(n)} \mathbf{c}_b^{(n)}$. They are of type Vector{Vector}, with each element Vector holding the data for a pair of replicas. Argument shift is of type Vector{Vector}, with each element Vector holding the shift data for each individual replica.

The second method computes the Rayleigh quotient directly from a DataFrame or PMCSimulation returned by solve. The keyword arguments shift_name, op_name and vec_name can be used to change the names of the relevant columns, see AllOverlaps for default formatting. The operator overlap data can be scaled by a prefactor Anorm. A specific reweighting depth can be set with keyword argument h. The default is h = 0 which calculates the Rayleigh quotient without reweighting.

The reweighting is an extension of the mixed estimator using the reweighting technique described in Umrigar et al. (1993). Reweighting is done over h time steps and length(shift) - skip time steps are used for the blocking analysis done with ratio_of_means. weights is a function that calulates the weights. See w_exp and w_lin. Additional keyword arguments are passed on to ratio_of_means.

Error propagation is done with MonteCarloMeasurements. Results are returned as RatioBlockingResult.

See also mixed_estimator, growth_estimator.

source
Rimu.StatsTools.rayleigh_replica_estimator_analysisMethod
rayleigh_replica_estimator_analysis(df::DataFrame; kwargs...)
 rayleigh_replica_estimator_analysis(sim::PMCSimulation; kwargs...)
 -> (; df_rre, df_se)

Compute the rayleigh_replica_estimator on a DataFrame df or PMCSimulation sim returned from solve repeatedly over a range of reweighting depths.

Returns a NamedTuple with the fields

  • df_rre: DataFrame with reweighting depth and rayleigh_replica_estimator data. See example below.
  • df_se: DataFrame with shift_estimator output, one row per replica

Keyword arguments

  • h_range: The default is about h_values values from 0 to twice the estimated correlation time
  • h_values = 100: minimum number of reweighting depths
  • skip = 0: initial time steps to exclude from averaging
  • threading = Threads.nthreads() > 1: if false a progress meter is displayed
  • shift_name = "shift": shift data corresponding to column in df with names <shift>_1, ...
  • op_name = "Op1": name of operator overlap corresponding to column in df with names c1_<op_ol>_c2, ...
  • vec_name = "dot": name of vector-vector overlap corresponding to column in df with names c1_<vec_ol>_c2, ...
  • Anorm = 1: a scalar prefactor to scale the operator overlap data
  • warn = true: whether to log warning messages when blocking fails or denominators are small

Example

sim = solve(...)
 df_rre, df_se = rayleigh_replica_estimator_analysis(sim; skip=5_000)
@@ -155,26 +155,26 @@
 using StatsPlots
 @df df_rre plot(_ -> se, :h, ribbon = (se_l, se_u), label = "⟨S⟩") # constant line and ribbon for shift estimator
 @df df_rre plot!(:h, :val, ribbon = (:val_l, :val_u), label="E_mix") # Rayleigh quotient estimator as a function of reweighting depth
-xlabel!("h")

See also: rayleigh_replica_estimator, mixed_estimator_analysis, AllOverlaps.

source
Rimu.StatsTools.w_expMethod
w_exp(shift, h, time_step; E_r = mean(shift), skip = 0)

Compute the weights for reweighting over h time steps with reference energy E_r from the exponential formula

\[w_h^{(n)} = \prod_{j=1}^h \exp[-dτ(S^{(q+n-j)}-E_r)] ,\]

where q = skip and $dτ$ is the time_step.

See also w_lin, growth_estimator, mixed_estimator.

source
Rimu.StatsTools.w_linMethod
w_lin(shift, h, time_step; E_r = mean(shift), skip = 0)

Compute the weights for reweighting over h time steps with reference energy E_r from the linearised formula

\[w_h^{(n)} = \prod_{j=1}^h [1-dτ(S^{(q+n-j)}-E_r)] ,\]

where q = skip and $dτ$ is the time_step.

See also w_exp, growth_estimator, mixed_estimator.

source
Rimu.StatsTools.w_expMethod
w_exp(shift, h, time_step; E_r = mean(shift), skip = 0)

Compute the weights for reweighting over h time steps with reference energy E_r from the exponential formula

\[w_h^{(n)} = \prod_{j=1}^h \exp[-dτ(S^{(q+n-j)}-E_r)] ,\]

where q = skip and $dτ$ is the time_step.

See also w_lin, growth_estimator, mixed_estimator.

source
Rimu.StatsTools.w_linMethod
w_lin(shift, h, time_step; E_r = mean(shift), skip = 0)

Compute the weights for reweighting over h time steps with reference energy E_r from the linearised formula

\[w_h^{(n)} = \prod_{j=1}^h [1-dτ(S^{(q+n-j)}-E_r)] ,\]

where q = skip and $dτ$ is the time_step.

See also w_exp, growth_estimator, mixed_estimator.

source
Rimu.StatsTools.replica_fidelityMethod
replica_fidelity(df::DataFrame; p_field = :hproj, skip = 0)
 replica_fidelity(sim::PMCSimulation; kwargs...)

Compute the fidelity of the average coefficient vector and the projector defined in p_field from the PMCSimulation or DataFrame returned by solve, using replicas _1 and _2. Calls ratio_of_means to perform a blocking analysis on a ratio of the means of separate time series and returns a RatioBlockingResult. The first skip steps in the time series are skipped.

The fidelity of states |ψ⟩ and |ϕ⟩ is defined as

\[F(ψ,ϕ) = \frac{|⟨ψ|ϕ⟩|^2}{⟨ψ|ψ⟩⟨ϕ|ϕ⟩} .\]

Specifically, replica_fidelity computes

\[F(\mathbf{v},⟨\mathbf{c}⟩) = \frac{⟨(\mathbf{c}_1⋅\mathbf{v})(\mathbf{v}⋅\mathbf{c}_1)⟩} - {⟨\mathbf{c}_1⋅\mathbf{c}_1⟩} ,\]

where v is the projector specified by p_field, which is assumed to be normalised to unity with the two-norm (i.e. v⋅v == 1), and $\mathbf{c}_1$ and $\mathbf{c}_2$ are two replica coefficient vectors.

source
Rimu.StatsTools.variational_energy_estimatorMethod
variational_energy_estimator(shifts, overlaps; kwargs...)
+    {⟨\mathbf{c}_1⋅\mathbf{c}_1⟩} ,\]

where v is the projector specified by p_field, which is assumed to be normalised to unity with the two-norm (i.e. v⋅v == 1), and $\mathbf{c}_1$ and $\mathbf{c}_2$ are two replica coefficient vectors.

source
Rimu.StatsTools.variational_energy_estimatorMethod
variational_energy_estimator(shifts, overlaps; kwargs...)
 variational_energy_estimator(df::DataFrame; max_replicas=:all, kwargs...)
 variational_energy_estimator(sim::PMCSimulation; kwargs...)
 -> r::RatioBlockingResult

Compute the variational energy estimator from the replica time series of the shifts and coefficient vector overlaps by blocking analysis. The keyword argument max_replicas can be used to constrain the number of replicas processed to be smaller than all available in df. Other keyword arguments are passed on to ratio_of_means(). Returns a RatioBlockingResult.

An estimator for the variational energy

\[\frac{⟨\mathbf{c}⟩^† \mathbf{H}⟨\mathbf{c}⟩}{⟨\mathbf{c}⟩^†⟨\mathbf{c}⟩}\]

is calculated from

\[Ē_{v} = \frac{\sum_{a<b}^R \overline{(S_a+S_b) \mathbf{c}_a^† \mathbf{c}_b}} - {2\sum_{a<b}^R \overline{\mathbf{c}_a^† \mathbf{c}_b}} ,\]

where the sum goes over distinct pairs out of the $R$ replicas. See arXiv:2103.07800.

The DataFrame and PMCSimulation versions can extract the relevant information from the result of solve. Set up the ProjectorMonteCarloProblem with the keyword argument replica_strategy = AllOverlaps(R) and R ≥ 2. If passing shifts and overlaps, the data has to be arranged in the correct order (as provided in the DataFrame version).

See AllOverlaps.

source

Additional docstrings

Rimu.StatsTools.BlockingResultType
BlockingResult(mean, err, err_err, p_cov, k, blocks)

Result of blocking_analysis.

Fields:

  • mean: sample mean
  • err: standard error (estimated standard deviation of the mean)
  • err_err: estimated uncertainty of err
  • p_cov: estimated pseudo covariance of mean, relevant for complex time series
  • k::Int: k-1 blocking steps were used to uncorrelate time series
  • blocks::Int: number of uncorrelated values after blocking

Has methods for NamedTuple, val_and_errs, val, errs, mean_and_se, Measurements.:±, MonteCarloMeasurements.Particles, and Statistics.cov for Complex data.

Example:

julia> blocking_analysis(smoothen(randn(2^10), 2^5))
+               {2\sum_{a<b}^R \overline{\mathbf{c}_a^† \mathbf{c}_b}} ,\]

where the sum goes over distinct pairs out of the $R$ replicas. See arXiv:2103.07800.

The DataFrame and PMCSimulation versions can extract the relevant information from the result of solve. Set up the ProjectorMonteCarloProblem with the keyword argument replica_strategy = AllOverlaps(R) and R ≥ 2. If passing shifts and overlaps, the data has to be arranged in the correct order (as provided in the DataFrame version).

See AllOverlaps.

source

Additional docstrings

Rimu.StatsTools.BlockingResultType
BlockingResult(mean, err, err_err, p_cov, k, blocks)

Result of blocking_analysis.

Fields:

  • mean: sample mean
  • err: standard error (estimated standard deviation of the mean)
  • err_err: estimated uncertainty of err
  • p_cov: estimated pseudo covariance of mean, relevant for complex time series
  • k::Int: k-1 blocking steps were used to uncorrelate time series
  • blocks::Int: number of uncorrelated values after blocking

Has methods for NamedTuple, val_and_errs, val, errs, mean_and_se, Measurements.:±, MonteCarloMeasurements.Particles, and Statistics.cov for Complex data.

Example:

julia> blocking_analysis(smoothen(randn(2^10), 2^5))
 BlockingResult{Float64}
   mean = -0.026 ± 0.029
   with uncertainty of ± 0.003638545517264226
-  from 32 blocks after 5 transformations (k = 6).
source
Rimu.StatsTools.blockerMethod
blocker(v::Vector) -> new_v::Vector

Reblock the data by successively taking the mean of two adjacent data points to form a new vector with a half of the length(v). The last data point will be discarded if length(v) is odd.

source
Rimu.StatsTools.blocks_with_mMethod
blocks_with_m(v; corrected = true) -> (;blocks, mean, std_err, std_err_err, p_cov, mj)

Perform the blocking algorithm from Flyvberg and Peterson JCP (1989). Returns named tuple with the results from all blocking steps. See mtest().

source
Rimu.StatsTools.mtestMethod
mtest(mj::AbstractVector; α = 0.01) -> k
-mtest(table::NamedTuple; α = 0.01) -> k

Hypothesis test for decorrelation of a time series after blocking transformations with significance level $1-α$ after Jonson PRE (2018). mj or table.mj is expected to be a vector with relevant $M_j$ values from a blocking analysis as obtained from blocks_with_m(). Returns the row number k where the M-test is passed. If the M-test has failed mtest() returns the value -1.

source
Rimu.StatsTools.RatioBlockingResultType
RatioBlockingResult(ratio, f, σ_f, δ_y, k, success)

Result of ratio_of_means().

Fields:

  • ratio::P: ratio with uncertainties propagated by MonteCarloMeasurements
  • f::T: ratio of means
  • σ_f::T: std from linear propagation
  • δ_y::T: coefficient of variation for denominator (≤ 0.1 for normal approx)
  • k::Int: k-1 blocking steps were used to uncorrelate time series
  • blocks::Int: number of data values after blocking
  • success::Bool: false if any of the blocking steps failed

Has methods for NamedTuple, val_and_errs, val, errs.

Note: to compute statistics on the RatioBlockingResult, use functions pmedian, pquantile, pmiddle, piterate, pextrema, pminimum, pmaximum, pmean, and pcov.

source
Rimu.StatsTools.particlesMethod
particles(samples, μ, σ)
-particles(samples, μ::AbstractVector, Σ::AbstractMatrix)

Return Particles object from MonteCarloMeasurements with single- or multivariate normal distribution. Zero variance parameters are supported.

source
Rimu.StatsTools.blockerMethod
blocker(v::Vector) -> new_v::Vector

Reblock the data by successively taking the mean of two adjacent data points to form a new vector with a half of the length(v). The last data point will be discarded if length(v) is odd.

source
Rimu.StatsTools.blocks_with_mMethod
blocks_with_m(v; corrected = true) -> (;blocks, mean, std_err, std_err_err, p_cov, mj)

Perform the blocking algorithm from Flyvberg and Peterson JCP (1989). Returns named tuple with the results from all blocking steps. See mtest().

source
Rimu.StatsTools.mtestMethod
mtest(mj::AbstractVector; α = 0.01) -> k
+mtest(table::NamedTuple; α = 0.01) -> k

Hypothesis test for decorrelation of a time series after blocking transformations with significance level $1-α$ after Jonson PRE (2018). mj or table.mj is expected to be a vector with relevant $M_j$ values from a blocking analysis as obtained from blocks_with_m(). Returns the row number k where the M-test is passed. If the M-test has failed mtest() returns the value -1.

source
Rimu.StatsTools.RatioBlockingResultType
RatioBlockingResult(ratio, f, σ_f, δ_y, k, success)

Result of ratio_of_means().

Fields:

  • ratio::P: ratio with uncertainties propagated by MonteCarloMeasurements
  • f::T: ratio of means
  • σ_f::T: std from linear propagation
  • δ_y::T: coefficient of variation for denominator (≤ 0.1 for normal approx)
  • k::Int: k-1 blocking steps were used to uncorrelate time series
  • blocks::Int: number of data values after blocking
  • success::Bool: false if any of the blocking steps failed

Has methods for NamedTuple, val_and_errs, val, errs.

Note: to compute statistics on the RatioBlockingResult, use functions pmedian, pquantile, pmiddle, piterate, pextrema, pminimum, pmaximum, pmean, and pcov.

source
Rimu.StatsTools.particlesMethod
particles(samples, μ, σ)
+particles(samples, μ::AbstractVector, Σ::AbstractMatrix)

Return Particles object from MonteCarloMeasurements with single- or multivariate normal distribution. Zero variance parameters are supported.

source
Rimu.StatsTools.particlesMethod
particles(samples, d)
 particles(::Nothing, d)
-particles(::Val{T}, d) where T

Return Particles object from MonteCarloMeasurements using a type-stable constructor if possible. Pass nothing for the default number of particles or Val(1_000) for using 1000 particles in a type-stable manner. If d is a Particles object it is passed through without re-sampling.

source
Rimu.StatsTools.ratio_estimatorsMethod
ratio_estimators(x, y, [k]; corrected=true, mc_samples=10_000) -> (; r, f, σ_f, δ_y, n)

Estimators for the ratio of means mean(x)/mean(y). If k is given, k-1 blocking steps are performed to remove internal correlations in the time series x and y. Otherwise these are assumed to be free of internal correlations. Correlations between x and y may be present and are taken into account.

Return values:

  • r::Particles is the Monte Carlo sampled ratio estimator, see Particles
  • f = mean(x)/mean(y)
  • σ_f standard deviation of f from linear error propagation (normal approximation)
  • δ_y = std(y)/mean(y) coefficient of variation; < 0.1 for normal approximation to work
  • n: number of uncorrelated data used for uncertainty estimation
source
Rimu.StatsTools.x_by_y_linearMethod
x_by_y_linear(μ_x,μ_y,σ_x,σ_y,ρ) -> f, σ_f

Linear error propagation for ratio f = x/y assuming x and y are correlated normal random variables and assuming the ratio can be approximated as a normal distribution. See wikipedia and Díaz-Francés, Rubio (2013).

\[σ_f = \sqrt{\frac{σ_x}{μ_y}^2 + \frac{μ_x σ_y}{μ_y^2}^2 - \frac{2 ρ μ_x}{μ_y^3}}\]

source
Core.NamedTupleMethod
NamedTuple(x::BlockingResult; n=1, p=nothing, name=:val)
+particles(::Val{T}, d) where T

Return Particles object from MonteCarloMeasurements using a type-stable constructor if possible. Pass nothing for the default number of particles or Val(1_000) for using 1000 particles in a type-stable manner. If d is a Particles object it is passed through without re-sampling.

source
Rimu.StatsTools.ratio_estimatorsMethod
ratio_estimators(x, y, [k]; corrected=true, mc_samples=10_000) -> (; r, f, σ_f, δ_y, n)

Estimators for the ratio of means mean(x)/mean(y). If k is given, k-1 blocking steps are performed to remove internal correlations in the time series x and y. Otherwise these are assumed to be free of internal correlations. Correlations between x and y may be present and are taken into account.

Return values:

  • r::Particles is the Monte Carlo sampled ratio estimator, see Particles
  • f = mean(x)/mean(y)
  • σ_f standard deviation of f from linear error propagation (normal approximation)
  • δ_y = std(y)/mean(y) coefficient of variation; < 0.1 for normal approximation to work
  • n: number of uncorrelated data used for uncertainty estimation
source
Rimu.StatsTools.x_by_y_linearMethod
x_by_y_linear(μ_x,μ_y,σ_x,σ_y,ρ) -> f, σ_f

Linear error propagation for ratio f = x/y assuming x and y are correlated normal random variables and assuming the ratio can be approximated as a normal distribution. See wikipedia and Díaz-Francés, Rubio (2013).

\[σ_f = \sqrt{\frac{σ_x}{μ_y}^2 + \frac{μ_x σ_y}{μ_y^2}^2 - \frac{2 ρ μ_x}{μ_y^3}}\]

source
Core.NamedTupleMethod
NamedTuple(x::BlockingResult; n=1, p=nothing, name=:val)
 NamedTuple(x::RatioBlockingResult; n=1, p=nothing, name=:val)

Return a named tuple with value and error bars (see val_and_errs) as well as additional numerical fields relevant for x.

Example:

julia> results = [blocking_analysis(i:0.1:2i+20) for i in 1:3]; # mock results
 
 julia> df = NamedTuple.(results, name=:res)|>DataFrame
@@ -192,4 +192,4 @@
      │ Float64   Float64    Float64    Float64   Float64    Float64    Int64  Int64       Bool
 ─────┼────────────────────────────────────────────────────────────────────────────────────────────────
    1 │ 0.581549  0.0925669  0.0812292  0.560532  0.0875548  0.0875548      4          12         true
-

See val_and_errs, val, errs, BlockingResult, RatioBlockingResult.

source
Rimu.StatsTools.autocovarianceMethod
autocovariance(v::Vector,h::Int; corrected::Bool=true)

$\hat{\gamma}(h) =\frac{1}{n}\sum_{t=1}^{n-h}(v_{t+h}-\bar{v})(v_t-\bar{v})^*$ Calculate the autocovariance of dataset v with a delay h. If corrected is true (the default) then the sum is scaled with n-h, whereas the sum is scaled with n if corrected is false where n = length(v).

source
Rimu.StatsTools.pseudo_covMethod
pseudo_cov(x, y; xmean = mean(x), ymean = mean(y), corrected = true)

Compute the pseudo covariance between collections x and y returning a scalar:

\[\frac{1}{n}\sum_{i=1}^{n} (x_i - \bar{x})(y_{i} - \bar{y})\]

Optionally, precomputed means can be passed as keyword arguments. pseudo_cov(x,y) is functionally equivalent to Statistics.cov(x, conj(y); corrected = false) but it is found to be significantly faster and avoids allocations.

source

Index

+

See val_and_errs, val, errs, BlockingResult, RatioBlockingResult.

source
Rimu.StatsTools.autocovarianceMethod
autocovariance(v::Vector,h::Int; corrected::Bool=true)

$\hat{\gamma}(h) =\frac{1}{n}\sum_{t=1}^{n-h}(v_{t+h}-\bar{v})(v_t-\bar{v})^*$ Calculate the autocovariance of dataset v with a delay h. If corrected is true (the default) then the sum is scaled with n-h, whereas the sum is scaled with n if corrected is false where n = length(v).

source
Rimu.StatsTools.pseudo_covMethod
pseudo_cov(x, y; xmean = mean(x), ymean = mean(y), corrected = true)

Compute the pseudo covariance between collections x and y returning a scalar:

\[\frac{1}{n}\sum_{i=1}^{n} (x_i - \bar{x})(y_{i} - \bar{y})\]

Optionally, precomputed means can be passed as keyword arguments. pseudo_cov(x,y) is functionally equivalent to Statistics.cov(x, conj(y); corrected = false) but it is found to be significantly faster and avoids allocations.

source

Index

diff --git a/previews/PR308/stochasticstyles.html b/previews/PR308/stochasticstyles.html index 8285e2c44..2c3f36b18 100644 --- a/previews/PR308/stochasticstyles.html +++ b/previews/PR308/stochasticstyles.html @@ -1,5 +1,5 @@ -Stochastic styles · Rimu.jl

Module StochasticStyles

Rimu.StochasticStylesModule

This module provides concrete implementations of StochasticStyles, which specify the algorithm used by ProjectorMonteCarloProblem when performing stochastic matrix-vector multiplication.

Implemented stochastic styles:

The offdiagonal spawning is defined in spawning.jl and is controlled by setting a SpawningStrategy.

The vector compression strategies are defined in compression.jl and are controlled by setting a CompressionStrategy.

source

Available StochasticStyles

Rimu.Interfaces.StyleUnknownType
StyleUnknown{T}() <: StochasticStyle

Trait for value types not (currently) compatible with FCIQMC. This style makes it possible to construct dict vectors with unsupported valtypes.

See also StochasticStyle.

source
Rimu.StochasticStyles.IsDynamicSemistochasticType
IsDynamicSemistochastic{T=Float64}(; kwargs...) <: StochasticStyle{T}

QMC propagation with floating-point walker numbers and reduced noise. All possible spawns (offdiagonal elements in vector-matrix multiplication) are performed deterministically when number of walkers in a configuration is high, as controlled by the rel_spawning_threshold and abs_spawning_threshold keywords. Stochastic selection of spawns is controlled by the spawning keyword.

By default, a stochastic vector compression is applied after annihilations are completed. This behaviour can be changed to on-the-fly projection (as in IsStochasticInteger or IsStochasticWithThreshold) by setting late_compression=false, or modifying spawning and compression. See parameters below for a more detailed explanation.

Parameters:

  • threshold = 1.0: Values below this number are stochastically projected to this value or zero. See also ThresholdCompression.

  • late_compression = true: If this is set to true, stochastic vector compression is performed after all the spawns are performed. If it is set to false, values are stochastically projected as they are being spawned. late_compression=true is equivalent to setting compression=ThresholdCompression(threshold) and spawning=WithReplacement(). late_compression=false is equivalent to compression=NoCompression() and spawning=WithReplacement(threshold).

  • rel_spawning_threshold = 1.0: If the walker number on a configuration times this threshold is greater than the number of offdiagonals, spawning is done deterministically. Should be set to 1 or more for best performance.

  • abs_spawning_threshold = Inf: If the walker number on a configuration is greater than this value, spawning is done deterministically. Can be set to e.g. abs_spawning_threshold = 0.1 * target_walkers.

  • spawning = WithReplacement(): SpawningStrategy to use for the non-exact spawns.

  • compression = ThresholdCompression(threshold): CompressionStrategy used to compress the vector after a step. Overrides threshold.

See also StochasticStyle.

source

The StochasticStyle interface

Rimu.Interfaces.StochasticStyleType
StochasticStyle(v)

Abstract type. When called as a function it returns the native style of the generalised vector v that determines how simulations are to proceed.

Usage

Concrete StochasticStyles can be used for the style keyword argument of ProjectorMonteCarloProblem, DVec and PDVec. The following styles are available:

Extended Help

Interface

When defining a new StochasticStyle, subtype it as MyStyle<:StochasticStyle{T} where T is the concrete value type the style is designed to work with.

For it to work with ProjectorMonteCarloProblem, a StochasticStyle must define the following:

and optionally

See also StochasticStyles, Interfaces.

source
Rimu.Interfaces.apply_column!Function
apply_column!(v, op, addr, num, boost=1) -> stats::Tuple

Apply the product of column addr of the operator op and the scalar num to the vector v according to the StochasticStyle of v. By expectation value this should be equivalent to

v .+= op[:, add] .* num

This is used to perform the spawning step in FCIQMC and to implement operator-vector multiplications. Mutates v and reports spawning statistics.

The boost argument multiplicatively increases the number of spawns to be performed without affecting the expectation value of the procedure.

source

Compression strategies

Rimu.Interfaces.CompressionStrategyType
CompressionStrategy

The CompressionStrategy controls how a vector is compressed after a step.

Default implementation:

Usage

A subtype of CompressionStrategy can be passed as a keyword argument to the constructors for some StochasticStyles. Calling CompressionStrategy(s::StochasticStyle) returns a relevant subtype. The default is NoCompression.

Interface

When defining a new CompressionStrategy, subtype it as MyCompressionStrategy <: CompressionStrategy and define these methods:

source
Rimu.StochasticStyles.ThresholdCompressionType
ThresholdCompression(threshold=1) <: CompressionStrategy

CompressionStrategy that compresses a vector by threshold projection. Every entry in the vector with a value below the threshold is either set to zero, or increased to the threshold. The probabilty of setting it to zero is equal to abs(value) / threshold.

source
Rimu.Interfaces.compress!Function
compress!([::CompressionStrategy,] v) -> ::NTuple{N,::Symbol}, ::NTuple{N}
-compress!([::CompressionStrategy,] w, v) -> ::NTuple{N,::Symbol}, ::NTuple{N}

Compress the vector v. The one-argument version compresses the vector in-place. The two-argument vector stores the result in w. The CompressionStrategy associated with the StochasticStyle of v is used to determine the type of compression.

Returns two tuples, containing the names and values of statistics that are to be reported.

source

Spawning strategies and convenience functions

The following functions and types are unexported, but are useful when defining new styles.

Rimu.StochasticStyles.diagonal_step!Function
diagonal_step!(w, op, add, val, threshold=0) -> (clones, deaths, zombies)

Perform diagonal step on a walker add => val. Optional argument threshold sets the projection threshold. If eltype(w) is an Integer, the val is rounded to the nearest integer stochastically.

source
Rimu.StochasticStyles.spawn!Function
spawn!(s::SpawningStrategy, w, op::AbstractHamiltonian, add, val, boost)
-spawn!(s::SpawningStrategy, w, offdiags::AbstractOffdiagonals, add, val, boost)

Perform stochastic spawns to w from address add with val walkers. val * boost controls the number of spawns performed.

This function should be overloaded in the second form, with offdiags as an argument.

See SpawningStrategy.

source
Rimu.StochasticStyles.BernoulliType
Bernoulli(threshold=0.0) <: SpawningStrategy

Perform Bernoulli sampling. A spawn is attempted on each offdiagonal element with a probability that results in an expected number of spawns equal to the number of walkers on the spawning configuration. This is significantly less efficient than WithReplacement.

If the number of spawn attempts is greater than the number of offdiagonals, this functions like Exact, but is less efficient. For best performance, this strategy is to be used as a substrategy of DynamicSemistochastic.

Parameters

  • threshold sets the projection threshold.

spawn! with this strategy returns the number of spawn attempts and the number of spawns.

source
Rimu.StochasticStyles.DynamicSemistochasticType
DynamicSemistochastic(; strat, rel_threshold, abs_threshold) <: SpawningStrategy

SpawningStrategy that behaves like strat when the number of walkers is low, but performs exact steps when it is high. What "high" means is controlled by the two thresholds described below.

Parameters

  • strat = WithReplacement(): a SpawningStrategy to use when the multiplication is not performed exactly. If the strat has a threshold different from zero, all spawns will be projected to that threshold.

  • rel_threshold = 1.0: When deciding on whether to perform an exact spawn, this value is multiplied to the number of walkers. Should be set to 1 or more for best performance. This threshold is affected by the boost argument to spawn!.

  • abs_threshold = Inf: When deciding on whether to perform an exact spawn, min(abs_threshold, num_offdiagonals) is used. This threshold is not affected by the boost argument to spawn!.

See e.g. WithoutReplacement for a description of the strat.threshold parameter.

spawn! with this strategy returns the numbers of exact and inexact spawns, the number of spawn attempts and the number of spawns.

source
Rimu.StochasticStyles.ExactType
Exact(threshold=0.0) <: SpawningStrategy

Perform an exact spawning step.

Parameters

  • threshold sets the projection threshold. If set to zero, no projection is performed.

spawn! with this strategy returns the number of spawn attempts and the number of spawns.

source
Rimu.StochasticStyles.SingleSpawnType
SingleSpawn(threshold=0.0) <: SpawningStrategy

Perform a single spawn. Useful as a building block for other stochastic styles.

Parameters

  • threshold sets the projection threshold. If set to zero, no projection is performed.

spawn! with this strategy returns the number of spawn attempts (always 1) and the number of spawns.

source
Rimu.StochasticStyles.SpawningStrategyType
SpawningStrategy

A SpawningStrategy is used to control how spawns (multiplies with off-diagonal part of the column vector) are performed and can be passed to some of the StochasticStyles as keyword arguments.

The following concrete implementations are provided:

Interface

In order to implement a new SpawningStrategy, define a method for spawn!.

source
Rimu.StochasticStyles.WithReplacementType
WithReplacement(threshold=0.0) <: SpawningStrategy

SpawningStrategy where spawn targets are sampled with replacement. This is the default spawning strategy for most of the StochasticStyles.

Parameters

  • threshold sets the projection threshold. If set to zero, no projection is performed.

spawn! with this strategy returns the number of spawn attempts and the number of spawns.

source
Rimu.StochasticStyles.WithoutReplacementType
WithoutReplacement(threshold=0.0) <: SpawningStrategy

SpawningStrategy where spawn targets are sampled without replacement. This strategy needs to allocate a temporary array during spawning, which makes it significantly less efficient than WithReplacement.

If the number of spawn attempts is greater than the number of offdiagonals, this functions like Exact, but is less efficient. For best performance, this strategy is to be used as a substrategy of DynamicSemistochastic.

Parameters

  • threshold sets the projection threshold. If set to zero, no projection is performed.

spawn! with this strategy returns the number of spawn attempts and the number of spawns.

source

Index

+Stochastic styles · Rimu.jl

Module StochasticStyles

Rimu.StochasticStylesModule

This module provides concrete implementations of StochasticStyles, which specify the algorithm used by ProjectorMonteCarloProblem when performing stochastic matrix-vector multiplication.

Implemented stochastic styles:

The offdiagonal spawning is defined in spawning.jl and is controlled by setting a SpawningStrategy.

The vector compression strategies are defined in compression.jl and are controlled by setting a CompressionStrategy.

source

Available StochasticStyles

Rimu.Interfaces.StyleUnknownType
StyleUnknown{T}() <: StochasticStyle

Trait for value types not (currently) compatible with FCIQMC. This style makes it possible to construct dict vectors with unsupported valtypes.

See also StochasticStyle.

source
Rimu.StochasticStyles.IsDynamicSemistochasticType
IsDynamicSemistochastic{T=Float64}(; kwargs...) <: StochasticStyle{T}

QMC propagation with floating-point walker numbers and reduced noise. All possible spawns (offdiagonal elements in vector-matrix multiplication) are performed deterministically when number of walkers in a configuration is high, as controlled by the rel_spawning_threshold and abs_spawning_threshold keywords. Stochastic selection of spawns is controlled by the spawning keyword.

By default, a stochastic vector compression is applied after annihilations are completed. This behaviour can be changed to on-the-fly projection (as in IsStochasticInteger or IsStochasticWithThreshold) by setting late_compression=false, or modifying spawning and compression. See parameters below for a more detailed explanation.

Parameters:

  • threshold = 1.0: Values below this number are stochastically projected to this value or zero. See also ThresholdCompression.

  • late_compression = true: If this is set to true, stochastic vector compression is performed after all the spawns are performed. If it is set to false, values are stochastically projected as they are being spawned. late_compression=true is equivalent to setting compression=ThresholdCompression(threshold) and spawning=WithReplacement(). late_compression=false is equivalent to compression=NoCompression() and spawning=WithReplacement(threshold).

  • rel_spawning_threshold = 1.0: If the walker number on a configuration times this threshold is greater than the number of offdiagonals, spawning is done deterministically. Should be set to 1 or more for best performance.

  • abs_spawning_threshold = Inf: If the walker number on a configuration is greater than this value, spawning is done deterministically. Can be set to e.g. abs_spawning_threshold = 0.1 * target_walkers.

  • spawning = WithReplacement(): SpawningStrategy to use for the non-exact spawns.

  • compression = ThresholdCompression(threshold): CompressionStrategy used to compress the vector after a step. Overrides threshold.

See also StochasticStyle.

source

The StochasticStyle interface

Rimu.Interfaces.StochasticStyleType
StochasticStyle(v)

Abstract type. When called as a function it returns the native style of the generalised vector v that determines how simulations are to proceed.

Usage

Concrete StochasticStyles can be used for the style keyword argument of ProjectorMonteCarloProblem, DVec and PDVec. The following styles are available:

Extended Help

Interface

When defining a new StochasticStyle, subtype it as MyStyle<:StochasticStyle{T} where T is the concrete value type the style is designed to work with.

For it to work with ProjectorMonteCarloProblem, a StochasticStyle must define the following:

and optionally

See also StochasticStyles, Interfaces.

source
Rimu.Interfaces.apply_column!Function
apply_column!(v, op, addr, num, boost=1) -> stats::Tuple

Apply the product of column addr of the operator op and the scalar num to the vector v according to the StochasticStyle of v. By expectation value this should be equivalent to

v .+= op[:, add] .* num

This is used to perform the spawning step in FCIQMC and to implement operator-vector multiplications. Mutates v and reports spawning statistics.

The boost argument multiplicatively increases the number of spawns to be performed without affecting the expectation value of the procedure.

source

Compression strategies

Rimu.Interfaces.CompressionStrategyType
CompressionStrategy

The CompressionStrategy controls how a vector is compressed after a step.

Default implementation:

Usage

A subtype of CompressionStrategy can be passed as a keyword argument to the constructors for some StochasticStyles. Calling CompressionStrategy(s::StochasticStyle) returns a relevant subtype. The default is NoCompression.

Interface

When defining a new CompressionStrategy, subtype it as MyCompressionStrategy <: CompressionStrategy and define these methods:

source
Rimu.StochasticStyles.ThresholdCompressionType
ThresholdCompression(threshold=1) <: CompressionStrategy

CompressionStrategy that compresses a vector by threshold projection. Every entry in the vector with a value below the threshold is either set to zero, or increased to the threshold. The probabilty of setting it to zero is equal to abs(value) / threshold.

source
Rimu.Interfaces.compress!Function
compress!([::CompressionStrategy,] v) -> ::NTuple{N,::Symbol}, ::NTuple{N}
+compress!([::CompressionStrategy,] w, v) -> ::NTuple{N,::Symbol}, ::NTuple{N}

Compress the vector v. The one-argument version compresses the vector in-place. The two-argument vector stores the result in w. The CompressionStrategy associated with the StochasticStyle of v is used to determine the type of compression.

Returns two tuples, containing the names and values of statistics that are to be reported.

source

Spawning strategies and convenience functions

The following functions and types are unexported, but are useful when defining new styles.

Rimu.StochasticStyles.diagonal_step!Function
diagonal_step!(w, op, add, val, threshold=0) -> (clones, deaths, zombies)

Perform diagonal step on a walker add => val. Optional argument threshold sets the projection threshold. If eltype(w) is an Integer, the val is rounded to the nearest integer stochastically.

source
Rimu.StochasticStyles.spawn!Function
spawn!(s::SpawningStrategy, w, op::AbstractHamiltonian, add, val, boost)
+spawn!(s::SpawningStrategy, w, offdiags::AbstractOffdiagonals, add, val, boost)

Perform stochastic spawns to w from address add with val walkers. val * boost controls the number of spawns performed.

This function should be overloaded in the second form, with offdiags as an argument.

See SpawningStrategy.

source
Rimu.StochasticStyles.BernoulliType
Bernoulli(threshold=0.0) <: SpawningStrategy

Perform Bernoulli sampling. A spawn is attempted on each offdiagonal element with a probability that results in an expected number of spawns equal to the number of walkers on the spawning configuration. This is significantly less efficient than WithReplacement.

If the number of spawn attempts is greater than the number of offdiagonals, this functions like Exact, but is less efficient. For best performance, this strategy is to be used as a substrategy of DynamicSemistochastic.

Parameters

  • threshold sets the projection threshold.

spawn! with this strategy returns the number of spawn attempts and the number of spawns.

source
Rimu.StochasticStyles.DynamicSemistochasticType
DynamicSemistochastic(; strat, rel_threshold, abs_threshold) <: SpawningStrategy

SpawningStrategy that behaves like strat when the number of walkers is low, but performs exact steps when it is high. What "high" means is controlled by the two thresholds described below.

Parameters

  • strat = WithReplacement(): a SpawningStrategy to use when the multiplication is not performed exactly. If the strat has a threshold different from zero, all spawns will be projected to that threshold.

  • rel_threshold = 1.0: When deciding on whether to perform an exact spawn, this value is multiplied to the number of walkers. Should be set to 1 or more for best performance. This threshold is affected by the boost argument to spawn!.

  • abs_threshold = Inf: When deciding on whether to perform an exact spawn, min(abs_threshold, num_offdiagonals) is used. This threshold is not affected by the boost argument to spawn!.

See e.g. WithoutReplacement for a description of the strat.threshold parameter.

spawn! with this strategy returns the numbers of exact and inexact spawns, the number of spawn attempts and the number of spawns.

source
Rimu.StochasticStyles.ExactType
Exact(threshold=0.0) <: SpawningStrategy

Perform an exact spawning step.

Parameters

  • threshold sets the projection threshold. If set to zero, no projection is performed.

spawn! with this strategy returns the number of spawn attempts and the number of spawns.

source
Rimu.StochasticStyles.SingleSpawnType
SingleSpawn(threshold=0.0) <: SpawningStrategy

Perform a single spawn. Useful as a building block for other stochastic styles.

Parameters

  • threshold sets the projection threshold. If set to zero, no projection is performed.

spawn! with this strategy returns the number of spawn attempts (always 1) and the number of spawns.

source
Rimu.StochasticStyles.SpawningStrategyType
SpawningStrategy

A SpawningStrategy is used to control how spawns (multiplies with off-diagonal part of the column vector) are performed and can be passed to some of the StochasticStyles as keyword arguments.

The following concrete implementations are provided:

Interface

In order to implement a new SpawningStrategy, define a method for spawn!.

source
Rimu.StochasticStyles.WithReplacementType
WithReplacement(threshold=0.0) <: SpawningStrategy

SpawningStrategy where spawn targets are sampled with replacement. This is the default spawning strategy for most of the StochasticStyles.

Parameters

  • threshold sets the projection threshold. If set to zero, no projection is performed.

spawn! with this strategy returns the number of spawn attempts and the number of spawns.

source
Rimu.StochasticStyles.WithoutReplacementType
WithoutReplacement(threshold=0.0) <: SpawningStrategy

SpawningStrategy where spawn targets are sampled without replacement. This strategy needs to allocate a temporary array during spawning, which makes it significantly less efficient than WithReplacement.

If the number of spawn attempts is greater than the number of offdiagonals, this functions like Exact, but is less efficient. For best performance, this strategy is to be used as a substrategy of DynamicSemistochastic.

Parameters

  • threshold sets the projection threshold. If set to zero, no projection is performed.

spawn! with this strategy returns the number of spawn attempts and the number of spawns.

source

Index

diff --git a/previews/PR308/testing.html b/previews/PR308/testing.html index c70504c14..a8aff97f4 100644 --- a/previews/PR308/testing.html +++ b/previews/PR308/testing.html @@ -1,2 +1,2 @@ -Code testing · Rimu.jl

Code testing

The script runtest.jl in the test/ folder contains tests of the code in Rimu. To run the test simply run the script from the Julia REPL or run

Rimu$ julia test/runtest.jl

from the command line.

More tests should be added over time to test core functionality of the code. To add new tests, directly edit the file runtest.jl.

Automated testing with GitHub Actions

GitHub Actions are set up to run the test script automatically on the GitHub cloud server every time a new commit to the master branch is pushed to the server. The setup for this to happen is configured in the file actions.yml in the Rimu/.github/workflows folder.

Testing of custom types for use with Rimu

The module Rimu.InterfaceTests contains a number of functions to test the interfaces of the AbstractHamiltonian type hierarchy. See Interface tests in the section Advanced operator usage and custom Hamiltonians.

+Code testing · Rimu.jl

Code testing

The script runtest.jl in the test/ folder contains tests of the code in Rimu. To run the test simply run the script from the Julia REPL or run

Rimu$ julia test/runtest.jl

from the command line.

More tests should be added over time to test core functionality of the code. To add new tests, directly edit the file runtest.jl.

Automated testing with GitHub Actions

GitHub Actions are set up to run the test script automatically on the GitHub cloud server every time a new commit to the master branch is pushed to the server. The setup for this to happen is configured in the file actions.yml in the Rimu/.github/workflows folder.

Testing of custom types for use with Rimu

The module Rimu.InterfaceTests contains a number of functions to test the interfaces of the AbstractHamiltonian type hierarchy. See Interface tests in the section Advanced operator usage and custom Hamiltonians.