bool ON_BezierCage::SetCV( int i, int j, int k, ON::point_style style, const double* Point ) { bool rc = true; int n; double w; double* cv = CV(i,j,k); if ( !cv ) return false; switch ( style ) { case ON::not_rational: // input Point is not rational memcpy( cv, Point, m_dim*sizeof(*cv) ); if ( IsRational() ) { // NURBS surface is rational - set weight to one cv[m_dim] = 1.0; } break; case ON::homogeneous_rational: // input Point is homogeneous rational if ( IsRational() ) { // NURBS surface is rational memcpy( cv, Point, (m_dim+1)*sizeof(*cv) ); } else { // NURBS surface is not rational w = (Point[m_dim] != 0.0) ? 1.0/Point[m_dim] : 1.0; for ( n = 0; n < m_dim; n++ ) { cv[n] = w*Point[n]; } } break; case ON::euclidean_rational: // input Point is euclidean rational if ( IsRational() ) { // NURBS surface is rational - convert euclean point to homogeneous form w = Point[m_dim]; for ( n = 0; n < m_dim; n++ ) cv[i] = w*Point[i]; cv[m_dim] = w; } else { // NURBS surface is not rational memcpy( cv, Point, m_dim*sizeof(*cv) ); } break; case ON::intrinsic_point_style: n = m_is_rat?m_dim+1:m_dim; memcpy(cv,Point,n*sizeof(*cv)); break; default: rc = false; break; } return rc; }
bool ON_BezierCage::MakeRational() { if ( !IsRational() ) { ON_ERROR("TODO: fill in ON_BezierCage::MakeRational()"); /* const int dim = Dimension(); if ( m_order[0] > 0 && m_order[1] > 0 && m_order[2] > 0 && dim > 0 ) { const double* old_cv; double* new_cv; int cvi, cvj, j, cvstride; if ( m_cv_stride[0] < m_cv_stride[1] ) { cvstride = m_cv_stride[0] > dim ? m_cv_stride[0] : dim+1; ReserveCVCapacity( cvstride*m_order[0]*m_order[1] ); new_cv = m_cv + cvstride*m_order[0]*m_order[1]-1; for ( cvj = m_order[1]-1; cvj >= 0; cvj-- ) { for ( cvi = m_order[0]-1; cvi >= 0; cvi-- ) { old_cv = CV(cvi,cvj)+dim-1; *new_cv-- = 1.0; for ( j = 0; j < dim; j++ ) { *new_cv-- = *old_cv--; } } } m_cv_stride[0] = dim+1; m_cv_stride[1] = (dim+1)*m_order[0]; } else { cvstride = m_cv_stride[1] > dim ? m_cv_stride[1] : dim+1; ReserveCVCapacity( cvstride*m_order[0]*m_order[1] ); new_cv = m_cv + cvstride*m_order[0]*m_order[1]-1; for ( cvi = m_order[0]-1; cvi >= 0; cvi-- ) { for ( cvj = m_order[1]-1; cvj >= 0; cvj-- ) { old_cv = CV(cvi,cvj)+dim-1; *new_cv-- = 1.0; for ( j = 0; j < dim; j++ ) { *new_cv-- = *old_cv--; } } } m_cv_stride[1] = dim+1; m_cv_stride[0] = (dim+1)*m_order[1]; } m_is_rat = 1; } */ } return IsRational(); }
bool ON_BezierCage::GetCV( int i, int j, int k, ON::point_style style, double* Point ) const { const double* cv = CV(i,j,k); if ( !cv ) return false; int dim = Dimension(); double w = ( IsRational() ) ? cv[dim] : 1.0; switch(style) { case ON::euclidean_rational: Point[dim] = w; // no break here case ON::not_rational: if ( w == 0.0 ) return false; w = 1.0/w; while(dim--) *Point++ = *cv++ * w; break; case ON::homogeneous_rational: Point[dim] = w; memcpy( Point, cv, dim*sizeof(*Point) ); break; default: return false; } return true; }
bool ON_BezierCage::MakeNonRational() { if ( IsRational() ) { ON_ERROR("TODO: fill in ON_BezierCage::MakeNonRational()"); /* const int dim = Dimension(); if ( m_order[0] > 0 && m_order[1] > 0 && dim > 0 ) { double w; const double* old_cv; double* new_cv = m_cv; int cvi, cvj, j; if ( m_cv_stride[0] < m_cv_stride[1] ) { for ( cvj = 0; cvj < m_order[1]; cvj++ ) { for ( cvi = 0; cvi < m_order[0]; cvi++ ) { old_cv = CV(cvi,cvj); w = old_cv[dim]; w = ( w != 0.0 ) ? 1.0/w : 1.0; for ( j = 0; j < dim; j++ ) { *new_cv++ = w*(*old_cv++); } } } m_cv_stride[0] = dim; m_cv_stride[1] = dim*m_order[0]; } else { for ( cvi = 0; cvi < m_order[0]; cvi++ ) { for ( cvj = 0; cvj < m_order[1]; cvj++ ) { old_cv = CV(cvi,cvj); w = old_cv[dim]; w = ( w != 0.0 ) ? 1.0/w : 1.0; for ( j = 0; j < dim; j++ ) { *new_cv++ = w*(*old_cv++); } } } m_cv_stride[1] = dim; m_cv_stride[0] = dim*m_order[1]; } m_is_rat = 0; } */ } return ( !IsRational() ) ? true : false; }
std::vector<RingElem> BM_QQ(const SparsePolyRing& P, const ConstMatrixView& pts_in) { const long NumPts = NumRows(pts_in); const long dim = NumCols(pts_in); matrix pts = NewDenseMat(RingQQ(), NumPts, dim); for (long i=0; i < NumPts; ++i) for (long j=0; j < dim; ++j) { BigRat q; if (!IsRational(q, pts_in(i,j))) throw 999; SetEntry(pts,i,j, q); } // Ensure input pts have integer coords by using // scale factors for each indet. vector<BigInt> ScaleFactor(dim, BigInt(1)); for (long j=0; j < dim; ++j) for (long i=0; i < NumPts; ++i) ScaleFactor[j] = lcm(ScaleFactor[j], ConvertTo<BigInt>(den(pts(i,j)))); mpz_t **points = (mpz_t**)malloc(NumPts*sizeof(mpz_t*)); for (long i=0; i < NumPts; ++i) { points[i] = (mpz_t*)malloc(dim*sizeof(mpz_t)); for (long j=0; j < dim; ++j) mpz_init(points[i][j]); for (long j=0; j < dim; ++j) { mpz_set(points[i][j], mpzref(ConvertTo<BigInt>(ScaleFactor[j]*pts(i,j)))); } } BMGB char0; // these will be "filled in" by BM_affine below BM modp; // pp_cmp_PPM = &PPM(P); // not threadsafe! BM_affine(&char0, &modp, dim, NumPts, points, pp_cmp); // THIS CALL DOES THE REAL WORK!!! pp_cmp_PPM = NULL; for (long i=NumPts-1; i >=0 ; --i) { for (long j=0; j < dim; ++j) mpz_clear(points[i][j]); free(points[i]); } free(points); if (modp == NULL) { if (char0 != NULL) BMGB_dtor(char0); CoCoA_ERROR("Something went wrong", "BM_QQ"); } // Now extract the answer... const int GBsize = char0->GBsize; std::vector<RingElem> GB(GBsize); const long NumVars = dim; vector<long> expv(NumVars); // buffer for creating monomials for (int i=0; i < GBsize; ++i) { BigInt denom(1); // scale factor needed to make GB elem monic. for (int var = 0; var < NumVars; ++var) { expv[var] = modp->pp[modp->GB[i]][var]; denom *= power(ScaleFactor[var], expv[var]); } RingElem GBelem = monomial(P, 1, expv); for (int j=0; j < NumPts; ++j) { if (mpq_sgn(char0->GB[i][j])==0) continue; BigRat c(char0->GB[i][j]); for (int var = 0; var < NumVars; ++var) { expv[var] = modp->pp[modp->sep[j]][var]; c *= power(ScaleFactor[var], expv[var]); } GBelem += monomial(P, c/denom, expv); } GB[i] = GBelem; } BMGB_dtor(char0); BM_dtor(modp); return GB; // ignoring separators for the moment }
bool isRationalObject() const { return IsRational( this->ref ); }