`log_modified_bessel_first_kind` has zero derivatives in the order at v = 0 and v = 1

Ouverte
#3,510 0 commentaires 0 réactions 0 personnes assignées Voir sur GitHub

Les mainteneurs répondent en général sous 1 jour

Personne n'a encore pris cette issue.

Évaluation

Difficulté
3/5
Temps estimé
1-2 jours
Accessibilité débutants
54/100
Type d'issue
Bug
Clarté
Clairement spécifiée
Activité
Active
Stack technique
cpp
Domaine
backend

Piste de recherche

Start with the implementation of log_modified_bessel_first_kind and the source comment about autodiff at v = 0, then inspect the reverse-mode test area under test/unit/math/rev/fun/. The issue proposes checking whether the special-case fits can be limited to non-autodiff orders so autodiff uses the general power series. Add the supplied order-gradient checks at v = 0 and v = 1 and confirm they match the expected values.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Description

AI use disclosure: This was written with the help of Claude Code (Opus 5.5).

Description

For v == 0 and v == 1, log_modified_bessel_first_kind(v, z) evaluates Boost's fits for $I_0$ and $I_1$, which do not depend on v. When v is an autodiff variable, every derivative with respect to v is therefore 0, in reverse and forward mode. The exact first derivative is $-K_0(z)/I_0(z)$ at v = 0 (decaying like $e^{-2z}$) and about $-1/z$ at v = 1 for large z. The source comments acknowledge this ("WARNING: will not autodiff for v = 0 correctly").

A sampler, optimizer or diagnose can start exactly there: with init=0, a real<lower=0> order starts at exp(0) = 1 and a real<lower=-1> order at 0.

do_lkj_constant, the normalizing constant of lkj_corr_lpdf, lkj_corr_cholesky_lpdf and lkj_cov_lpdf, has the same defect at eta == 1.0: develop drops the η-derivatives of the constant there, so the η-gradient keeps only the data term and the second η-derivative is 0. Open PR #3434 fixes this as part of its rewrite: on its head (35435f53dc), the first and second η-derivatives at η = 1 are within 3e-16 of the exact values (K = 2). Its tests have no η = 1 point.

Possible fix: take the two shortcuts only when v is not autodiff (!is_autodiff_v<T1> &&). The test below then passes, and an autodiff order goes through the general power series.

Example

New file test/unit/math/rev/fun/log_modified_bessel_first_kind_test.cpp:

#include <stan/math/rev.hpp>
#include <test/unit/math/rev/util.hpp>
#include <gtest/gtest.h>

TEST_F(AgradRev, log_modified_bessel_first_kind_order_gradient) {
  using stan::math::var;
  auto d_dv = [](double v_val) {
    var v = v_val;
    stan::math::log_modified_bessel_first_kind(v, 0.5).grad();
    double g = v.adj();
    stan::math::recover_memory();
    return g;
  };
  // d/dv log I_v(0.5) from mpmath (50 digits); at v = 0 it is -K_0 / I_0
  EXPECT_NEAR(-0.86923697789771742858, d_dv(0), 1e-12);
  EXPECT_NEAR(-1.8244901560201558681, d_dv(1), 1e-12);
}

It fails on develop:

[ RUN      ] AgradRev.log_modified_bessel_first_kind_order_gradient
d_dv(0) evaluates to 0
d_dv(1) evaluates to 0
[  FAILED  ] AgradRev.log_modified_bessel_first_kind_order_gradient

Expected Output

The order gradient at z = 0.5 is −0.86923697789771743 at v = 0 and −1.8244901560201559 at v = 1 (mpmath).

Current Version:

v5.4.0 (develop at 1f83dc5dc4)

Langage dominant
C++
Étoiles
845
Forks
225
Merge moyen
4 j 21 h
PR mergées (30 j)
13

Préparer son environnement

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Autres issues de stan-dev/math

Toutes les issues de stan-dev/math

Issues similaires

Plus d'issues C++

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.