## [Vxl-users] fixes for vnl_real_npolynomial

 [Vxl-users] fixes for vnl_real_npolynomial From: Lee Worden - 2006-06-23 01:23:28 ```Hi, I haven't been on vxl-users, and I'm having trouble connecting to the archive, so I apologize if this has already been dealt with. My project is generating vnl_real_npolynomial objects dynamically from evolving data structures in a simulation and passing them to vnl_rnpoly_solve, so it is probably stressing the code more than a lot of applications of those objects. I have workarounds for 2 bugs in vnl_real_npolynomial in VXL 1.5.1 and earlier. I'm posting them here in case they're useful to someone or they might be of use in a future release. Feedback is welcome. Thanks for the library - it's great! Lee ------ first: simplify() doesn't always remove terms with zero coefficient -- it fails when there is one or more zero term at the end of the vector. Here is a function that can fix up the object before you use it. The main change is marked with "***". void simplify(vnl_real_npolynomial &poly) { vnl_vector coeffs_ = poly.coefficients(); vnl_matrix polyn_ = poly.polyn(); unsigned int nvar_ = polyn_.cols(); unsigned int nterms_ = polyn_.rows(); for (unsigned int row1=0; row10 && coeffs_(nterms_-1)==0) --nterms_; // *** for (unsigned int row=0; row coeffs_ = P.coefficients(); vnl_matrix polyn_ = P.polyn(); unsigned int nvar_ = polyn_.cols(); unsigned int nterms_ = polyn_.rows(); if (nvar_ <= 3) for (unsigned int i=0; i0) { os << ' '; if (coeffs_(i) >= 0) os << "+ "; } if (coeffs_(i) < 0) os << "- "; if (fabs(coeffs_(i)) != 1) os << fabs(coeffs_(i)) << ' '; unsigned int totaldeg = 0; if (nvar_ > 0 && polyn_(i,0) > 0) { os << 'X'; totaldeg += polyn_(i,0); } if (nvar_ > 0 && polyn_(i,0) > 1) os << '^' << polyn_(i,0) << ' '; if (nvar_ > 1 && polyn_(i,1) > 0) { os << 'Y'; totaldeg += polyn_(i,1); } if (nvar_ > 1 && polyn_(i,1) > 1) os << '^' << polyn_(i,1) << ' '; if (nvar_ > 2 && polyn_(i,2) > 0) { os << 'Z'; totaldeg += polyn_(i,2); } if (nvar_ > 2 && polyn_(i,2) > 1) os << '^' << polyn_(i,2) << ' '; if (totaldeg == 0 && vcl_fabs(coeffs_(i)) == 1) os << fabs(coeffs_(i)); } else for (unsigned int i=0; i0) { os << ' '; if (coeffs_(i) >= 0) os << "+ "; } if (coeffs_(i) < 0) os << "- "; if (fabs(coeffs_(i)) != 1) os << fabs(coeffs_(i)) << ' '; unsigned int totaldeg = 0; for (unsigned int j=0; j 0) os << 'X' << j; if (polyn_(i,j) > 1) os << '^' << polyn_(i,j) << ' '; totaldeg += polyn_(i,j); } if (totaldeg == 0 && vcl_fabs(coeffs_(i)) == 1) os << fabs(coeffs_(i)); } //os << endl; return os.str(); } ```

 [Vxl-users] fixes for vnl_real_npolynomial From: Lee Worden - 2006-06-23 01:23:28 ```Hi, I haven't been on vxl-users, and I'm having trouble connecting to the archive, so I apologize if this has already been dealt with. My project is generating vnl_real_npolynomial objects dynamically from evolving data structures in a simulation and passing them to vnl_rnpoly_solve, so it is probably stressing the code more than a lot of applications of those objects. I have workarounds for 2 bugs in vnl_real_npolynomial in VXL 1.5.1 and earlier. I'm posting them here in case they're useful to someone or they might be of use in a future release. Feedback is welcome. Thanks for the library - it's great! Lee ------ first: simplify() doesn't always remove terms with zero coefficient -- it fails when there is one or more zero term at the end of the vector. Here is a function that can fix up the object before you use it. The main change is marked with "***". void simplify(vnl_real_npolynomial &poly) { vnl_vector coeffs_ = poly.coefficients(); vnl_matrix polyn_ = poly.polyn(); unsigned int nvar_ = polyn_.cols(); unsigned int nterms_ = polyn_.rows(); for (unsigned int row1=0; row10 && coeffs_(nterms_-1)==0) --nterms_; // *** for (unsigned int row=0; row coeffs_ = P.coefficients(); vnl_matrix polyn_ = P.polyn(); unsigned int nvar_ = polyn_.cols(); unsigned int nterms_ = polyn_.rows(); if (nvar_ <= 3) for (unsigned int i=0; i0) { os << ' '; if (coeffs_(i) >= 0) os << "+ "; } if (coeffs_(i) < 0) os << "- "; if (fabs(coeffs_(i)) != 1) os << fabs(coeffs_(i)) << ' '; unsigned int totaldeg = 0; if (nvar_ > 0 && polyn_(i,0) > 0) { os << 'X'; totaldeg += polyn_(i,0); } if (nvar_ > 0 && polyn_(i,0) > 1) os << '^' << polyn_(i,0) << ' '; if (nvar_ > 1 && polyn_(i,1) > 0) { os << 'Y'; totaldeg += polyn_(i,1); } if (nvar_ > 1 && polyn_(i,1) > 1) os << '^' << polyn_(i,1) << ' '; if (nvar_ > 2 && polyn_(i,2) > 0) { os << 'Z'; totaldeg += polyn_(i,2); } if (nvar_ > 2 && polyn_(i,2) > 1) os << '^' << polyn_(i,2) << ' '; if (totaldeg == 0 && vcl_fabs(coeffs_(i)) == 1) os << fabs(coeffs_(i)); } else for (unsigned int i=0; i0) { os << ' '; if (coeffs_(i) >= 0) os << "+ "; } if (coeffs_(i) < 0) os << "- "; if (fabs(coeffs_(i)) != 1) os << fabs(coeffs_(i)) << ' '; unsigned int totaldeg = 0; for (unsigned int j=0; j 0) os << 'X' << j; if (polyn_(i,j) > 1) os << '^' << polyn_(i,j) << ' '; totaldeg += polyn_(i,j); } if (totaldeg == 0 && vcl_fabs(coeffs_(i)) == 1) os << fabs(coeffs_(i)); } //os << endl; return os.str(); } ```
 Re: [Vxl-users] fixes for vnl_real_npolynomial From: Peter Vanroose - 2006-06-24 12:56:42 ```Thanks for the fixes! I'll incorporate them so they become available in the next vxl release. -- Peter. ```
 [Vxl-users] fixes for vnl_real_polynomial From: - 2006-08-02 00:29:10 ```Hi all. A while back I posted bug fixes for vnl_real_npolynomial relating to the simplify() member function and to printing out the object. Here are corresponding bug fixes for vnl_real_polynomial. There is also buggy behavior when the polynomial is zero - I believe it crashes when passed to vnl_poly_roots and when asked to perform devaluate() (at least after it's been worked over by the simplify() function listed below). I don't have fixes for that, because it makes more sense to work around, but it would be good to fix to prevent ugly crashes. lw. ====== 1. the vnl_poly_roots class refuses to operate on a polynomial that has leading zero coefficients. This function makes sure there aren't any. inline void simplify(vnl_real_polynomial &p) { vnl_vector &coeffs_ = p.coefficients(); // vnl_rpoly_roots insists on no leading zeros unsigned first = 0; const double threshold = 1e-8; while (first 0) coeffs_ = coeffs_.extract(coeffs_.size()-first,first); p.set_coefficients(coeffs_); } ====== 2. this is modified from vnl_real_polynomial::print(). that function fails when the constant term is 1 or -1, and I think it has a bug regarding the sign of the first coefficient. Also it's convenient to be able to write cout << asString(p) << endl and such. (If I were maintaining the class I would probably also provide a << operator for p, but that's not necessary.) inline string asString(vnl_real_polynomial &p) { ostringstream os; int d = p.degree(); vnl_vector &coeffs_ = p.coefficients(); int i = 0; while (i <= d && coeffs_[i] == 0) ++i; if (i > d) { os << "0 "; return os.str(); } // bool b = (coeffs_[i+1] > 0); // to avoid '+' in front of equation bool b = (coeffs_[i] > 0); // to avoid '+' in front of equation for (; i <= d; ++i) { if (coeffs_[i] == 0) continue; if (coeffs_[i] < 0) os << "- "; else if (!b) os << "+ "; b = false; if (d == 0 || fabs(coeffs_[i]) != 1) os << fabs(coeffs_[i]) << ' '; if (d-i > 1) os << "X^" << d-i << ' '; else if (d-i == 1) os << "X "; } return os.str(); } ```