rowvec Connectome::richClub(const mat &W, int klevel) { /* inputs: W: weighted connection matrix optional: k-level: max level of RC(k). When k-level is -1, k-level is set to max of degree of W output: rich: rich-club curve adopted from Opsahl et al. Phys Rev Lett, 2008, 101(16) */ rowvec nodeDegree = degree(W); if (klevel == -1) klevel = nodeDegree.max(); vec wrank = sort(vectorise(W),"descend"); rowvec Rw = rowvec(1,W.n_rows).fill(datum::nan); uvec smallNodes; for (uint kk=0;kk<klevel;++kk) { smallNodes = find(nodeDegree<kk+1); if (smallNodes.is_empty()) continue; mat cutOutW = W; smallNodes = sort(smallNodes,"descend"); for (uint i =0;i<smallNodes.n_elem;++i) { cutOutW.shed_row(smallNodes(i)); cutOutW.shed_col(smallNodes(i)); } double Wr = accu(cutOutW); uvec t = find(cutOutW != 0); if (!t.is_empty()) Rw(kk) = Wr/ accu(wrank.subvec(0,t.n_elem-1)); } return Rw; }
/*! Insert \f$ l_r \f$ times a knot in the \f$ l_k \f$ th interval of the knot vector. The inserted knot \f$ l_u \f$ has multiplicity \f$ l_s \f$. Of course the knot vector changes. But The list of control points and the list of the associated weights change too. \param l_u : A real number which is between the extrimities of the knot vector and which has to be inserted. \param l_k : The number of the knot interval in which \f$ l_u \f$ lies. \param l_s : Multiplicity of \f$ l_u \f$ \param l_r : Number of times \f$ l_u \f$ has to be inserted. \param l_p : Degree of the NURBS basis functions. \param l_knots : The knot vector \param l_controlPoints : the list of control points. \param l_weights : the list of weights. */ void vpNurbs::curveKnotIns(double l_u, unsigned int l_k, unsigned int l_s, unsigned int l_r, unsigned int l_p, std::vector<double> &l_knots, std::vector<vpImagePoint> &l_controlPoints, std::vector<double> &l_weights) { vpMatrix Rw(l_p+1,3); std::vector<vpImagePoint>::iterator it1; std::vector<double>::iterator it2; vpImagePoint pt; double w = 0; for (unsigned int j = 0; j <= l_p-l_s; j++) { Rw[j][0] = (l_controlPoints[l_k-l_p+j]).get_i() * l_weights[l_k-l_p+j]; Rw[j][1] = (l_controlPoints[l_k-l_p+j]).get_j() * l_weights[l_k-l_p+j]; Rw[j][2] = l_weights[l_k-l_p+j]; } it1 = l_controlPoints.begin(); l_controlPoints.insert(it1+(int)l_k-(int)l_s, l_r, pt); it2 = l_weights.begin(); l_weights.insert(it2+(int)l_k-(int)l_s, l_r, w); unsigned int L=0; double alpha; for (unsigned int j = 1; j <= l_r; j++) { L = l_k - l_p +j; for (unsigned int i = 0; i <=l_p-j-l_s; i++) { alpha = (l_u - l_knots[L+i])/(l_knots[i+l_k+1] - l_knots[L+i]); Rw[i][0]= alpha*Rw[i+1][0]+(1.0-alpha)*Rw[i][0]; Rw[i][1]= alpha*Rw[i+1][1]+(1.0-alpha)*Rw[i][1]; Rw[i][2]= alpha*Rw[i+1][2]+(1.0-alpha)*Rw[i][2]; } pt.set_ij(Rw[0][0]/Rw[0][2],Rw[0][1]/Rw[0][2]); l_controlPoints[L] = pt; l_weights[L] = Rw[0][2]; pt.set_ij(Rw[l_p-j-l_s][0]/Rw[l_p-j-l_s][2],Rw[l_p-j-l_s][1]/Rw[l_p-j-l_s][2]); l_controlPoints[l_k+l_r-j-l_s] = pt; l_weights[l_k+l_r-j-l_s] = Rw[l_p-j-l_s][2]; } for(unsigned int j = L+1; j < l_k-l_s; j++) { pt.set_ij(Rw[j-L][0]/Rw[j-L][2],Rw[j-L][1]/Rw[j-L][2]); l_controlPoints[j] = pt; l_weights[j] = Rw[j-L][2]; } it2 = l_knots.begin(); l_knots.insert(it2+(int)l_k, l_r, l_u); }
void lcd_init(){ MyLCDport; Rw(0); lcd_init4bitmode(); }
/*! Method which enables to compute a NURBS curve approximating a set of data points. The data points are approximated thanks to a least square method. The result of the method is composed by a knot vector, a set of control points and a set of associated weights. \param l_crossingPoints : The list of data points which have to be interpolated. \param l_p : Degree of the NURBS basis functions. \param l_n : The desired number of control points. l_n must be under or equal to the number of data points. \param l_knots : The knot vector. \param l_controlPoints : the list of control points. \param l_weights : the list of weights. */ void vpNurbs::globalCurveApprox(std::vector<vpImagePoint> &l_crossingPoints, unsigned int l_p, unsigned int l_n, std::vector<double> &l_knots, std::vector<vpImagePoint> &l_controlPoints, std::vector<double> &l_weights) { l_knots.clear(); l_controlPoints.clear(); l_weights.clear(); unsigned int m = (unsigned int)l_crossingPoints.size()-1; double d = 0; for(unsigned int k=1; k<=m; k++) d = d + distance(l_crossingPoints[k],1,l_crossingPoints[k-1],1); //Compute ubar std::vector<double> ubar; ubar.push_back(0.0); for(unsigned int k=1; k<m; k++) ubar.push_back(ubar[k-1]+distance(l_crossingPoints[k],1,l_crossingPoints[k-1],1)/d); ubar.push_back(1.0); //Compute the knot vector for(unsigned int k = 0; k <= l_p; k++) l_knots.push_back(0.0); d = (double)(m+1)/(double)(l_n-l_p+1); for(unsigned int j = 1; j <= l_n-l_p; j++) { double i = floor(j*d); double alpha = j*d-i; l_knots.push_back((1.0-alpha)*ubar[(unsigned int)i-1]+alpha*ubar[(unsigned int)i]); } for(unsigned int k = 0; k <= l_p ; k++) l_knots.push_back(1.0); //Compute Rk std::vector<vpImagePoint> Rk; vpBasisFunction* N; for(unsigned int k = 1; k <= m-1; k++) { unsigned int span = findSpan(ubar[k], l_p, l_knots); if (span == l_p && span == l_n) { N = computeBasisFuns(ubar[k], span, l_p, l_knots); vpImagePoint pt(l_crossingPoints[k].get_i()-N[0].value*l_crossingPoints[0].get_i()-N[l_p].value*l_crossingPoints[m].get_i(), l_crossingPoints[k].get_j()-N[0].value*l_crossingPoints[0].get_j()-N[l_p].value*l_crossingPoints[m].get_j()); Rk.push_back(pt); delete[] N; } else if (span == l_p) { N = computeBasisFuns(ubar[k], span, l_p, l_knots); vpImagePoint pt(l_crossingPoints[k].get_i()-N[0].value*l_crossingPoints[0].get_i(), l_crossingPoints[k].get_j()-N[0].value*l_crossingPoints[0].get_j()); Rk.push_back(pt); delete[] N; } else if (span == l_n) { N = computeBasisFuns(ubar[k], span, l_p, l_knots); vpImagePoint pt(l_crossingPoints[k].get_i()-N[l_p].value*l_crossingPoints[m].get_i(), l_crossingPoints[k].get_j()-N[l_p].value*l_crossingPoints[m].get_j()); Rk.push_back(pt); delete[] N; } else { Rk.push_back(l_crossingPoints[k]); } } vpMatrix A(m-1,l_n-1); //Compute A for(unsigned int i = 1; i <= m-1; i++) { unsigned int span = findSpan(ubar[i], l_p, l_knots); N = computeBasisFuns(ubar[i], span, l_p, l_knots); for (unsigned int k = 0; k <= l_p; k++) { if (N[k].i > 0 && N[k].i < l_n) A[i-1][N[k].i-1] = N[k].value; } delete[] N; } vpColVector Ri(l_n-1); vpColVector Rj(l_n-1); vpColVector Rw(l_n-1); for (unsigned int i = 0; i < l_n-1; i++) { double sum =0; for (unsigned int k = 0; k < m-1; k++) sum = sum + A[k][i]*Rk[k].get_i(); Ri[i] = sum; sum = 0; for (unsigned int k = 0; k < m-1; k++) sum = sum + A[k][i]*Rk[k].get_j(); Rj[i] = sum; sum = 0; for (unsigned int k = 0; k < m-1; k++) sum = sum + A[k][i]; //The crossing points weigths are equal to 1. Rw[i] = sum; } vpMatrix AtA = A.AtA(); vpMatrix AtAinv; AtA.pseudoInverse(AtAinv); vpColVector Pi = AtAinv*Ri; vpColVector Pj = AtAinv*Rj; vpColVector Pw = AtAinv*Rw; vpImagePoint pt; l_controlPoints.push_back(l_crossingPoints[0]); l_weights.push_back(1.0); for (unsigned int k = 0; k < l_n-1; k++) { pt.set_ij(Pi[k],Pj[k]); l_controlPoints.push_back(pt); l_weights.push_back(Pw[k]); } l_controlPoints.push_back(l_crossingPoints[m]); l_weights.push_back(1.0); }
inline void converter<point_t>::knot_insertion(point_container_t& P, std::multiset<value_type>& knots, std::size_t order, value_type t) const { typedef typename point_t::value_type value_type; // copy knotvector for subscript [] access std::vector<value_type> kv_cpy(knots.begin(), knots.end()); // get parameter std::size_t p = order - 1; // degree std::size_t s = knots.count(t); // multiplicity std::size_t r = std::max(std::size_t(0), p - s); // number of insertions // get knotspan std::size_t k = std::distance(knots.begin(), knots.upper_bound(t)); std::size_t np = P.size(); // number of control points // start computation std::size_t nq = np + r; // helper arrays std::vector<point_t> Qw(nq); std::vector<point_t> Rw(p - s + 1); // copy unaffected points and transform into homogenous coords for (size_t i = 0; i <= k - p; ++i) { Qw[i] = P[i].as_homogenous(); } for (size_t i = k - s - 1; i <= np - 1; ++i) { Qw[i + r] = P[i].as_homogenous(); } // helper points for (size_t i = 0; i <= p - s; ++i) { Rw[i] = P[k - p + i - 1].as_homogenous(); } // do knot insertion itself std::size_t L = 0; for (std::size_t j = 1; j <= r; ++j) { L = k - p + j; for (std::size_t i = 0; i <= p - j - s; ++i) { value_type alpha = (t - kv_cpy[L + i - 1]) / (kv_cpy[i + k] - kv_cpy[L + i - 1]); Rw[i] = alpha * Rw[i + 1] + value_type(1.0 - alpha) * Rw[i]; } Qw[L - 1] = Rw[0]; Qw[k + r - j - s - 1] = Rw[p - j - s]; } // insert knots for (std::size_t i = 0; i < r; ++i) { knots.insert(t); } // copy new control points P.clear(); // transform back to euclidian space for (typename std::vector<point_t>::iterator i = Qw.begin(); i != Qw.end(); ++i) { P.push_back((*i).as_euclidian()); } }