use super::PolyVec;
use crate::families::jet_partitions::MultiDirJet;
use smallvec::{SmallVec, smallvec};
#[inline]
pub(super) fn poly_mul(lhs: &[f64], rhs: &[f64]) -> PolyVec {
if lhs.is_empty() || rhs.is_empty() {
return PolyVec::new();
}
let n = lhs.len() + rhs.len() - 1;
let mut out: PolyVec = smallvec![0.0; n];
let out_slice = out.as_mut_slice();
for (i, &lv) in lhs.iter().enumerate() {
let dst = &mut out_slice[i..i + rhs.len()];
for (d, &rv) in dst.iter_mut().zip(rhs.iter()) {
*d += lv * rv;
}
}
out
}
#[inline]
pub(super) fn poly_sub(lhs: &[f64], rhs: &[f64]) -> PolyVec {
let mut out: PolyVec = SmallVec::new();
out.extend_from_slice(lhs);
if rhs.len() > lhs.len() {
out.resize(rhs.len(), 0.0);
}
for (d, &v) in out[..rhs.len()].iter_mut().zip(rhs.iter()) {
*d -= v;
}
out
}
#[inline]
pub(super) fn poly_add(lhs: &[f64], rhs: &[f64]) -> PolyVec {
let (a, b) = if lhs.len() >= rhs.len() {
(lhs, rhs)
} else {
(rhs, lhs)
};
let mut out: PolyVec = SmallVec::new();
out.extend_from_slice(a);
for (d, &v) in out[..b.len()].iter_mut().zip(b.iter()) {
*d += v;
}
out
}
#[inline]
pub(super) fn poly_scale(poly: &[f64], scale: f64) -> PolyVec {
let mut out: PolyVec = SmallVec::with_capacity(poly.len());
for &v in poly {
out.push(scale * v);
}
out
}
pub(super) fn poly_add_jets(lhs: &[MultiDirJet], rhs: &[MultiDirJet]) -> Vec<MultiDirJet> {
let count = lhs.len().max(rhs.len());
let mut out = Vec::with_capacity(count);
for idx in 0..count {
let left = lhs
.get(idx)
.cloned()
.unwrap_or_else(|| MultiDirJet::zero(2));
let right = rhs
.get(idx)
.cloned()
.unwrap_or_else(|| MultiDirJet::zero(2));
out.push(left.add(&right));
}
out
}
pub(super) fn poly_scale_jets(poly: &[MultiDirJet], scale: &MultiDirJet) -> Vec<MultiDirJet> {
poly.iter().map(|coeff| coeff.mul(scale)).collect()
}
pub(super) fn poly_mul_jets(lhs: &[MultiDirJet], rhs: &[MultiDirJet]) -> Vec<MultiDirJet> {
if lhs.is_empty() || rhs.is_empty() {
return Vec::new();
}
let mut out = vec![MultiDirJet::zero(2); lhs.len() + rhs.len() - 1];
for (i, left) in lhs.iter().enumerate() {
for (j, right) in rhs.iter().enumerate() {
let prod = left.mul(right);
out[i + j] = out[i + j].add(&prod);
}
}
out
}
pub(super) fn poly_coeff_mask(poly: &[MultiDirJet], mask: usize) -> Vec<f64> {
poly.iter().map(|coeff| coeff.coeff(mask)).collect()
}