Skip to content

Implement quantile-based integration ranges in OneFactorCopula family - #2851

Open
Nityahapani wants to merge 1 commit into
lballabio:masterfrom
Nityahapani:fix/onefactorcopula-quantile-based-range
Open

Nityahapani wants to merge 1 commit into
lballabio:masterfrom
Nityahapani:fix/onefactorcopula-quantile-based-range

Conversation

@Nityahapani

Copy link
Copy Markdown

Seven FIXME comments across onefactorcopula.cpp and onefactorstudentcopula.cpp flagged the same problem: hardcoded ±10 integration limits for the Y-table in performCalculations() and for the M/Z grids in cumulativeYintegral(), with a note to derive them from a cutoff quantile instead.

The hardcoded limits are fragile:

  • For fat-tailed Student-t distributions with low degrees of freedom, ±10 may not capture enough tail mass, biasing the computed probabilities.
  • For all distributions, there is no connection between the grid bounds and the actual tails of the marginals, making the quality of the approximation opaque.

Fix: replace every hardcoded bound with a value computed at cutoff = 1e-6 (or 1e-7 for the Z moment check) using the appropriate inverse CDF:

OneFactorStudentCopula (both M and Z are Student-t):
ybound = InverseCumulativeStudent(nm)(1-c)*scaleM
+ InverseCumulativeStudent(nz)(1-c)*scaleZ

OneFactorGaussianStudentCopula (M Gaussian, Z Student-t):
ybound = InverseCumulativeNormal(1-c)
+ InverseCumulativeStudent(nz)(1-c)*scaleZ

OneFactorStudentGaussianCopula (M Student-t, Z Gaussian):
ybound = InverseCumulativeStudent(nm)(1-c)*scaleM
+ InverseCumulativeNormal(1-c)

checkMoments() Z grid: InverseCumulativeNormal(1-1e-7)
checkMoments() Y grid: use the already-computed y_.front()/y_.back()
which now reflect the quantile-based bounds

Also clarify the FIXME comment in conditionalProbability() explaining why p < 1e-10 is guarded (numerical stability of inverseCumulativeY at degenerate tail).

Adds #include for normaldistribution.hpp in onefactorcopula.cpp and studenttdistribution.hpp in onefactorstudentcopula.cpp.

Seven FIXME comments across onefactorcopula.cpp and onefactorstudentcopula.cpp
flagged the same problem: hardcoded ±10 integration limits for the Y-table
in performCalculations() and for the M/Z grids in cumulativeYintegral(), with
a note to derive them from a cutoff quantile instead.

The hardcoded limits are fragile:
- For fat-tailed Student-t distributions with low degrees of freedom, ±10
  may not capture enough tail mass, biasing the computed probabilities.
- For all distributions, there is no connection between the grid bounds and
  the actual tails of the marginals, making the quality of the approximation
  opaque.

Fix: replace every hardcoded bound with a value computed at cutoff = 1e-6
(or 1e-7 for the Z moment check) using the appropriate inverse CDF:

  OneFactorStudentCopula (both M and Z are Student-t):
    ybound = InverseCumulativeStudent(nm)(1-c)*scaleM
           + InverseCumulativeStudent(nz)(1-c)*scaleZ

  OneFactorGaussianStudentCopula (M Gaussian, Z Student-t):
    ybound = InverseCumulativeNormal(1-c)
           + InverseCumulativeStudent(nz)(1-c)*scaleZ

  OneFactorStudentGaussianCopula (M Student-t, Z Gaussian):
    ybound = InverseCumulativeStudent(nm)(1-c)*scaleM
           + InverseCumulativeNormal(1-c)

  checkMoments() Z grid: InverseCumulativeNormal(1-1e-7)
  checkMoments() Y grid: use the already-computed y_.front()/y_.back()
                         which now reflect the quantile-based bounds

Also clarify the FIXME comment in conditionalProbability() explaining
why p < 1e-10 is guarded (numerical stability of inverseCumulativeY at
degenerate tail).

Adds #include for normaldistribution.hpp in onefactorcopula.cpp and
studenttdistribution.hpp in onefactorstudentcopula.cpp.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant