mod engine;
mod evolution;
mod measurement;
mod readout;
mod state;
pub use engine::MpsSimulator;
pub mod distributed;
mod tensor;
use crate::{Error, Result};
use serde::{Deserialize, Serialize};
pub use state::{MpsCheckpoint, MpsState, SiteData, TruncationReport};
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct MpsLimits {
pub max_sites: usize,
pub max_bond: usize,
pub max_tensor_elements: usize,
pub max_state_elements: usize,
pub max_truncation_distance: f64,
pub svd_iterations: usize,
}
impl Default for MpsLimits {
fn default() -> Self {
Self {
max_sites: 100_000,
max_bond: 128,
max_tensor_elements: 1 << 20,
max_state_elements: 1 << 24,
max_truncation_distance: 0.,
svd_iterations: 10_000,
}
}
}
impl MpsLimits {
pub(crate) fn validate(&self) -> Result<()> {
if self.max_sites == 0
|| self.max_bond == 0
|| self.max_tensor_elements == 0
|| self.max_state_elements == 0
|| self.svd_iterations == 0
|| !self.max_truncation_distance.is_finite()
|| !(0.0..=1.).contains(&self.max_truncation_distance)
{
return Err(Error::InvalidValue("invalid MPS limits".into()));
}
Ok(())
}
pub(crate) fn tensor(&self, n: usize) -> Result<()> {
limit("MPS local tensor", n, self.max_tensor_elements)
}
}
pub(crate) fn limit(resource: &'static str, required: usize, limit: usize) -> Result<()> {
if required > limit {
Err(Error::ResourceLimit {
resource,
required,
limit,
})
} else {
Ok(())
}
}