use crate::float::*;

pub trait LinearMap<T, H> {
    fn apply(&self, result: &mut [T], input: &[T], helper: &mut H);
}

pub(crate) fn lanczos_step<T: Float>(vprev_vnext: &mut [T], v_k: &[T], span_extension: &[T], beta_prev: T) -> (T, T) {
    let alpha = v_k.dot(span_extension);

    let mut norm_squared = T::zero();

    vprev_vnext.iter_mut().zip(span_extension.iter().zip(v_k.iter())).for_each(|(n, (w, v))| {
        *n *= -beta_prev;
        *n += *w - alpha * *v;
        norm_squared += *n * *n;
    });

    let beta = norm_squared.sqrt();

    vprev_vnext.iter_mut().for_each(|n| *n /= beta);

    (alpha, beta)
}

#[cfg(test)]
mod tests {
    // TODO: Test the lanczos step function
}
