# Problem with a cubic solving function

Hello, I’m new to CUDA so please be patient… :)

I’m trying to programe a device function that solves a cubic function, but I’m getting “Invalid operation” error.

The device code is the following:

[codebox]/*c[0] + c[1]*x + c[2]*x^2 + c[3]x^3 = 0/

device

int SolveCubic2(float c[ 4 ], float s[ 3 ])

{

``````int i, num;

float sub, a, b, cc, sq_a, sqrt_d, p, q, cb_p, d, u, v, phi, t,

onethird;
``````

/* normal form: x^3 + ax^2 + bx + c = 0 */

a = c[2] / c[3];

``````b = c[1] / c[3];

cc = c[0] / c[3];
``````

/* substitute x = y-A/3 to eliminate quadric term: x^3 + px + q = 0 */

sq_a = a * a;

``````p = 1.0 / 3.0 * (-1.0 / 3.0 * sq_a + B );

q = 0.5 * (2.0/27.0 * a * sq_a - 1.0 / 3.0 * a * b + cc );
``````

/* use Cardano’s formula */

cb_p = p * p * p;

``````d = q * q + cb_p;

onethird = 1.0/3.0;

if ( isZero(d) ) {

if ( isZero(q) ) {                    /* one triple solution */

s[0] = 0.0;

num = 1;

}

else {                 /* one single and one double solution */

u = pow(-q,onethird);

s[0] = 2 * u;

s[1] = -u;

num = 2;

}

}

else if ( d < 0 ) {  /* Casus irreducibilis: three real solutions */

phi = 1.0 / 3.0 * acos(-q / sqrt(-cb_p));

t = 2 * sqrt(-p);

s[0] = t * cos(phi);

s[1] = -t * cos(phi + M_PI / 3.0);

s[2] = -t * cos(phi - M_PI / 3.0);

num = 3;

}

else {                                       /* one real solution */

sqrt_d = sqrt(d);

u = pow(sqrt_d - q,onethird);

v = - pow(sqrt_d + q,onethird);

s[0] = u + v;

num = 1;

}
``````

/* resubstitute */

``````sub = 1.0/3.0 * a;

for ( i=0; i<num; i++) s[i] -= sub;
``````

return num;

}[/codebox]

I’m using windows vista with sdk 2.0 on a 8800 GTX. I can’t use sqrt and power functions? What’s wrong with this code?

Thanks for the help!

I spend the all day backtracking this problem and I figure out that if I comment the line that is in bold below everything just work fine :

#define EQN_EPS 1e-9
#define IsZero(x) ((x) > -EQN_EPS && (x) < EQN_EPS)

(…)

if ( isZero(d) ) {
if ( isZero(q) ) { /* one triple solution */
s[0] = 0.0;

the invalid operation error simply disapear. If I take this line to a step before or after the if statement everything works out fine:

Before:
s[0] = 0.0;
if ( isZero(d) ) {
if ( isZero(q) ) { /* one triple solution */

After:
if ( isZero(d) ) {
if ( isZero(q) ) { /* one triple solution */
(…)
}
else
{
(…)
}
}
s[0] = 0.0;

S is a array of floats with 3 positions previouslly allocated.

So what I’m doing wrong here? Thanks alot!