13 #ifndef EIGEN_HYBRIDNONLINEARSOLVER_H
14 #define EIGEN_HYBRIDNONLINEARSOLVER_H
18 namespace HybridNonLinearSolverSpace {
42 template<
typename FunctorType,
typename Scalar=
double>
120 template<
typename FunctorType,
typename Scalar>
130 if (
n <= 0 ||
tol < 0.)
137 useExternalScaling =
true;
141 template<
typename FunctorType,
typename Scalar>
147 wa1.resize(
n); wa2.resize(
n); wa3.resize(
n); wa4.resize(
n);
151 if (!useExternalScaling)
153 eigen_assert( (!useExternalScaling ||
diag.size()==
n) &&
"When useExternalScaling is set, the caller must provide a valid 'diag'");
162 if (useExternalScaling)
170 if ( functor(
x, fvec) < 0)
172 fnorm = fvec.stableNorm();
184 template<
typename FunctorType,
typename Scalar>
193 std::vector<JacobiRotation<Scalar> > v_givens(
n), w_givens(
n);
198 if ( functor.df(
x, fjac) < 0)
202 wa2 = fjac.colwise().blueNorm();
207 if (!useExternalScaling)
208 for (
j = 0;
j <
n; ++
j)
209 diag[
j] = (wa2[
j]==0.) ? 1. : wa2[
j];
213 xnorm =
diag.cwiseProduct(
x).stableNorm();
232 if (!useExternalScaling)
237 internal::dogleg<Scalar>(
R,
diag, qtf,
delta, wa1);
242 pnorm =
diag.cwiseProduct(wa1).stableNorm();
249 if ( functor(wa2, wa4) < 0)
252 fnorm1 = wa4.stableNorm();
260 wa3 =
R.template triangularView<Upper>()*wa1 + qtf;
261 temp = wa3.stableNorm();
269 ratio = actred / prered;
290 wa2 =
diag.cwiseProduct(
x);
292 xnorm = wa2.stableNorm();
299 if (actred >=
Scalar(.001))
326 wa1 =
diag.cwiseProduct(
diag.cwiseProduct(wa1)/pnorm );
327 wa2 = fjac.transpose() * wa4;
330 wa2 = (wa2-wa3)/pnorm;
333 internal::r1updt<Scalar>(
R, wa1, v_givens, w_givens, wa2, wa3, &sing);
334 internal::r1mpyq<Scalar>(
n,
n, fjac.data(), v_givens, w_givens);
335 internal::r1mpyq<Scalar>(1,
n, qtf.data(), v_givens, w_givens);
342 template<
typename FunctorType,
typename Scalar>
350 status = solveOneStep(
x);
356 template<
typename FunctorType,
typename Scalar>
366 if (
n <= 0 ||
tol < 0.)
374 useExternalScaling =
true;
375 return solveNumericalDiff(
x);
378 template<
typename FunctorType,
typename Scalar>
387 wa1.resize(
n); wa2.resize(
n); wa3.resize(
n); wa4.resize(
n);
391 if (!useExternalScaling)
393 eigen_assert( (!useExternalScaling ||
diag.size()==
n) &&
"When useExternalScaling is set, the caller must provide a valid 'diag'");
402 if (useExternalScaling)
410 if ( functor(
x, fvec) < 0)
412 fnorm = fvec.stableNorm();
424 template<
typename FunctorType,
typename Scalar>
434 std::vector<JacobiRotation<Scalar> > v_givens(
n), w_givens(
n);
445 wa2 = fjac.colwise().blueNorm();
450 if (!useExternalScaling)
451 for (
j = 0;
j <
n; ++
j)
452 diag[
j] = (wa2[
j]==0.) ? 1. : wa2[
j];
456 xnorm =
diag.cwiseProduct(
x).stableNorm();
475 if (!useExternalScaling)
480 internal::dogleg<Scalar>(
R,
diag, qtf,
delta, wa1);
485 pnorm =
diag.cwiseProduct(wa1).stableNorm();
492 if ( functor(wa2, wa4) < 0)
495 fnorm1 = wa4.stableNorm();
503 wa3 =
R.template triangularView<Upper>()*wa1 + qtf;
504 temp = wa3.stableNorm();
512 ratio = actred / prered;
533 wa2 =
diag.cwiseProduct(
x);
535 xnorm = wa2.stableNorm();
542 if (actred >=
Scalar(.001))
569 wa1 =
diag.cwiseProduct(
diag.cwiseProduct(wa1)/pnorm );
570 wa2 = fjac.transpose() * wa4;
573 wa2 = (wa2-wa3)/pnorm;
576 internal::r1updt<Scalar>(
R, wa1, v_givens, w_givens, wa2, wa3, &sing);
577 internal::r1mpyq<Scalar>(
n,
n, fjac.data(), v_givens, w_givens);
578 internal::r1mpyq<Scalar>(1,
n, qtf.data(), v_givens, w_givens);
585 template<
typename FunctorType,
typename Scalar>
593 status = solveNumericalDiffOneStep(
x);
599 #endif // EIGEN_HYBRIDNONLINEARSOLVER_H