pub fn apply_linear_operator<T, V>(
operator: &LinearOperator<T, V>,
state: &TreeTN<T, V>,
options: ApplyOptions,
) -> Result<TreeTN<T, V>>Expand description
Apply a LinearOperator to a TreeTN state: compute A|x⟩.
This function handles:
- Partial operators (fills gaps with identity via compose_exclusive_linear_operators)
- Index transformations (input/output mappings)
- Multiple contraction algorithms (ZipUp, Fit, Naive)
§Arguments
operator- The LinearOperator to applystate- The input state |x⟩options- Options controlling the contraction algorithm
§Returns
The result A|x⟩ as a TreeTN, or an error if application fails.
§Example
use std::collections::HashMap;
use tensor4all_core::{DynIndex, TensorDynLen, TensorLike};
use tensor4all_treetn::{apply_linear_operator, ApplyOptions, IndexMapping, LinearOperator, TreeTN};
let site = DynIndex::new_dyn(2);
let state_tensor = TensorDynLen::from_dense(vec![site.clone()], vec![1.0, 2.0])?;
let state = TreeTN::<TensorDynLen, usize>::from_tensors(vec![state_tensor], vec![0])?;
let input_internal = DynIndex::new_dyn(2);
let output_internal = DynIndex::new_dyn(2);
let mpo_tensor = TensorDynLen::from_dense(
vec![input_internal.clone(), output_internal.clone()],
vec![1.0, 0.0, 0.0, 1.0],
)?;
let mpo = TreeTN::<TensorDynLen, usize>::from_tensors(vec![mpo_tensor], vec![0])?;
let mut input_mapping = HashMap::new();
input_mapping.insert(
0usize,
IndexMapping {
true_index: site.clone(),
internal_index: input_internal,
},
);
let mut output_mapping = HashMap::new();
output_mapping.insert(
0usize,
IndexMapping {
true_index: site.clone(),
internal_index: output_internal,
},
);
let operator = LinearOperator::new(mpo, input_mapping, output_mapping);
let result = apply_linear_operator(&operator, &state, ApplyOptions::default())?;
assert_eq!(result.node_count(), 1);
// Applying identity preserves the state
let result_dense = result.to_dense()?;
let state_dense = state.to_dense()?;
assert!((&result_dense - &state_dense).maxabs() < 1e-12);
let truncated = apply_linear_operator(
&operator,
&state,
ApplyOptions::zipup()
.with_max_rank(4)
.with_svd_policy(tensor4all_core::SvdTruncationPolicy::new(1e-10)),
)?;
assert_eq!(truncated.node_count(), 1);