Newton optimizer: handle flat directions without producing NaN - #3429
Newton optimizer: handle flat directions without producing NaN#3429SteveBronder wants to merge 10 commits into
Conversation
Fixes #3425. make_negative_definite_and_solve divided the gradient projection by fabs(eigenvalue) with no zero guard. For a target that is flat along a direction the gradient and Hessian are both zero, so the step was 0/0 and the resulting NaN parameters were accepted by the line search and reported by the service as a successful run. - Drop eigen-directions whose magnitude is negligible relative to the largest eigenvalue, as in a pseudo-inverse, so the step is finite. - Reject non-finite step directions, candidate points, and objective values in newton_step instead of accepting them. - Have the newton service return error_codes::SOFTWARE with TERM_LSFAIL when the final log density or parameters are not finite. Adds a flat_target test model plus unit tests at the solve, step, and service layers that reproduce the reported NaN.
| vector_d eigenprojections = eigenvectors.transpose() * g; | ||
| double max_abs_eigenvalue = eigenvalues.cwiseAbs().maxCoeff(); | ||
| double tolerance | ||
| = max_abs_eigenvalue * H.rows() * std::numeric_limits<double>::epsilon(); |
There was a problem hiding this comment.
Where does this number come from? Is machine epsilon the appropriate baseline here? Why does it depend on the number of rows? Maybe this is related to the numerical precision of the solver...
Also you should handle the case where all eigenvalues are zero. Set some minimum absolute tolerance.
| eigenprojections[i] = -eigenprojections[i] / fabs(eigenvalues[i]); | ||
| double abs_eigenvalue = std::fabs(eigenvalues[i]); | ||
| if (abs_eigenvalue <= tolerance) { | ||
| eigenprojections[i] = 0; |
There was a problem hiding this comment.
If target is flat then gradient is zero and what you substitute for the eigenvalue doesn't matter, as long as it's finite. But it's also possible that the target is linear, and if so, the gradient is nonzero while the hessian is still zero. I think you'd want nonzero movement in that case. So instead of zero you should use inverse tolerance. Unlike pseudo-inverse, such "saturating inverse" is continuous.
| eigenprojections[i] = 0; | |
| eigenprojections[i] = -eigenprojections[i] / tolerance; |
There was a problem hiding this comment.
Talking to claude I had it cite all of it's choices and explain things. I've cleanup up Claude's explanation below which I think makes sense.
Your suggestion divides by tolerance, which at that point was n * eps * max(abs(lambda)). That gives a step along a flat direction of roughly 1e15 times the gradient. Nocedal and Wright discuss exactly this on pp. 49-50 of Numerical Optimization (2nd ed., §3.4, "Eigenvalue Modification"): replacing small eigenvalues with a
So the code now floors every eigenvalue magnitude rather than branching, and the floor is
const double sqrt_eps = std::sqrt(std::numeric_limits<double>::epsilon());
double max_abs_eigenvalue = eigenvalues.cwiseAbs().maxCoeff();
double delta = std::fmax(sqrt_eps * max_abs_eigenvalue, sqrt_eps);
for (int i = 0; i < g.size(); i++) {
eigenprojections[i]
= -eigenprojections[i] / std::fmax(std::fabs(eigenvalues[i]), delta);
}This is the max(abs(pivot), delta) floor from the modified Cholesky factorization, eq. 3.49 on p. 54 of the same book (credited there to Gill, Murray, and Wright, with Moré and Sorensen for the bounded condition number), applied in the eigenbasis. Written that way it is the "PT-inverse" of Paternain, Mokhtari, and Ribeiro, SIAM J. Optim. 29(1) 2019, Definition 2.1 (arXiv:1707.08028 (https://arxiv.org/abs/1707.08028)):
On the value of the floor:
- The relative term follows the
$\delta = \sqrt u$ on p. 49. R's nlm (the Dennis and Schnabel minimizer in src/appl/uncmin.c (https://raw.githubusercontent.com/wch/r-source/trunk/src/appl/uncmin.c)) uses the same rule: tol = sqrt(epsm) with pivots floored at tol*diagmx, the square root of epsilon times the largest diagonal entry. - The absolute term is the minimum absolute tolerance you asked for in the other comment, so an all-zero Hessian gives a finite direction. I dropped the numeric_limits::min() clamp because dividing a moderate gradient by it overflows to infinity. Precedent for an absolute clamp on curvature: Ceres'
min_lm_diagonal = 1e-6 on diag(J'J)(include/ceres/solver.h (https://raw.githubusercontent.com/ceres-solver/ceres-solver/master/include/ceres/solver.h)) and Ipopt'smin_hessian_perturbation(options (https://coin-or.github.io/Ipopt/OPTIONS.html)). Using √u for the absolute term makes it agree with the relative term when the largest eigenvalue is 1, the "well scaled" assumption Nocedal and Wright use on p. 196.
There was a problem hiding this comment.
Your suggestion divides by tolerance, which at that point was
n * eps * max(abs(lambda)). That gives a step along a flat direction of roughly 1e15 times the gradient.
Claude seems to forget that I had also questioned whether that tolerance was appropriate.
And 1e15 times zero ("flat gradient") is still zero.
But yes, this all makes sense.
Precedent for an absolute clamp on curvature: Ceres'
min_lm_diagonal = 1e-6 on diag(J'J)and Ipopt'smin_hessian_perturbation.
Feels like this sentence cuts off early? Maybe should be
and Ipopt's
min_hessian_perturbation = 1e-20on the iteration matrix.
| * @return true if all elements are finite | ||
| */ | ||
| template <typename Vec> | ||
| inline bool all_finite(const Vec& v) { |
There was a problem hiding this comment.
This looks like a reimplementation of stan::math::is_scal_finite
There was a problem hiding this comment.
Sorry! yes I need to fixup a few things . We can totally remove this function
|
By the way, and this is a pre-existing issue, but even a simple model like parameters {
vector[3] x;
}
model {
x ~ normal(0, [10,1,0.1]');
}takes 100 iterations, which is completely unreasonable behavior for a Newton solver. Apparently step size is 1.90735e-06 for every iteration so something is very wrong. And that something is
|
That ship may have sailed... Even within math, it's not used by any other code, so I'm not sure why it (or
This sounds like it would be worthy of it's own PR |
For the record, anything inside of math's internal namespace has zero API guarantee aka the math library can change these on a whim with no version notice. This is what Eigen does as well (and partly why upgrading Eigen is such a hassle for us) |
…st normal double Match the premultiplied threshold used by Eigen's rank-revealing decompositions on master: Higham's backward error bound with a factor of 4 covering the constant, and a lower clamp at numeric_limits<double>::min() so an all-zero Hessian yields a positive cutoff. Adds tests for the cutoff boundary and for an all-zero Hessian with a nonzero gradient.
|
Yeah I understand that. These functions were added entirely on their own with no direct usages in |
Replace the rank cutoff in make_negative_definite_and_solve with a saturating inverse: each eigenvalue magnitude is floored at delta = max(sqrt(u) * max|lambda|, sqrt(u)) before inverting, following the modified-Newton floor in Nocedal and Wright, Numerical Optimization, 2nd ed., Sec. 3.4 (eq. 3.49; delta of order sqrt(u), p. 49). Dropping small eigenvalues stalled on targets with a nonzero gradient but no curvature, and rounding noise in the finite-difference Hessian could still be inverted into steps of order 1e19. The floor is continuous in the eigenvalues and bounds the effective condition number of the solve by 1 / sqrt(u). Adds a linear_target test model and tests at the solve, step, and service layers: small eigenvalues are floored rather than dropped, the solve is continuous across the old cutoff, and a linear target moves uphill by a bounded step without reporting convergence.
Jenkins Console Log Machine informationDistributor ID: Ubuntu Description: Ubuntu 20.04.3 LTS Release: 20.04 Codename: focal CPU: Architecture: x86_64 CPU op-mode(s): 32-bit, 64-bit Byte Order: Little Endian Address sizes: 52 bits physical, 57 bits virtual CPU(s): 192 On-line CPU(s) list: 0-191 Thread(s) per core: 2 Core(s) per socket: 48 Socket(s): 2 NUMA node(s): 2 Vendor ID: AuthenticAMD CPU family: 25 Model: 17 Model name: AMD EPYC 9474F 48-Core Processor Stepping: 1 Frequency boost: enabled CPU MHz: 1494.681 CPU max MHz: 4114.4229 CPU min MHz: 1500.0000 BogoMIPS: 7189.04 Virtualization: AMD-V L1d cache: 3 MiB L1i cache: 3 MiB L2 cache: 96 MiB L3 cache: 512 MiB NUMA node0 CPU(s): 0-47,96-143 NUMA node1 CPU(s): 48-95,144-191 Vulnerability Gather data sampling: Not affected Vulnerability Indirect target selection: Not affected Vulnerability Itlb multihit: Not affected Vulnerability L1tf: Not affected Vulnerability Mds: Not affected Vulnerability Meltdown: Not affected Vulnerability Mmio stale data: Not affected Vulnerability Reg file data sampling: Not affected Vulnerability Retbleed: Not affected Vulnerability Spec rstack overflow: Mitigation; Safe RET Vulnerability Spec store bypass: Mitigation; Speculative Store Bypass disabled via prctl Vulnerability Spectre v1: Mitigation; usercopy/swapgs barriers and __user pointer sanitization Vulnerability Spectre v2: Mitigation; Enhanced / Automatic IBRS; IBPB conditional; STIBP always-on; PBRSB-eIBRS Not affected; BHI Not affected Vulnerability Srbds: Not affected Vulnerability Tsa: Mitigation; Clear CPU buffers Vulnerability Tsx async abort: Not affected Vulnerability Vmscape: Mitigation; IBPB before exit to userspace Flags: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good amd_lbr_v2 nopl xtopology nonstop_tsc cpuid extd_apicid aperfmperf rapl pni pclmulqdq monitor ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx f16c rdrand lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw ibs skinit wdt tce topoext perfctr_core perfctr_nb bpext perfctr_llc mwaitx cpb cat_l3 cdp_l3 hw_pstate ssbd mba perfmon_v2 ibrs ibpb stibp ibrs_enhanced vmmcall fsgsbase bmi1 avx2 smep bmi2 erms invpcid cqm rdt_a avx512f avx512dq rdseed adx smap avx512ifma clflushopt clwb avx512cd sha_ni avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves cqm_llc cqm_occup_llc cqm_mbm_total cqm_mbm_local user_shstk avx512_bf16 clzero irperf xsaveerptr rdpru wbnoinvd amd_ppin cppc arat npt lbrv svm_lock nrip_save tsc_scale vmcb_clean flushbyasid decodeassists pausefilter pfthreshold avic v_vmsave_vmload vgif x2avic v_spec_ctrl vnmi avx512vbmi umip pku ospke avx512_vbmi2 gfni vaes vpclmulqdq avx512_vnni avx512_bitalg avx512_vpopcntdq la57 rdpid overflow_recov succor smca fsrm flush_l1d debug_swap G++: g++ (Ubuntu 9.4.0-1ubuntu1~20.04) 9.4.0 Copyright (C) 2019 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Clang: clang version 10.0.0-4ubuntu1 Target: x86_64-pc-linux-gnu Thread model: posix InstalledDir: /usr/bin |
Jenkins Console Log Machine informationDistributor ID: Ubuntu Description: Ubuntu 20.04.3 LTS Release: 20.04 Codename: focal CPU: Architecture: x86_64 CPU op-mode(s): 32-bit, 64-bit Byte Order: Little Endian Address sizes: 52 bits physical, 57 bits virtual CPU(s): 192 On-line CPU(s) list: 0-191 Thread(s) per core: 2 Core(s) per socket: 48 Socket(s): 2 NUMA node(s): 2 Vendor ID: AuthenticAMD CPU family: 25 Model: 17 Model name: AMD EPYC 9474F 48-Core Processor Stepping: 1 Frequency boost: enabled CPU MHz: 1499.401 CPU max MHz: 4114.4229 CPU min MHz: 1500.0000 BogoMIPS: 7189.04 Virtualization: AMD-V L1d cache: 3 MiB L1i cache: 3 MiB L2 cache: 96 MiB L3 cache: 512 MiB NUMA node0 CPU(s): 0-47,96-143 NUMA node1 CPU(s): 48-95,144-191 Vulnerability Gather data sampling: Not affected Vulnerability Indirect target selection: Not affected Vulnerability Itlb multihit: Not affected Vulnerability L1tf: Not affected Vulnerability Mds: Not affected Vulnerability Meltdown: Not affected Vulnerability Mmio stale data: Not affected Vulnerability Reg file data sampling: Not affected Vulnerability Retbleed: Not affected Vulnerability Spec rstack overflow: Mitigation; Safe RET Vulnerability Spec store bypass: Mitigation; Speculative Store Bypass disabled via prctl Vulnerability Spectre v1: Mitigation; usercopy/swapgs barriers and __user pointer sanitization Vulnerability Spectre v2: Mitigation; Enhanced / Automatic IBRS; IBPB conditional; STIBP always-on; PBRSB-eIBRS Not affected; BHI Not affected Vulnerability Srbds: Not affected Vulnerability Tsa: Mitigation; Clear CPU buffers Vulnerability Tsx async abort: Not affected Vulnerability Vmscape: Mitigation; IBPB before exit to userspace Flags: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good amd_lbr_v2 nopl xtopology nonstop_tsc cpuid extd_apicid aperfmperf rapl pni pclmulqdq monitor ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx f16c rdrand lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw ibs skinit wdt tce topoext perfctr_core perfctr_nb bpext perfctr_llc mwaitx cpb cat_l3 cdp_l3 hw_pstate ssbd mba perfmon_v2 ibrs ibpb stibp ibrs_enhanced vmmcall fsgsbase bmi1 avx2 smep bmi2 erms invpcid cqm rdt_a avx512f avx512dq rdseed adx smap avx512ifma clflushopt clwb avx512cd sha_ni avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves cqm_llc cqm_occup_llc cqm_mbm_total cqm_mbm_local user_shstk avx512_bf16 clzero irperf xsaveerptr rdpru wbnoinvd amd_ppin cppc arat npt lbrv svm_lock nrip_save tsc_scale vmcb_clean flushbyasid decodeassists pausefilter pfthreshold avic v_vmsave_vmload vgif x2avic v_spec_ctrl vnmi avx512vbmi umip pku ospke avx512_vbmi2 gfni vaes vpclmulqdq avx512_vnni avx512_bitalg avx512_vpopcntdq la57 rdpid overflow_recov succor smca fsrm flush_l1d debug_swap G++: g++ (Ubuntu 9.4.0-1ubuntu1~20.04) 9.4.0 Copyright (C) 2019 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Clang: clang version 10.0.0-4ubuntu1 Target: x86_64-pc-linux-gnu Thread model: posix InstalledDir: /usr/bin |
Jenkins Console Log Machine informationDistributor ID: Ubuntu Description: Ubuntu 20.04.3 LTS Release: 20.04 Codename: focal CPU: Architecture: x86_64 CPU op-mode(s): 32-bit, 64-bit Byte Order: Little Endian Address sizes: 43 bits physical, 48 bits virtual CPU(s): 256 On-line CPU(s) list: 0-255 Thread(s) per core: 2 Core(s) per socket: 64 Socket(s): 2 NUMA node(s): 2 Vendor ID: AuthenticAMD CPU family: 23 Model: 49 Model name: AMD EPYC 7742 64-Core Processor Stepping: 0 Frequency boost: enabled CPU MHz: 1497.227 CPU max MHz: 3416.0681 CPU min MHz: 1500.0000 BogoMIPS: 4491.55 Virtualization: AMD-V L1d cache: 4 MiB L1i cache: 4 MiB L2 cache: 64 MiB L3 cache: 512 MiB NUMA node0 CPU(s): 0-63,128-191 NUMA node1 CPU(s): 64-127,192-255 Vulnerability Gather data sampling: Not affected Vulnerability Indirect target selection: Not affected Vulnerability Itlb multihit: Not affected Vulnerability L1tf: Not affected Vulnerability Mds: Not affected Vulnerability Meltdown: Not affected Vulnerability Mmio stale data: Not affected Vulnerability Reg file data sampling: Not affected Vulnerability Retbleed: Mitigation; untrained return thunk; SMT enabled with STIBP protection Vulnerability Spec rstack overflow: Mitigation; Safe RET Vulnerability Spec store bypass: Mitigation; Speculative Store Bypass disabled via prctl Vulnerability Spectre v1: Mitigation; usercopy/swapgs barriers and __user pointer sanitization Vulnerability Spectre v2: Mitigation; Retpolines; IBPB conditional; STIBP always-on; RSB filling; PBRSB-eIBRS Not affected; BHI Not affected Vulnerability Srbds: Not affected Vulnerability Tsa: Not affected Vulnerability Tsx async abort: Not affected Vulnerability Vmscape: Mitigation; IBPB before exit to userspace Flags: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good nopl xtopology nonstop_tsc cpuid extd_apicid aperfmperf rapl pni pclmulqdq monitor ssse3 fma cx16 sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx f16c rdrand lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw ibs skinit wdt tce topoext perfctr_core perfctr_nb bpext perfctr_llc mwaitx cpb cat_l3 cdp_l3 hw_pstate ssbd mba ibrs ibpb stibp vmmcall fsgsbase bmi1 avx2 smep bmi2 cqm rdt_a rdseed adx smap clflushopt clwb sha_ni xsaveopt xsavec xgetbv1 xsaves cqm_llc cqm_occup_llc cqm_mbm_total cqm_mbm_local clzero irperf xsaveerptr rdpru wbnoinvd amd_ppin arat npt lbrv svm_lock nrip_save tsc_scale vmcb_clean flushbyasid decodeassists pausefilter pfthreshold avic v_vmsave_vmload vgif v_spec_ctrl umip rdpid overflow_recov succor smca sev sev_es G++: g++ (Ubuntu 9.4.0-1ubuntu1~20.04) 9.4.0 Copyright (C) 2019 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Clang: clang version 10.0.0-4ubuntu1 Target: x86_64-pc-linux-gnu Thread model: posix InstalledDir: /usr/bin |
If I'm being honest, there are a lot of funky things in this newton optimizer |
Compute the Hessian with stan::math::internal::finite_diff_hessian_auto, a central difference of the gradient with a per-coordinate step size. This costs 2n + 1 gradient evaluations per step instead of the 4n + 1 of the four-point stencil in grad_hess_log_prob, and matches what laplace_sample already uses. Evaluate the log density with propto = false so the backtracking line search can run on plain doubles instead of a reverse-mode pass whose gradient was discarded. The returned log density therefore includes constant terms. Work in Eigen vectors directly, dropping the element-wise copies, and forward output_stream to the log density evaluations instead of ignoring it.
f6dbb1a to
9f77b74
Compare
Jenkins Console Log Machine informationDistributor ID: Ubuntu Description: Ubuntu 20.04.3 LTS Release: 20.04 Codename: focal CPU: Architecture: x86_64 CPU op-mode(s): 32-bit, 64-bit Byte Order: Little Endian Address sizes: 46 bits physical, 48 bits virtual CPU(s): 80 On-line CPU(s) list: 0-79 Thread(s) per core: 2 Core(s) per socket: 20 Socket(s): 2 NUMA node(s): 2 Vendor ID: GenuineIntel CPU family: 6 Model: 85 Model name: Intel(R) Xeon(R) Gold 6248 CPU @ 2.50GHz Stepping: 7 CPU MHz: 999.941 CPU max MHz: 3900.0000 CPU min MHz: 1000.0000 BogoMIPS: 5000.00 Virtualization: VT-x L1d cache: 1.3 MiB L1i cache: 1.3 MiB L2 cache: 40 MiB L3 cache: 55 MiB NUMA node0 CPU(s): 0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52,54,56,58,60,62,64,66,68,70,72,74,76,78 NUMA node1 CPU(s): 1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31,33,35,37,39,41,43,45,47,49,51,53,55,57,59,61,63,65,67,69,71,73,75,77,79 Vulnerability Gather data sampling: Mitigation; Microcode Vulnerability Indirect target selection: Mitigation; Aligned branch/return thunks Vulnerability Itlb multihit: KVM: Mitigation: Split huge pages Vulnerability L1tf: Not affected Vulnerability Mds: Not affected Vulnerability Meltdown: Not affected Vulnerability Mmio stale data: Mitigation; Clear CPU buffers; SMT vulnerable Vulnerability Reg file data sampling: Not affected Vulnerability Retbleed: Mitigation; Enhanced IBRS Vulnerability Spec rstack overflow: Not affected Vulnerability Spec store bypass: Mitigation; Speculative Store Bypass disabled via prctl Vulnerability Spectre v1: Mitigation; usercopy/swapgs barriers and __user pointer sanitization Vulnerability Spectre v2: Mitigation; Enhanced / Automatic IBRS; IBPB conditional; PBRSB-eIBRS SW sequence; BHI SW loop, KVM SW loop Vulnerability Srbds: Not affected Vulnerability Tsa: Not affected Vulnerability Tsx async abort: Mitigation; TSX disabled Vulnerability Vmscape: Mitigation; IBPB before exit to userspace Flags: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid dca sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault epb cat_l3 cdp_l3 intel_ppin ssbd mba ibrs ibpb stibp ibrs_enhanced tpr_shadow flexpriority ept vpid ept_ad fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid cqm mpx rdt_a avx512f avx512dq rdseed adx smap clflushopt clwb intel_pt avx512cd avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves cqm_llc cqm_occup_llc cqm_mbm_total cqm_mbm_local dtherm ida arat pln pts hwp hwp_act_window hwp_epp hwp_pkg_req vnmi pku ospke avx512_vnni md_clear flush_l1d arch_capabilities G++: g++ (Ubuntu 9.4.0-1ubuntu1~20.04) 9.4.0 Copyright (C) 2019 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Clang: clang version 10.0.0-4ubuntu1 Target: x86_64-pc-linux-gnu Thread model: posix InstalledDir: /usr/bin |
|
@WardBrian so the cmdstan test is failing, but imo I think we should make this change. The difference is that we now use |
|
It will be a bit odd that newton and the other optimizers wouldn't agree with each other on a model where they all find the same mode but report a different There is also the option of using var types but not actually calling gradient, which would still be better than what the current code does. |
That's what |
I think compared to the forward pass I would not imagine them to be very expensive. For instance normal_lpdf is pretty simple I think many of them are kind of like this. |
Submission Checklist
./runTests.py src/test/unitmake cpplintSummary
Fixes #3425.
make_negative_definite_and_solvedivided the gradient projection byfabs(eigenvalue)with no guard against zero or near zero values. This could lead to some directions of the gradient and hessian being flat and causing NaN values to return. Now we check that the absolute of the eigen value is greater than a tolerance defined by the an epsilon scaled by the overall maximum eigenvalue. We reject non-finite step directions, candidate points, and objective values in newton_step instead of accepting them. And the newton service layer not returnserror_codes::SOFTWAREwithTERM_LSFAILwhen the final log density or parameters are not finite.Adds a
flat_targettest model plus unit tests at the solve, step, and service layers that reproduce the reported NaN.Documentation
Updated docs for
make_negative_definite_and_solveto reflect the change.Copyright and Licensing
Please list the copyright holder for the work you are submitting (this will be you or your assignee, such as a university or company): Steve Bronder
By submitting this pull request, the copyright holder is agreeing to license the submitted work under the following licenses: