| 455 | } |
| 456 | |
| 457 | std::vector<double> LNLib::Polynomials::OneBasisFunctionDerivative(int spanIndex, int degree, int derivative, const std::vector<double>& knotVector, double paramT) |
| 458 | { |
| 459 | VALIDATE_ARGUMENT(spanIndex >= 0, "spanIndex", "SpanIndex must be greater than or equal zero."); |
| 460 | VALIDATE_ARGUMENT(degree > 0, "degree", "Degree must be greater than zero."); |
| 461 | VALIDATE_ARGUMENT(derivative <= degree, "derivative", "Derivative must not be greater than degree."); |
| 462 | VALIDATE_ARGUMENT(knotVector.size() > 0, "knotVector", "KnotVector size must be greater than zero."); |
| 463 | VALIDATE_ARGUMENT(ValidationUtils::IsValidKnotVector(knotVector), "knotVector", "KnotVector must be a nondecreasing sequence of real numbers."); |
| 464 | VALIDATE_ARGUMENT_RANGE(paramT, knotVector[0], knotVector[knotVector.size() - 1]); |
| 465 | |
| 466 | std::vector<double> derivatives(derivative + 1, 0.0); |
| 467 | |
| 468 | if (MathUtils::IsLessThan(paramT, knotVector[spanIndex]) || |
| 469 | MathUtils::IsGreaterThanOrEqual(paramT, knotVector[spanIndex + degree + 1])) |
| 470 | { |
| 471 | return derivatives; |
| 472 | } |
| 473 | |
| 474 | std::vector<std::vector<double>> N(degree + 1, std::vector<double>(degree + 1,0.0)); |
| 475 | |
| 476 | for (int j = 0; j <= degree; j++) |
| 477 | { |
| 478 | if (MathUtils::IsGreaterThanOrEqual(paramT, knotVector[spanIndex + j]) && |
| 479 | MathUtils::IsLessThan(paramT, knotVector[spanIndex + j + 1])) |
| 480 | { |
| 481 | N[j][0] = 1.0; |
| 482 | } |
| 483 | } |
| 484 | for (int k = 1; k <= degree; k++) |
| 485 | { |
| 486 | double saved = 0.0; |
| 487 | if (!MathUtils::IsAlmostEqualTo(N[0][k - 1], 0.0)) |
| 488 | { |
| 489 | saved = ((paramT - knotVector[spanIndex]) * N[0][k - 1]) / (knotVector[spanIndex + k] - knotVector[spanIndex]); |
| 490 | } |
| 491 | for (int j = 0; j < degree - k + 1; j++) |
| 492 | { |
| 493 | double knotLeft = knotVector[spanIndex + j + 1]; |
| 494 | double knotRight = knotVector[spanIndex + j + k + 1]; |
| 495 | |
| 496 | if (MathUtils::IsAlmostEqualTo(N[j + 1][k - 1], 0.0)) |
| 497 | { |
| 498 | N[j][k] = saved; |
| 499 | saved = 0.0; |
| 500 | } |
| 501 | else |
| 502 | { |
| 503 | double temp = N[j + 1][k - 1] / (knotRight - knotLeft); |
| 504 | N[j][k] = saved + (knotRight - paramT) * temp; |
| 505 | saved = (paramT - knotLeft) * temp; |
| 506 | } |
| 507 | } |
| 508 | } |
| 509 | |
| 510 | derivatives[0] = N[0][degree]; |
| 511 | |
| 512 | for (int k = 1; k <= derivative; k++) |
| 513 | { |
| 514 | std::vector<double> ND(k+1,0.0); |
nothing calls this directly
no outgoing calls
no test coverage detected