MCPcopy Index your code
hub / github.com/RustPython/RustPython / sumprod

Function sumprod

crates/stdlib/src/math.rs:609–754  ·  view source on GitHub ↗
(
        p: ArgIterable<PyObjectRef>,
        q: ArgIterable<PyObjectRef>,
        vm: &VirtualMachine,
    )

Source from the content-addressed store, hash-verified

607
608 #[pyfunction]
609 fn sumprod(
610 p: ArgIterable<PyObjectRef>,
611 q: ArgIterable<PyObjectRef>,
612 vm: &VirtualMachine,
613 ) -> PyResult<PyObjectRef> {
614 use crate::vm::builtins::PyInt;
615
616 let mut p_iter = p.iter(vm)?;
617 let mut q_iter = q.iter(vm)?;
618
619 // Fast path state
620 let mut int_path_enabled = true;
621 let mut int_total: i64 = 0;
622 let mut int_total_in_use = false;
623 let mut flt_p_values: Vec<f64> = Vec::new();
624 let mut flt_q_values: Vec<f64> = Vec::new();
625
626 // Fallback accumulator for generic Python path
627 let mut obj_total: Option<PyObjectRef> = None;
628
629 loop {
630 let m_p = p_iter.next();
631 let m_q = q_iter.next();
632
633 let (p_i, q_i, finished) = match (m_p, m_q) {
634 (Some(r_p), Some(r_q)) => (Some(r_p?), Some(r_q?), false),
635 (None, None) => (None, None, true),
636 _ => return Err(vm.new_value_error("Inputs are not the same length")),
637 };
638
639 // Integer fast path (only for exact int types, not subclasses)
640 if int_path_enabled {
641 if !finished {
642 let (p_i, q_i) = (p_i.as_ref().unwrap(), q_i.as_ref().unwrap());
643 if p_i.class().is(vm.ctx.types.int_type)
644 && q_i.class().is(vm.ctx.types.int_type)
645 && let (Some(p_int), Some(q_int)) =
646 (p_i.downcast_ref::<PyInt>(), q_i.downcast_ref::<PyInt>())
647 && let (Ok(p_val), Ok(q_val)) = (
648 p_int.as_bigint().try_into() as Result<i64, _>,
649 q_int.as_bigint().try_into() as Result<i64, _>,
650 )
651 && let Some(prod) = p_val.checked_mul(q_val)
652 && let Some(new_total) = int_total.checked_add(prod)
653 {
654 int_total = new_total;
655 int_total_in_use = true;
656 continue;
657 }
658 }
659 // Finalize int path
660 int_path_enabled = false;
661 if int_total_in_use {
662 let int_obj: PyObjectRef = vm.ctx.new_int(int_total).into();
663 obj_total = Some(match obj_total {
664 Some(total) => vm._add(&total, &int_obj)?,
665 None => int_obj,
666 });

Callers 10

fmeanFunction · 0.90
covarianceFunction · 0.90
correlationFunction · 0.90
linear_regressionFunction · 0.90
parabolic_kernelFunction · 0.90
quartic_kernelFunction · 0.90
triweight_kernelFunction · 0.90
_sqrtprodFunction · 0.90
testSumProdMethod · 0.85
test_sumprod_accuracyMethod · 0.85

Calls 15

newFunction · 0.85
pymath_exceptionFunction · 0.85
onceFunction · 0.85
isMethod · 0.80
as_bigintMethod · 0.80
to_f64Method · 0.80
okMethod · 0.80
collectMethod · 0.80
chainMethod · 0.80
SomeClass · 0.50
ErrClass · 0.50
iterMethod · 0.45

Tested by 2

testSumProdMethod · 0.68
test_sumprod_accuracyMethod · 0.68