num-complex icon indicating copy to clipboard operation
num-complex copied to clipboard

mul_add between real and complex numbers

Open isomer opened this issue 1 year ago • 1 comments

I'm attempting to use:

 println!("{:?}", (2.0_f32).mul_add(
      Complex::new(3.0_f32, 4.0_f32), 
      Complex::new(5.0_f32, 6.0_f32)));

which doesn't exist.

I think the equivalent would be:

fn fma<T: num::Float>(a: T, b: Complex<T>, c: Complex<T>) -> Complex<T> {
    let re = a.mul_add(b.re, c.re);
    let im = a.mul_add(b.im, c.im);
    Complex::new(re, im)
}

which does compile using two fused multiply adds which hopefully the compiler could reorder, vectorise or whatever optimisations it believes fruitful.

The code I'm writing (a convolution kernel) is attempting to be generic over real and complex numbers which relies on the num::Complex crate to provide this implementation.

My preferred solution would be for num::Complex to implement T::mul_add(Complex<T>, Complex<T>) -> Complex<T> where T: MulAdd<T, T, Output=T>

isomer avatar Oct 31 '24 10:10 isomer

There is also a discussion about adding div_add at #146. It should probably also be taken into consideration for consistency purposes.

Similarly CheckedAdd/Sub/... are being added at #152 .

When deciding which arguments should be supported for Complex<T> and T we should also discuss owned vs reference arguments.

PaulXiCao avatar Oct 27 '25 22:10 PaulXiCao