-
-
Notifications
You must be signed in to change notification settings - Fork 204
Add Wolfe line search to Laplace approximation #3250
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 47 commits
Commits
Show all changes
125 commits
Select commit
Hold shift + click to select a range
43c3eef
update the laplace line search to use a more advanced wolfe line sear…
SteveBronder 74a92bc
Merge remote-tracking branch 'origin/develop' into fix/laplace-wolfe-…
SteveBronder 2de7a4f
add data for roach data test
SteveBronder 547288e
update tests
SteveBronder cb5e282
move wolfe to its own file
SteveBronder cdaf700
Merge remote-tracking branch 'origin' into fix/laplace-wolfe-line-search
SteveBronder 6b22c85
update wolfe
SteveBronder a1d0906
Merge remote-tracking branch 'origin' into fix/laplace-wolfe-line-search
SteveBronder 5b6ffff
update to use barzilai borwein step size as initial step size estimate
SteveBronder 8eff766
seperate moto from other lpdf tests
SteveBronder f542cc5
update
SteveBronder c845944
add WolfeInfo
SteveBronder 40f1243
use WolfeInfo for extra data
SteveBronder 6e528d2
put everything for iterations in laplace into structs
SteveBronder d89eeb5
update poisson test
SteveBronder 40d889f
add swap functions
SteveBronder 59b7a2f
cleanup laplace_density_est to reduce repeated code
SteveBronder c73f5aa
update to search for a good initial alpha on a space
SteveBronder 773d417
fix code for wolfe line search
SteveBronder b557dad
update tests for zoom
SteveBronder b18bf87
all tests pass for laplace with new wolfe
SteveBronder 98df588
use log sum of diagonal of U matrix for solver 3 determinant
SteveBronder 929dd47
move update_step to be a user passed function
SteveBronder 2ebb01a
cleanup the laplace code to remove some passed by reference values to…
SteveBronder 3bbcef3
cleanup the laplace code to remove some passed by reference values to…
SteveBronder 66ffec9
update WolfeData with member accessors and use Eval within WolfeData
SteveBronder ff5bee4
update docs for wolfe
SteveBronder 7a7415a
update logic in laplace_marginal_desntiy_est so that final updated va…
SteveBronder 973144a
clang format
SteveBronder cc5d49a
change stepsize of finite difference to use 6th order instead of 2nd …
SteveBronder d759fdd
change moto test gradient relative error
SteveBronder 7b4e3a1
update wolfe tests
SteveBronder dfba08b
allow user to set max number of line search iterations.
SteveBronder 7df0ed1
remove extra copy is laplace_likelihood::theta_grad
SteveBronder 0c92732
cleanup and doc
SteveBronder d19ee8b
clang format
SteveBronder 82e43da
Merge commit '5e698970d52ee9cfe85630cca9794e43ec829cf2' into HEAD
yashikno 22a2210
[Jenkins] auto-formatting by clang-format version 10.0.0-4ubuntu1
stan-buildbot 24e2e19
update finit diff back to original
SteveBronder 7720c7a
[Jenkins] auto-formatting by clang-format version 10.0.0-4ubuntu1
stan-buildbot 63e1700
fix finite_diff_stepsize and lower tolerance for AD tests on inv_Phi,…
SteveBronder a9f17d4
Merge commit 'b82d68ced2e73c8188f3bbf287c1321033103986' into HEAD
yashikno 28c44dd
[Jenkins] auto-formatting by clang-format version 10.0.0-4ubuntu1
stan-buildbot fddf54f
cpplint fixes
SteveBronder 113e2b1
[Jenkins] auto-formatting by clang-format version 10.0.0-4ubuntu1
stan-buildbot 88a8950
fix doxygen docs
SteveBronder c4fcba2
Merge remote-tracking branch 'refs/remotes/origin/fix/wolfe-zoom1' in…
SteveBronder 521145f
update moto tests to not take the gradient with respect to y as some …
SteveBronder d648ee0
update laplace_latent_tol_bernoulli_logit_rng user options orderings.…
SteveBronder 7778307
[Jenkins] auto-formatting by clang-format version 10.0.0-4ubuntu1
stan-buildbot 04b5b2e
handle NA values for obj and grad. Allow for zero line search. allow …
SteveBronder 4117a31
[Jenkins] auto-formatting by clang-format version 10.0.0-4ubuntu1
stan-buildbot affabfa
update step iter
SteveBronder a143355
cleanup zoom in wolfe line search
SteveBronder 95c21d5
Merge commit '85c147ee6adbe58eb9ae1578c0478fcf3da9bf76' into HEAD
yashikno 5ba7426
[Jenkins] auto-formatting by clang-format version 10.0.0-4ubuntu1
stan-buildbot 475c632
update poisson_log_lpmf test to use google test parameterization
SteveBronder 307fb0c
add throw testing in neg_binomial_log_summary
SteveBronder 5038198
breakout the laplace tests so they print nicely
SteveBronder 7e9af37
[Jenkins] auto-formatting by clang-format version 10.0.0-4ubuntu1
stan-buildbot 863223e
fix cpplint
SteveBronder 04197f2
[Jenkins] auto-formatting by clang-format version 10.0.0-4ubuntu1
stan-buildbot c8a1613
address partial review comments
SteveBronder aeb1662
Merge commit 'a5f80224b857e06dd7ca753d826e5b292ee8e73c' into HEAD
yashikno ea9ffe0
[Jenkins] auto-formatting by clang-format version 10.0.0-4ubuntu1
stan-buildbot 7f7bbb2
update refactor for laplace_marginal_density_est
SteveBronder 66e8470
update with initial shim
SteveBronder 6acdd09
update with initial shim
SteveBronder 9dc118e
update with initial shim
SteveBronder b9a493a
update with initial shim
SteveBronder 7c886f5
update with initial shim
SteveBronder 5eb664b
update with initial shim
SteveBronder 1f7ff3c
update with initial shim
SteveBronder 65914d3
update with initial shim
SteveBronder 6b74be8
update with initial shim
SteveBronder e9cad2e
update
SteveBronder db4f677
Merge commit 'a6932f2a8ff8d1800c7020d29593b5934a20e40b' into HEAD
yashikno aa73b5d
[Jenkins] auto-formatting by clang-format version 10.0.0-4ubuntu1
stan-buildbot cf151fa
remove extra comments
SteveBronder 0022b41
Moves many of the functions built for laplace into seperate files for…
SteveBronder 0e1b7f4
Merge commit '52f7e9244d5367b74e4b4274d2a1c0e9f15a23f9' into HEAD
yashikno d26626f
[Jenkins] auto-formatting by clang-format version 10.0.0-4ubuntu1
stan-buildbot a2a0a99
add initializers to solvers for laplace
SteveBronder a4f0b7d
fix docs for laplace_marginal_density_est
SteveBronder 4c884dd
[Jenkins] auto-formatting by clang-format version 10.0.0-4ubuntu1
stan-buildbot e6b2d74
minor cleanup
SteveBronder 27d2fc9
minor cleanup
SteveBronder f845a43
cleanup retry logic on NaN of Inf objective function values
SteveBronder 200fd9a
[Jenkins] auto-formatting by clang-format version 10.0.0-4ubuntu1
stan-buildbot d6859f1
adds fallthrough option in user opts. User ops are now a tuple the us…
SteveBronder d2de83d
Merge remote-tracking branch 'refs/remotes/origin/fix/wolfe-zoom1' in…
SteveBronder 7f1a995
[Jenkins] auto-formatting by clang-format version 10.0.0-4ubuntu1
stan-buildbot d86fa69
update docs
SteveBronder 6abd9da
[Jenkins] auto-formatting by clang-format version 10.0.0-4ubuntu1
stan-buildbot b30823d
remove .csv files for .hpp files
SteveBronder dd1e74e
Merge remote-tracking branch 'refs/remotes/origin/fix/wolfe-zoom1' in…
SteveBronder b292cae
[Jenkins] auto-formatting by clang-format version 10.0.0-4ubuntu1
stan-buildbot ed3ce3a
make non-static so it's memory is allocated dynamically.
SteveBronder d9319ad
remove rev/core/set_zero_adjoints.hpp
SteveBronder a14b58d
update for @wardbrian review
SteveBronder b61a3d6
Merge commit 'bf9fc6bc00539c5ddb31d4ed622b08b19ea36c44' into HEAD
yashikno 28467a2
[Jenkins] auto-formatting by clang-format version 10.0.0-4ubuntu1
stan-buildbot d43587f
update
SteveBronder 10d5012
[Jenkins] auto-formatting by clang-format version 10.0.0-4ubuntu1
stan-buildbot c2bc877
use csv reader for roach_data
SteveBronder 5d24366
fix doxygen for new Eigen
SteveBronder 968b4bb
Update Eigen library version in Doxygen config
SteveBronder f993bdb
use std::decay on tuple_to_laplace_options template argument
SteveBronder 102a79a
update with decay_t
SteveBronder 0acaf73
Merge commit '42063be9833129cdf1d4b2299616ec8aba237d80' into HEAD
yashikno 96e3c2f
[Jenkins] auto-formatting by clang-format version 10.0.0-4ubuntu1
stan-buildbot 6288ccd
fixes for @wardbrian review
SteveBronder 8cefcd4
[Jenkins] auto-formatting by clang-format version 10.0.0-4ubuntu1
stan-buildbot 6789f32
Remove commented out debugging statements in aki_ex
SteveBronder eab35ec
update with last review
SteveBronder 97846a6
[Jenkins] auto-formatting by clang-format version 10.0.0-4ubuntu1
stan-buildbot 495e9c6
fix wolfe table formatting
SteveBronder 17002d9
remove log files
SteveBronder 37d2ab4
Revert "remove log files"
SteveBronder 30573a7
Revert "fix wolfe table formatting"
SteveBronder 237f2a4
Revert "[Jenkins] auto-formatting by clang-format version 10.0.0-4ubu…
SteveBronder cd363fe
Revert "update with last review"
SteveBronder 7a47143
cleanup tests and address review comments
SteveBronder fcd1b3c
[Jenkins] auto-formatting by clang-format version 10.0.0-4ubuntu1
stan-buildbot ca363fe
changed tests compile with O3 and native
SteveBronder File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,11 +8,49 @@ | |
| namespace stan { | ||
| namespace math { | ||
|
|
||
| namespace internal { | ||
| /** | ||
| * Set all adjoints of the output to zero. | ||
| */ | ||
| template <typename Output> | ||
| inline void set_zero_adjoint(Output&& output) { | ||
| if constexpr (is_all_arithmetic_scalar_v<Output>) { | ||
| return; | ||
| } else { | ||
| return iter_tuple_nested( | ||
| [](auto&& output_i) { | ||
| using output_i_t = std::decay_t<decltype(output_i)>; | ||
| if constexpr (is_all_arithmetic_scalar_v<output_i_t>) { | ||
| return; | ||
| } else if constexpr (is_std_vector<output_i_t>::value) { | ||
| for (Eigen::Index i = 0; i < output_i.size(); ++i) { | ||
| output_i[i].adj() = 0; | ||
| } | ||
| } else if constexpr (is_eigen_v<output_i_t>) { | ||
| output_i.adj().setZero(); | ||
| } else if constexpr (is_stan_scalar_v<output_i_t>) { | ||
| output_i.adj() = 0; | ||
| } else { | ||
| static_assert( | ||
| sizeof(std::decay_t<output_i_t>*) == 0, | ||
| "INTERNAL ERROR:(laplace_marginal_lpdf) set_zero_adjoints was " | ||
| "not able to deduce the actions needed for the given type. " | ||
| "This is an internal error, please report it: " | ||
| "https://github.com/stan-dev/math/issues"); | ||
| } | ||
| }, | ||
| std::forward<Output>(output)); | ||
| } | ||
| } | ||
|
|
||
| } // namespace internal | ||
|
|
||
| /** | ||
| * functions to compute the log density, first, second, | ||
| * and third-order derivatives for a likelihoood specified by the user. | ||
| */ | ||
| namespace laplace_likelihood { | ||
|
|
||
| namespace internal { | ||
| /** | ||
| * @tparam F A functor with `opertor()(Args&&...)` returning a scalar | ||
|
|
@@ -106,6 +144,126 @@ inline auto shallow_copy_vargs(Args&&... args) { | |
| std::forward<Args>(args)...); | ||
| } | ||
|
|
||
| /** | ||
| * Computes theta gradient `f` wrt `theta` and `args...` | ||
| * @note If `Args` contains \ref var types then their adjoints will be | ||
| * calculated as a side effect. | ||
| * @tparam F A functor with `opertor()(Args&&...)` returning a scalar | ||
| * @tparam Theta A class assignable to an Eigen vector type | ||
| * @tparam Stream Type of stream for messages. | ||
| * @tparam Args Type of variadic arguments. | ||
| * @param f Log likelihood function. | ||
| * @param theta Latent Gaussian model. | ||
| * @param msgs Stream for messages. | ||
| * @param args Variadic arguments for the likelihood function. | ||
| */ | ||
| template <typename F, typename Theta, typename Stream, typename... Args, | ||
| require_eigen_vector_vt<std::is_arithmetic, Theta>* = nullptr> | ||
| inline auto theta_grad(F&& f, Theta&& theta, Stream* msgs, Args&&... args) { | ||
| using Eigen::Dynamic; | ||
| using Eigen::Matrix; | ||
| nested_rev_autodiff nested; | ||
| Matrix<var, Dynamic, 1> theta_var = theta; | ||
| var f_var = f(theta_var, args..., msgs); | ||
| grad(f_var.vi_); | ||
| return theta_var.adj().eval(); | ||
| } | ||
|
|
||
| /** | ||
| * Computes likelihood argument gradient of `f` | ||
SteveBronder marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| * @note If `Args` contains \ref var types then their adjoints will be | ||
| * calculated as a side effect. | ||
| * @tparam F A functor with `opertor()(Args&&...)` returning a scalar | ||
| * @tparam Theta A class assignable to an Eigen vector type | ||
| * @tparam Stream Type of stream for messages. | ||
| * @tparam Args Type of variadic arguments. | ||
| * @param f Log likelihood function. | ||
| * @param theta Latent Gaussian model. | ||
| * @param msgs Stream for messages. | ||
| * @param args Variadic arguments for the likelihood function. | ||
| */ | ||
| template <typename F, typename Theta, typename Stream, typename... Args, | ||
| require_eigen_vector_vt<std::is_arithmetic, Theta>* = nullptr> | ||
| inline void ll_arg_grad(F&& f, Theta&& theta, Stream* msgs, Args&&... args) { | ||
| using Eigen::Dynamic; | ||
| using Eigen::Matrix; | ||
| nested_rev_autodiff nested; | ||
| var f_var = f(theta, args..., msgs); | ||
| grad(f_var.vi_); | ||
| } | ||
|
|
||
| /** | ||
| * Computes negative block diagonal Hessian of `f` wrt`theta` and `args...` | ||
| * @note If `Args` contains \ref var types then their adjoints will be | ||
| * calculated as a side effect. | ||
| * @tparam F A functor with `opertor()(Args&&...)` returning a scalar | ||
| * @tparam Theta A class assignable to an Eigen vector type | ||
| * @tparam Stream Type of stream for messages. | ||
| * @tparam Args Type of variadic arguments. | ||
| * @param f Log likelihood function. | ||
| * @param theta Latent Gaussian model. | ||
| * @param hessian_block_size If the Hessian of the log likelihood function w.r.t | ||
| * the latent Gaussian variable is block-diagonal, | ||
| * size of each block. | ||
| * @param msgs Stream for messages. | ||
| * @param args Variadic arguments for the likelihood function. | ||
| */ | ||
| template <typename F, typename Theta, typename Stream, typename... Args, | ||
| require_eigen_vector_vt<std::is_arithmetic, Theta>* = nullptr> | ||
| inline auto diagonal_hessian(F&& f, Theta&& theta, Stream* msgs, | ||
| Args&&... args) { | ||
| using Eigen::Dynamic; | ||
| using Eigen::Matrix; | ||
| const Eigen::Index theta_size = theta.size(); | ||
| auto v = Eigen::VectorXd::Ones(theta_size); | ||
| Eigen::VectorXd hessian_v = Eigen::VectorXd::Zero(theta_size); | ||
| hessian_times_vector(f, hessian_v, std::forward<Theta>(theta), std::move(v), | ||
| value_of(args)..., msgs); | ||
| return (-hessian_v).eval(); | ||
| } | ||
|
|
||
| /** | ||
| * Computes negative block diagonal Hessian of `f` wrt`theta` and `args...` | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Change the description slightly to distinguish from previous function and indicate that one handles the diagonal case and one doesn't. |
||
| * @note If `Args` contains \ref var types then their adjoints will be | ||
| * calculated as a side effect. | ||
| * @tparam F A functor with `opertor()(Args&&...)` returning a scalar | ||
| * @tparam Theta A class assignable to an Eigen vector type | ||
| * @tparam Stream Type of stream for messages. | ||
| * @tparam Args Type of variadic arguments. | ||
| * @param f Log likelihood function. | ||
| * @param theta Latent Gaussian model. | ||
| * @param hessian_block_size If the Hessian of the log likelihood function w.r.t | ||
| * the latent Gaussian variable is block-diagonal, | ||
| * size of each block. | ||
| * @param msgs Stream for messages. | ||
| * @param args Variadic arguments for the likelihood function. | ||
| */ | ||
| template <typename F, typename Theta, typename Stream, typename... Args, | ||
| require_eigen_vector_vt<std::is_arithmetic, Theta>* = nullptr> | ||
| inline auto block_hessian(F&& f, Theta&& theta, | ||
| const Eigen::Index hessian_block_size, Stream* msgs, | ||
| Args&&... args) { | ||
| using Eigen::Dynamic; | ||
| using Eigen::Matrix; | ||
| const Eigen::Index theta_size = theta.size(); | ||
| if (hessian_block_size == 1) { | ||
| auto v = Eigen::VectorXd::Ones(theta_size); | ||
| Eigen::VectorXd hessian_v = Eigen::VectorXd::Zero(theta_size); | ||
| hessian_times_vector(f, hessian_v, std::forward<Theta>(theta), std::move(v), | ||
| value_of(args)..., msgs); | ||
| Eigen::SparseMatrix<double> hessian_theta(theta_size, theta_size); | ||
| hessian_theta.reserve(Eigen::VectorXi::Constant(theta_size, 1)); | ||
| for (Eigen::Index i = 0; i < theta_size; i++) { | ||
| hessian_theta.insert(i, i) = hessian_v(i); | ||
| } | ||
| return (-hessian_theta).eval(); | ||
| } else { | ||
| return (-hessian_block_diag(f, std::forward<Theta>(theta), | ||
| hessian_block_size, value_of(args)..., msgs)) | ||
| .eval(); | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Computes theta gradient and negative block diagonal Hessian of `f` wrt | ||
| * `theta` and `args...` | ||
|
|
@@ -301,6 +459,79 @@ inline auto diff_eta_implicit(F&& f, V_t&& v, Theta&& theta, Stream* msgs, | |
|
|
||
| } // namespace internal | ||
|
|
||
| /** | ||
| * A wrapper that accepts a tuple as arguments. | ||
| * @tparam F A functor with `opertor()(Args&&...)` returning a scalar | ||
| * @tparam Theta A class assignable to an Eigen vector type | ||
| * @tparam TupleArgs Type of arguments for covariance function. | ||
| * @tparam Stream Type of stream for messages. | ||
| * @param f Log likelihood function. | ||
| * @param theta Latent Gaussian model. | ||
| * @param ll_tup Arguments for likelihood function | ||
| * @param msgs stream messages. | ||
| */ | ||
| template <typename F, typename Theta, typename TupleArgs, typename Stream, | ||
| require_eigen_vector_t<Theta>* = nullptr, | ||
| require_tuple_t<TupleArgs>* = nullptr> | ||
| inline auto theta_grad(F&& f, Theta&& theta, TupleArgs&& ll_tup, | ||
| Stream* msgs = nullptr) { | ||
| return apply( | ||
| [](auto&& f, auto&& theta, auto&& msgs, auto&&... args) { | ||
| return internal::theta_grad(std::forward<decltype(f)>(f), | ||
| std::forward<decltype(theta)>(theta), msgs, | ||
| std::forward<decltype(args)>(args)...); | ||
| }, | ||
| std::forward<TupleArgs>(ll_tup), std::forward<F>(f), | ||
| std::forward<Theta>(theta), msgs); | ||
| } | ||
|
|
||
| template <typename F, typename Theta, typename TupleArgs, typename Stream, | ||
| require_eigen_vector_t<Theta>* = nullptr, | ||
| require_tuple_t<TupleArgs>* = nullptr> | ||
| inline auto ll_arg_grad(F&& f, Theta&& theta, TupleArgs&& ll_tup, | ||
| Stream* msgs = nullptr) { | ||
| return apply( | ||
| [](auto&& f, auto&& theta, auto&& msgs, auto&&... args) { | ||
| return internal::ll_arg_grad(std::forward<decltype(f)>(f), | ||
| std::forward<decltype(theta)>(theta), msgs, | ||
| std::forward<decltype(args)>(args)...); | ||
| }, | ||
| std::forward<TupleArgs>(ll_tup), std::forward<F>(f), | ||
| std::forward<Theta>(theta), msgs); | ||
| } | ||
|
|
||
| template <typename F, typename Theta, typename TupleArgs, typename Stream, | ||
| require_eigen_vector_t<Theta>* = nullptr, | ||
| require_tuple_t<TupleArgs>* = nullptr> | ||
| inline auto diagonal_hessian(F&& f, Theta&& theta, TupleArgs&& ll_tuple, | ||
| Stream* msgs) { | ||
| return apply( | ||
| [](auto&& f, auto&& theta, auto* msgs, auto&&... args) { | ||
| return internal::diagonal_hessian( | ||
| std::forward<decltype(f)>(f), std::forward<decltype(theta)>(theta), | ||
| msgs, std::forward<decltype(args)>(args)...); | ||
| }, | ||
| std::forward<TupleArgs>(ll_tuple), std::forward<F>(f), | ||
| std::forward<Theta>(theta), msgs); | ||
| } | ||
|
|
||
| template <typename F, typename Theta, typename TupleArgs, typename Stream, | ||
| require_eigen_vector_t<Theta>* = nullptr, | ||
| require_tuple_t<TupleArgs>* = nullptr> | ||
| inline auto block_hessian(F&& f, Theta&& theta, | ||
| const Eigen::Index hessian_block_size, | ||
| TupleArgs&& ll_tuple, Stream* msgs) { | ||
| return apply( | ||
| [](auto&& f, auto&& theta, auto hessian_block_size, auto* msgs, | ||
| auto&&... args) { | ||
| return internal::block_hessian( | ||
| std::forward<decltype(f)>(f), std::forward<decltype(theta)>(theta), | ||
| hessian_block_size, msgs, std::forward<decltype(args)>(args)...); | ||
| }, | ||
| std::forward<TupleArgs>(ll_tuple), std::forward<F>(f), | ||
| std::forward<Theta>(theta), hessian_block_size, msgs); | ||
| } | ||
|
|
||
| /** | ||
| * A wrapper that accepts a tuple as arguments. | ||
| * @tparam F A functor with `opertor()(Args&&...)` returning a scalar | ||
|
|
||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.