/* nag_mv_gaussian_mixture_ld (g03gbc) Example Program.
*
* Copyright 2023 Numerical Algorithms Group.
*
* Mark 29.2, 2023.
*/
#include <math.h>
#include <nag.h>
#include <stdio.h>
#include <string.h>
int main(void) {
/* Integer scalar and array declarations */
Integer exit_status = 0, i, j, lens, m, n, ng, niter, nvar, riter, tdprob,
pdx, pds, sds, tds, pdf, pdg;
Integer s1, s2, x1, g1, f1;
Integer *isx = 0;
/* Double scalar and array declarations */
double loglik, tol;
double *f = 0, *g = 0, *prob = 0, *s = 0, *w = 0, *x = 0;
/* NAG structures */
Nag_Boolean popt;
Nag_VarCovar sopt;
NagError fail;
/* Character scalar and array declarations */
char nag_enum_popt[30 + 1], nag_enum_sopt[30 + 1];
printf("nag_mv_gaussian_mixture_ld (g03gbc) Example Program Results\n\n");
fflush(stdout);
/* Skip heading in data file */
scanf("%*[^\n] ");
/* Problem size */
scanf("%" NAG_IFMT "", &n);
scanf("%" NAG_IFMT "", &m);
scanf("%" NAG_IFMT "", &nvar);
scanf("%*[^\n] ");
/* Number of groups */
scanf("%" NAG_IFMT "", &ng);
scanf("%*[^\n] ");
/* Scaling option */
scanf("%30s", nag_enum_sopt);
scanf("%*[^\n] ");
/* Initial probabilities option */
scanf("%30s", nag_enum_popt);
scanf("%*[^\n] ");
/* Maximum number of iterations */
scanf("%" NAG_IFMT "", &niter);
scanf("%*[^\n] ");
/* Principal dimensions */
x1 = m;
g1 = ng;
f1 = ng;
pdx = 2*m;
tdprob = ng;
pdf = 2*ng;
pdg = 2*ng;
s1 = nvar;
s2 = nvar;
tds = ng;
/* nag_enum_name_to_value (x04nac).
* Converts NAG enum member name to value
*/
popt = (Nag_Boolean)nag_enum_name_to_value(nag_enum_popt);
sopt = (Nag_VarCovar)nag_enum_name_to_value(nag_enum_sopt);
/* Variance/covariance array */
switch (sopt) {
case Nag_GroupCovar:
break;
case Nag_PooledCovar:
break;
case Nag_GroupVar:
s2 = ng;
break;
case Nag_PooledVar:
s2 = 1;
break;
case Nag_OverallVar:
s1 = 1;
s2 = 1;
break;
}
pds = 2*s1;
sds = 2*s2;
lens = pds*sds*tds;
if (!(x = NAG_ALLOC(n * pdx, double)) ||
!(prob = NAG_ALLOC(n * tdprob, double)) ||
!(g = NAG_ALLOC(pdg * nvar, double)) || !(w = NAG_ALLOC(2*ng, double)) ||
!(isx = NAG_ALLOC(m, Integer)) || !(f = NAG_ALLOC(pdf * n, double)) ||
!(s = NAG_ALLOC(lens, double))) {
printf("Allocation failure\n");
exit_status = -1;
goto END;
}
/* Data matrix X */
for (i = 0; i < n; i++) {
for (j = 0; j < m; j++) {
scanf("%lf", &x[i*pdx+j]);
x[i*pdx+j+m] = x[i*pdx+j];
}
}
scanf("%*[^\n] ");
/* Included variables */
if (nvar != m) {
for (j = 0; j < m; j++)
scanf("%" NAG_IFMT "", &isx[j]);
scanf("%*[^\n] ");
}
/* Optimization parameters */
tol = 0.0;
riter = 5;
/* Fit the model */
/* nag_mv_gaussian_mixture_ld (g03gbc).
* Computes a Gaussian mixture model onto leading submatrices
* First Call using sopt = Nag_GroupCovar and
* popt = Nag_TRUE (probabilities set internally)
*/
INIT_FAIL(fail);
g03gbc(n, m, x, pdx, isx, nvar, ng, Nag_TRUE, prob, tdprob, &niter,
riter, w, g, pdg, Nag_GroupCovar, s, pds, sds, f, pdf, tol, &loglik,
&fail);
if (fail.code != NE_NOERROR) {
printf("nag_mv_gaussian_mixture_ld (g03gbc) failed 1.\n%s\n", fail.message);
exit_status = 1;
goto END;
} else {
printf("First call to nag_mv_gaussian_mixture_ld was successful\n\n");
}
/* Optionally read initial probabilities of group membership */
if (popt == Nag_FALSE) {
for (i = 0; i < n; i++)
for (j = 0; j < ng; j++)
scanf("%lf", &prob[j+i*tdprob]);
scanf("%*[^\n] ");
}
/* Fit the model */
/* nag_mv_gaussian_mixture_ld (g03gbc).
* Computes a Gaussian mixture model onto trailing submatrices
*/
g03gbc(n, m, &x[x1], pdx, isx, nvar, ng, popt, prob, tdprob, &niter, riter,
&w[ng], &g[g1], pdg, sopt, &s[s1+s2*pds], pds, sds, &f[f1], pdf, tol,
&loglik, &fail);
if (fail.code != NE_NOERROR) {
printf("nag_mv_gaussian_mixture_ld (g03gbc) failed 2.\n%s\n", fail.message);
exit_status = 2;
goto END;
}
/* Results (from second call using trailing submatrices) */
/* nag_file_print_matrix_real_gen (x04cac).
* Print real general matrix (easy-to-use)
*/
nag_file_print_matrix_real_gen(Nag_RowMajor, Nag_GeneralMatrix,
Nag_NonUnitDiag, 1, ng, &w[ng], ng,
"Mixing proportions", NULL, &fail);
nag_file_print_matrix_real_gen(Nag_RowMajor, Nag_GeneralMatrix,
Nag_NonUnitDiag, nvar, ng, &g[g1], pdg,
"\n Group means", NULL, &fail);
/* Variance/Covariance */
switch (sopt) {
case Nag_GroupCovar:
for (i = 1; i <= ng; i++) {
nag_file_print_matrix_real_gen(
Nag_RowMajor, Nag_GeneralMatrix, Nag_NonUnitDiag, nvar, nvar,
&s[s1+s2*pds+i*pds*sds], pds, "\n Variance-covariance matrix", NULL,
&fail);
}
break;
case Nag_PooledCovar:
nag_file_print_matrix_real_gen(
Nag_RowMajor, Nag_GeneralMatrix, Nag_NonUnitDiag, nvar, nvar,
&s[s1+s2*pds], pds, "\n Pooled Variance-covariance matrix", NULL,
&fail);
break;
case Nag_GroupVar:
nag_file_print_matrix_real_gen(Nag_RowMajor, Nag_GeneralMatrix,
Nag_NonUnitDiag, nvar, ng, &s[s1+s2*pds],
pds, "\n Groupwise Variance", NULL, &fail);
break;
case Nag_PooledVar:
nag_file_print_matrix_real_gen(Nag_RowMajor, Nag_GeneralMatrix,
Nag_NonUnitDiag, nvar, 1, &s[s1+s2*pds],
pds, "\n Pooled Variance", NULL, &fail);
break;
case Nag_OverallVar:
printf("\n Overall Variance = %g\n", x[s1+s2*pds]);
break;
}
nag_file_print_matrix_real_gen(Nag_RowMajor, Nag_GeneralMatrix,
Nag_NonUnitDiag, n, ng, &f[f1], pdf,
"\n Densities", NULL, &fail);
nag_file_print_matrix_real_gen(Nag_RowMajor, Nag_GeneralMatrix,
Nag_NonUnitDiag, n, ng, prob, tdprob,
"\n Membership probabilities", NULL, &fail);
printf("\nNo. iterations: %" NAG_IFMT "\n", niter);
printf("Log-likelihood: %g\n\n", loglik);
END:
NAG_FREE(f);
NAG_FREE(g);
NAG_FREE(prob);
NAG_FREE(s);
NAG_FREE(w);
NAG_FREE(x);
NAG_FREE(isx);
return exit_status;
}