11 : setGuess(
std::move(initialGuessSetter)), stopCondition(
std::move(stopCondition)), extract(
std::move(extractResult)), target(tgt), current(static_cast<InputT>(0)), maxIterations(maxIter), h(jacobianStep), tolerance(tol), alpha(damping) {
12 current = glm::vec3(0.0f);
13 fPerturbed.fill(glm::vec3(0.0f));
14 state = SolverState::WaitingForBase;
20 case SolverState::WaitingForBase:
23 if (!stopCondition())
return false;
25 baseOutput = extract();
26 if (glm::length(baseOutput - target) < tolerance) {
29 if (iterationCount >= maxIterations) {
33 currentPerturbation = 0;
34 state = SolverState::PerturbComponent;
37 case SolverState::PerturbComponent:
40 xPerturbed[currentPerturbation] += h;
43 state = SolverState::WaitingForPerturbed;
46 case SolverState::WaitingForPerturbed:
48 if (!stopCondition())
return false;
50 fPerturbed[currentPerturbation] = extract();
52 currentPerturbation++;
54 if (currentPerturbation < 3)
55 state = SolverState::PerturbComponent;
57 state = SolverState::ComputeJacobian;
61 case SolverState::ComputeJacobian: {
63 for (
int j = 0; j < 3; ++j)
64 for (
int i = 0; i < 3; ++i) {
66 J[i][j] = (fPerturbed[j][i] - baseOutput[i]) / h;
69 glm::vec3 error = baseOutput - target;
71 float detJ = glm::determinant(J);
74 if (std::abs(detJ) < kSingularJacobianDeterminant) {
76 dx = -kSingularJacobianNudgeFactor * error;
79 dx = -alpha * glm::inverse(J) * error;
85 state = SolverState::WaitingForBase;
VectorRootSolver(InitialGuessSetter initialGuessSetter, StopCondition stopCondition, ResultExtractor extractResult, const OutputT &target, double tolerance=1e-3, int maxIterations=30, double jacobianStep=0.01, double damping=1.0)
Construct a new VectorRootSolver object.