Search code examples
glsl

GLSL double precision complex number power function


I currently have the following GLSL functions defined for raising a complex number to a power.

dvec2 p2 (dvec2 t) {return (dvec2 (cmul(t,t) ));}
dvec2 p3 (dvec2 t) {return (dvec2 (cmul(cmul(t,t),t) ));}
dvec2 p4 (dvec2 t) {return (dvec2 (cmul(cmul(cmul(t,t),t),t) ));}
dvec2 p5 (dvec2 t) {return (dvec2 (cmul(cmul(cmul(cmul(t,t),t),t),t) ));}
dvec2 p6 (dvec2 t) {return (dvec2 (cmul(cmul(cmul(cmul(cmul(t,t),t),t),t),t) ));}
dvec2 p7 (dvec2 t) {return (dvec2 (cmul(cmul(cmul(cmul(cmul(cmul(t,t),t),t),t),t),t) ));}
dvec2 p8 (dvec2 t) {return (dvec2 (cmul(cmul(cmul(cmul(cmul(cmul(cmul(t,t),t),t),t),t),t),t) ));}

I can use these in complex number formula like

dvec2 func (dvec2 z) { return (dvec2( cadd(csub(p4(z),cmul(c5,p2(z))),c4) ));

and it works fine.

Now I want to get rid of those p2,p3,p4,etc functions and write a more generalized power function. So I tried the following

dvec2 cpow (dvec2 c, int p) {
    for (int i = 0; i < p; i++) {
    c=cmul(c,c);
    }
    return c;
}

which I then call like

dvec2 func   (dvec2 z) { return (dvec2( cadd(csub(cpow(z,4),cmul(c5,cpow(z,2))),c4) )); }

But it gives different results. I can find a lot of complex power routines online but they all use log and trig calls which are not double precision which I need for this GLSL code.

Can any GLSL gurus spot why that simple cpow loop would not work?


Solution

  • your conversion formula is wrong ... because you multiply by the subresult meaning you got squaring instead of multiplying ... You have to change your function to:

    dvec2 cpow (dvec2 c, int p) 
        {
        dvec2 a=(1.0,0.0); // assuming a.x is real part
        for (int i = 1; i <= p; i++) a=cmul(a,c);
        return a;
        }
    

    if you want something faster you can use power by squaring or even port to polar representation do power there and convert back to cartesian form of complex number. For more info see:

    Look for the vec2 cpow(vec2 a,vec2 b) // a^b in the GLSL code for tetration fractal.