GLSL双精度复数幂函数
GLSL double precision complex number power function
我目前定义了以下 GLSL 函数,用于计算复数的幂。
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) ));}
我可以在像
这样的复数公式中使用这些
dvec2 func (dvec2 z) { return (dvec2( cadd(csub(p4(z),cmul(c5,p2(z))),c4) ));
而且效果很好。
现在我想摆脱那些 p2、p3、p4 等函数并编写一个更通用的幂函数。所以我尝试了以下
dvec2 cpow (dvec2 c, int p) {
for (int i = 0; i < p; i++) {
c=cmul(c,c);
}
return c;
}
然后我称之为
dvec2 func (dvec2 z) { return (dvec2( cadd(csub(cpow(z,4),cmul(c5,cpow(z,2))),c4) )); }
但它给出了不同的结果。我可以在网上找到很多复杂的电源例程,但它们都使用 log 和 trig 调用,这些调用不是双精度的,我需要这个 GLSL 代码。
任何 GLSL 大师都可以找出为什么那个简单的 cpow 循环不起作用吗?
您的转换公式是错误的...因为您乘以子结果意味着您得到的是平方而不是乘法...您必须将函数更改为:
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;
}
如果你想要更快的东西,你可以使用 甚至端口到极坐标表示在那里做电源并转换回笛卡尔形式的复数。有关详细信息,请参阅:
在四分形的 GLSL 代码中寻找 vec2 cpow(vec2 a,vec2 b) // a^b
。
我目前定义了以下 GLSL 函数,用于计算复数的幂。
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) ));}
我可以在像
这样的复数公式中使用这些dvec2 func (dvec2 z) { return (dvec2( cadd(csub(p4(z),cmul(c5,p2(z))),c4) ));
而且效果很好。
现在我想摆脱那些 p2、p3、p4 等函数并编写一个更通用的幂函数。所以我尝试了以下
dvec2 cpow (dvec2 c, int p) {
for (int i = 0; i < p; i++) {
c=cmul(c,c);
}
return c;
}
然后我称之为
dvec2 func (dvec2 z) { return (dvec2( cadd(csub(cpow(z,4),cmul(c5,cpow(z,2))),c4) )); }
但它给出了不同的结果。我可以在网上找到很多复杂的电源例程,但它们都使用 log 和 trig 调用,这些调用不是双精度的,我需要这个 GLSL 代码。
任何 GLSL 大师都可以找出为什么那个简单的 cpow 循环不起作用吗?
您的转换公式是错误的...因为您乘以子结果意味着您得到的是平方而不是乘法...您必须将函数更改为:
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;
}
如果你想要更快的东西,你可以使用
在四分形的 GLSL 代码中寻找 vec2 cpow(vec2 a,vec2 b) // a^b
。