Used to evaluate basis functions - alternative to the recursive deBoorCox
| 158 | |
| 159 | // Used to evaluate basis functions - alternative to the recursive deBoorCox |
| 160 | SparseMatrix BSplineBasis1D::buildBasisMatrix(double x, unsigned int u, unsigned int k, bool diff) const |
| 161 | { |
| 162 | /* Build B-spline Matrix |
| 163 | * R_k in R^(k,k+1) |
| 164 | * or, if diff = true, the differentiated basis matrix |
| 165 | * DR_k in R^(k,k+1) |
| 166 | */ |
| 167 | |
| 168 | if (!(k >= 1 && k <= getBasisDegree())) |
| 169 | { |
| 170 | throw Exception("BSplineBasis1D::buildBasisMatrix: Incorrect input paramaters!"); |
| 171 | } |
| 172 | |
| 173 | // assert(u >= basisDegree + 1); |
| 174 | // assert(u < ks.size() - basisDegree); |
| 175 | |
| 176 | unsigned int rows = k; |
| 177 | unsigned int cols = k+1; |
| 178 | SparseMatrix R(rows, cols); |
| 179 | R.reserve(Eigen::VectorXi::Constant(cols, 2)); |
| 180 | |
| 181 | for (unsigned int i = 0; i < rows; i++) |
| 182 | { |
| 183 | double dk = knots.at(u+1+i) - knots.at(u+1+i-k); |
| 184 | if (dk == 0) |
| 185 | { |
| 186 | continue; |
| 187 | } |
| 188 | else |
| 189 | { |
| 190 | if (diff) |
| 191 | { |
| 192 | // Insert diagonal element |
| 193 | R.insert(i,i) = -1/dk; |
| 194 | |
| 195 | // Insert super-diagonal element |
| 196 | R.insert(i,i+1) = 1/dk; |
| 197 | } |
| 198 | else |
| 199 | { |
| 200 | // Insert diagonal element |
| 201 | double a = (knots.at(u+1+i) - x)/dk; |
| 202 | if (a != 0) |
| 203 | R.insert(i,i) = a; |
| 204 | |
| 205 | // Insert super-diagonal element |
| 206 | double b = (x - knots.at(u+1+i-k))/dk; |
| 207 | if (b != 0) |
| 208 | R.insert(i,i+1) = b; |
| 209 | } |
| 210 | } |
| 211 | } |
| 212 | |
| 213 | R.makeCompressed(); |
| 214 | |
| 215 | return R; |
| 216 | } |
| 217 |