|
14 | 14 | import sys as _sys
|
15 | 15 | import time as _time
|
16 | 16 | import pathlib as _pathlib
|
| 17 | +import warnings as _warnings |
17 | 18 |
|
18 | 19 | import numpy as _np
|
19 | 20 |
|
@@ -557,6 +558,8 @@ def lsvec(self, probs, counts, total_counts, freqs, intermediates=None):
|
557 | 558 | """
|
558 | 559 | return _np.sqrt(self.terms(probs, counts, total_counts, freqs, intermediates))
|
559 | 560 |
|
| 561 | + # Infinite loop in evaluation of "dterms" and "dlsvec". |
| 562 | + |
560 | 563 | def dterms(self, probs, counts, total_counts, freqs, intermediates=None):
|
561 | 564 | """
|
562 | 565 | Compute the derivatives of the terms of this objective function.
|
@@ -591,8 +594,9 @@ def dterms(self, probs, counts, total_counts, freqs, intermediates=None):
|
591 | 594 | """
|
592 | 595 | if intermediates is None:
|
593 | 596 | intermediates = self._intermediates(probs, counts, total_counts, freqs)
|
594 |
| - return 2 * self.lsvec(probs, counts, total_counts, freqs, intermediates) \ |
595 |
| - * self.dlsvec(probs, counts, total_counts, freqs, intermediates) |
| 597 | + u = self.lsvec(probs, counts, total_counts, freqs, intermediates) |
| 598 | + v = self.dlsvec(probs, counts, total_counts, freqs, intermediates) |
| 599 | + return 2 * u * v |
596 | 600 |
|
597 | 601 | def dlsvec(self, probs, counts, total_counts, freqs, intermediates=None):
|
598 | 602 | """
|
@@ -2753,35 +2757,37 @@ def zero_freq_hterms(self, total_counts, probs):
|
2753 | 2757 | return 2 * _np.ones(len(probs))
|
2754 | 2758 |
|
2755 | 2759 |
|
2756 |
| -# The log(Likelihood) within the Poisson picture is: # noqa |
2757 |
| -# # noqa |
2758 |
| -# L = prod_{i,sl} lambda_{i,sl}^N_{i,sl} e^{-lambda_{i,sl}} / N_{i,sl}! # noqa |
2759 |
| -# # noqa |
2760 |
| -# Where lamba_{i,sl} := p_{i,sl}*N[i] is a rate, i indexes the operation sequence, # noqa |
2761 |
| -# and sl indexes the spam label. N[i] is the total counts for the i-th circuit, and # noqa |
2762 |
| -# so sum_{sl} N_{i,sl} == N[i]. We can ignore the p-independent N_j! and take the log: # noqa |
2763 |
| -# # noqa |
2764 |
| -# log L = sum_{i,sl} N_{i,sl} log(N[i]*p_{i,sl}) - N[i]*p_{i,sl} # noqa |
2765 |
| -# = sum_{i,sl} N_{i,sl} log(p_{i,sl}) - N[i]*p_{i,sl} (where we ignore the p-independent log(N[i]) terms) # noqa |
2766 |
| -# # noqa |
2767 |
| -# The objective function computes the negative log(Likelihood) as a vector of leastsq # noqa |
2768 |
| -# terms, where each term == sqrt( N_{i,sl} * -log(p_{i,sl}) + N[i] * p_{i,sl} ) # noqa |
2769 |
| -# # noqa |
2770 |
| -# See LikelihoodFunctions.py for details on patching # noqa |
2771 |
| -# The log(Likelihood) within the standard picture is: |
2772 |
| -# |
2773 |
| -# L = prod_{i,sl} p_{i,sl}^N_{i,sl} |
2774 |
| -# |
2775 |
| -# Where i indexes the operation sequence, and sl indexes the spam label. |
2776 |
| -# N[i] is the total counts for the i-th circuit, and |
2777 |
| -# so sum_{sl} N_{i,sl} == N[i]. We take the log: |
2778 |
| -# |
2779 |
| -# log L = sum_{i,sl} N_{i,sl} log(p_{i,sl}) |
2780 |
| -# |
2781 |
| -# The objective function computes the negative log(Likelihood) as a vector of leastsq |
2782 |
| -# terms, where each term == sqrt( N_{i,sl} * -log(p_{i,sl}) ) |
2783 |
| -# |
2784 |
| -# See LikelihoodFunction.py for details on patching |
| 2760 | +""" |
| 2761 | +The log(Likelihood) within the Poisson picture is: # noqa |
| 2762 | + # noqa |
| 2763 | +L = prod_{i,sl} lambda_{i,sl}^N_{i,sl} e^{-lambda_{i,sl}} / N_{i,sl}! # noqa |
| 2764 | + # noqa |
| 2765 | +Where lamba_{i,sl} := p_{i,sl}*N[i] is a rate, i indexes the operation sequence, # noqa |
| 2766 | + and sl indexes the spam label. N[i] is the total counts for the i-th circuit, and # noqa |
| 2767 | + so sum_{sl} N_{i,sl} == N[i]. We can ignore the p-independent N_j! and take the log: # noqa |
| 2768 | + # noqa |
| 2769 | +log L = sum_{i,sl} N_{i,sl} log(N[i]*p_{i,sl}) - N[i]*p_{i,sl} # noqa |
| 2770 | + = sum_{i,sl} N_{i,sl} log(p_{i,sl}) - N[i]*p_{i,sl} (where we ignore the p-independent log(N[i]) terms) # noqa |
| 2771 | + # noqa |
| 2772 | +The objective function computes the negative log(Likelihood) as a vector of leastsq # noqa |
| 2773 | + terms, where each term == sqrt( N_{i,sl} * -log(p_{i,sl}) + N[i] * p_{i,sl} ) # noqa |
| 2774 | + # noqa |
| 2775 | +See LikelihoodFunctions.py for details on patching # noqa |
| 2776 | +The log(Likelihood) within the standard picture is: |
| 2777 | +
|
| 2778 | +L = prod_{i,sl} p_{i,sl}^N_{i,sl} |
| 2779 | +
|
| 2780 | +Where i indexes the operation sequence, and sl indexes the spam label. |
| 2781 | + N[i] is the total counts for the i-th circuit, and |
| 2782 | + so sum_{sl} N_{i,sl} == N[i]. We take the log: |
| 2783 | +
|
| 2784 | +log L = sum_{i,sl} N_{i,sl} log(p_{i,sl}) |
| 2785 | +
|
| 2786 | +The objective function computes the negative log(Likelihood) as a vector of leastsq |
| 2787 | + terms, where each term == sqrt( N_{i,sl} * -log(p_{i,sl}) ) |
| 2788 | +
|
| 2789 | +See LikelihoodFunction.py for details on patching |
| 2790 | +""" |
2785 | 2791 | class RawPoissonPicDeltaLogLFunction(RawObjectiveFunction):
|
2786 | 2792 | """
|
2787 | 2793 | The function `N*f*log(f/p) - N*(f-p)`.
|
@@ -4018,6 +4024,9 @@ def __init__(self, regularization=None,
|
4018 | 4024 | resource_alloc=None, name='tvd', description="Total Variational Distance (TVD)", verbosity=0):
|
4019 | 4025 | super().__init__(regularization, resource_alloc, name, description, verbosity)
|
4020 | 4026 |
|
| 4027 | + def chi2k_distributed_qty(self, objective_function_value): |
| 4028 | + return -1 |
| 4029 | + |
4021 | 4030 | def terms(self, probs, counts, total_counts, freqs, intermediates=None):
|
4022 | 4031 | """
|
4023 | 4032 | Compute the terms of the objective function.
|
@@ -4083,7 +4092,11 @@ def dterms(self, probs, counts, total_counts, freqs, intermediates=None):
|
4083 | 4092 | numpy.ndarray
|
4084 | 4093 | A 1D array of length equal to that of each array argument.
|
4085 | 4094 | """
|
4086 |
| - raise NotImplementedError("Derivatives not implemented for TVD yet!") |
| 4095 | + _warnings.warn('This derivative is discontinuous and does not return a full subgradient.') |
| 4096 | + t = self.terms(probs, counts, total_counts, freqs, intermediates) |
| 4097 | + d = 0.5*_np.ones_like(t) |
| 4098 | + d[t < 0] *= -1 |
| 4099 | + return d |
4087 | 4100 |
|
4088 | 4101 | def hterms(self, probs, counts, total_counts, freqs, intermediates=None):
|
4089 | 4102 | """
|
|
0 commit comments