Hi Jim. > What about logic like this: > > boolean checkRoots = false; > if (D < 0) { > // 3 solution form is possible, so use it > checkRoots = (D > -TINY); // Check them if we were borderline > // compute 3 roots as before > } else { > double u = ...; > double v = ...; > res[0] = u+v; // should be 2*u if D is near zero > if (u close to v) { // Will be true for D near zero > res[1] = -res[0]/2; // should be -u if D is near zero > checkRoots = true; // Check them if we were borderline > // Note that q=0 case ends up here as well... > } > } > if (checkRoots) { > if (num > 2 && (res[2] == res[1] || res[2] == res[0]) { > num--; > } > if (num > 1 && res[1] == res[0]) { > res[1] = res[--num]; // Copies res[2] to res[1] if needed > } > for (int i = num-1; i >= 0; i--) { > res[i] = refine(res[i]); > for (int j = i+1; j < num; j++) { > if (res[i] == res[j]) { > res[i] = res[--num]; > break; > } > } > } > }
I have two concerns about this. 1. How would refine() be implemented? Would we do something like in findZero? 2. While I have no problem with your suggestion, it won't help us in cases where there's a root with a multiplicity of 2 which is not found. This was a large part of the motivation for this work. What should we do in this case? The only solution I can see is to find the roots of the derivative and evaluate the cubic at them, because when a root has multiplicity > 1, the polynomial's derivative also has a root there. This is what I'm currently doing. Should we go ahead and push the pisces changes? The cubic solver in pisces is good enough for what we're using it. Regards, Denis.