Skip to main content

apply_linear_operator

Function apply_linear_operator 

Source
pub fn apply_linear_operator<T, V>(
    operator: &LinearOperator<T, V>,
    state: &TreeTN<T, V>,
    options: ApplyOptions,
) -> Result<TreeTN<T, V>>
where T: TensorLike, T::Index: IndexLike + Clone + Hash + Eq + Debug, <T::Index as IndexLike>::Id: Clone + Hash + Eq + Ord + Debug + Send + Sync, V: Clone + Hash + Eq + Ord + Send + Sync + Debug,
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 apply
  • state - 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);