25package umontreal.ssj.probdistmulti;
27import umontreal.ssj.util.Num;
47 private static final double LOGMIN = -709.1;
48 protected double[] alpha;
50 private static class Optim
implements Uncmin_methods {
55 public Optim(
double[] logP,
int n) {
58 this.logP =
new double[k];
59 System.arraycopy(logP, 0, this.logP, 0, k);
62 public double f_to_minimize(
double[] alpha) {
63 double sumAlpha = 0.0;
64 double sumLnGammaAlpha = 0.0;
65 double sumAlphaLnP = 0.0;
67 for (
int i = 1; i < alpha.length; i++) {
73 sumAlphaLnP += ((alpha[i] - 1.0) * logP[i - 1]);
76 return (-n * (
Num.
lnGamma(sumAlpha) - sumLnGammaAlpha + sumAlphaLnP));
79 public void gradient(
double[] alpha,
double[] g) {
82 public void hessian(
double[] alpha,
double[][] h) {
86 public DirichletDist(
double[] alpha) {
91 return density_(alpha, x);
95 return getMean_(alpha);
99 return getCovariance_(alpha);
103 return getCorrelation_(alpha);
106 private static void verifParam(
double[] alpha) {
108 for (
int i = 0; i < alpha.length; i++) {
110 throw new IllegalArgumentException(
"alpha[" + i +
"] <= 0");
114 private static double density_(
double[] alpha,
double[] x) {
116 double sumLnGamma = 0.0;
117 double sumAlphaLnXi = 0.0;
119 if (alpha.length != x.length)
120 throw new IllegalArgumentException(
"alpha and x must have the same dimension");
122 for (
int i = 0; i < alpha.length; i++) {
124 sumLnGamma += Num.lnGamma(alpha[i]);
125 if (x[i] <= 0.0 || x[i] >= 1.0)
127 sumAlphaLnXi += (alpha[i] - 1.0) * Math.log(x[i]);
130 return Math.exp(Num.lnGamma(alpha0) - sumLnGamma + sumAlphaLnXi);
138 public static double density(
double[] alpha,
double[] x) {
140 return density_(alpha, x);
143 private static double[][] getCovariance_(
double[] alpha) {
144 double[][] cov =
new double[alpha.length][alpha.length];
147 for (
int i = 0; i < alpha.length; i++)
150 for (
int i = 0; i < alpha.length; i++) {
151 for (
int j = 0; j < alpha.length; j++)
152 cov[i][j] = -(alpha[i] * alpha[j]) / (alpha0 * alpha0 * (alpha0 + 1.0));
154 cov[i][i] = (alpha[i] / alpha0) * (1.0 - alpha[i] / alpha0) / (alpha0 + 1.0);
167 return getCovariance_(alpha);
170 private static double[][] getCorrelation_(
double[] alpha) {
171 double corr[][] =
new double[alpha.length][alpha.length];
174 for (
int i = 0; i < alpha.length; i++)
177 for (
int i = 0; i < alpha.length; i++) {
178 for (
int j = 0; j < alpha.length; j++)
179 corr[i][j] = -Math.sqrt((alpha[i] * alpha[j]) / ((alpha0 - alpha[i]) * (alpha0 - alpha[j])));
191 return getCorrelation_(alpha);
214 public static double[]
getMLE(
double[][] x,
int n,
int d) {
216 throw new IllegalArgumentException(
"n <= 0");
218 throw new IllegalArgumentException(
"d <= 0");
220 double[] logP =
new double[d];
221 double mean[] =
new double[d];
222 double var[] =
new double[d];
225 for (i = 0; i < d; i++) {
230 for (i = 0; i < n; i++) {
231 for (j = 0; j < d; j++) {
233 logP[j] += Math.log(x[i][j]);
240 for (i = 0; i < d; i++) {
241 logP[i] /= (double) n;
242 mean[i] /= (double) n;
246 for (j = 0; j < d; j++) {
248 for (i = 0; i < n; i++)
249 sum += (x[i][j] - mean[j]) * (x[i][j] - mean[j]);
250 var[j] = sum / (double) n;
253 double alpha0 = (mean[0] * (1.0 - mean[0])) / var[0] - 1.0;
254 Optim system =
new Optim(logP, n);
256 double[] parameters =
new double[d];
257 double[] xpls =
new double[d + 1];
258 double[] alpha =
new double[d + 1];
259 double[] fpls =
new double[d + 1];
260 double[] gpls =
new double[d + 1];
261 int[] itrcmd =
new int[2];
262 double[][] a =
new double[d + 1][d + 1];
263 double[] udiag =
new double[d + 1];
265 for (i = 1; i <= d; i++)
266 alpha[i] = mean[i - 1] * alpha0;
268 Uncmin_f77.optif0_f77(d, alpha, system, xpls, fpls, gpls, itrcmd, a, udiag);
270 for (i = 0; i < d; i++)
271 parameters[i] = xpls[i + 1];
276 private static double[] getMean_(
double[] alpha) {
278 double[] mean =
new double[alpha.length];
280 for (
int i = 0; i < alpha.length; i++)
283 for (
int i = 0; i < alpha.length; i++)
284 mean[i] = alpha[i] / alpha0;
295 public static double[]
getMean(
double[] alpha) {
297 return getMean_(alpha);
318 this.dimension = alpha.length;
319 this.alpha =
new double[dimension];
320 for (
int i = 0; i < dimension; i++) {
322 throw new IllegalArgumentException(
"alpha[" + i +
"] <= 0");
323 this.alpha[i] = alpha[i];
Classes implementing continuous multi-dimensional distributions should inherit from this class.
double[][] getCorrelation()
Returns the correlation matrix of the distribution, defined as.
static double[] getMean(double[] alpha)
Computes the mean of the Dirichlet distribution with parameters ( , …, ), where.
double density(double[] x)
Returns , the probability density of evaluated at the point , where .
static double[][] getCovariance(double[] alpha)
Computes the covariance matrix of the Dirichlet distribution with parameters ( , …,...
void setParams(double[] alpha)
Sets the parameters ( , …, ) of this object.
static double density(double[] alpha, double[] x)
Computes the density ( fDirichlet ) of the Dirichlet distribution with parameters ( ,...
static double[] getMLE(double[][] x, int n, int d)
Estimates the parameters [ ] of the Dirichlet distribution using the maximum likelihood method.
double[] getAlpha()
Returns the parameters ( , …, ) of this object.
double[][] getCovariance()
Returns the variance-covariance matrix of the distribution, defined as .
double getAlpha(int i)
Returns the th component of the alpha vector.
double[] getMean()
Returns the mean vector of the distribution, defined as .
static double[][] getCorrelation(double[] alpha)
Computes the correlation matrix of the Dirichlet distribution with parameters ( , …,...
This class provides various constants and methods to compute numerical quantities such as factorials,...
static double lnGamma(double x)
Returns the natural logarithm of the gamma function evaluated at x.