예제 #1
0
파일: PCA.cpp 프로젝트: PaulBoersma/praat
double PCA_and_TableOfReal_getFractionVariance (PCA me, TableOfReal thee, long from, long to) {
	try {
		double fraction = NUMundefined;

		if (from < 1 || from > to || to > thy numberOfColumns) {
			return NUMundefined;
		}

		autoSSCP s = TableOfReal_to_SSCP (thee, 0, 0, 0, 0);
		autoSSCP sp = Eigen_and_SSCP_project (me, s.get());
		fraction = SSCP_getFractionVariation (sp.get(), from, to);
		return fraction;
	} catch (MelderError) {
		return NUMundefined;
	}
}
예제 #2
0
autoDiscriminant TableOfReal_to_Discriminant (TableOfReal me) {
    try {
        autoDiscriminant thee = Thing_new (Discriminant);
        long dimension = my numberOfColumns;

        if (! NUMdmatrix_hasFiniteElements(my data, 1, my numberOfRows, 1, my numberOfColumns)) {
            Melder_throw (U"At least one of the table's elements is not finite or undefined.");
        }

        if (! TableOfReal_hasRowLabels (me)) {
            Melder_throw (U"At least one of the rows has no label.");
        }

        autoTableOfReal mew = TableOfReal_sortOnlyByRowLabels (me);
        if (! TableOfReal_hasColumnLabels (mew.get())) {
            TableOfReal_setSequentialColumnLabels (mew.get(), 0, 0, U"c", 1, 1);
        }

        thy groups = TableOfReal_to_SSCPList_byLabel (mew.get());
        thy total = TableOfReal_to_SSCP (mew.get(), 0, 0, 0, 0);

        if ((thy numberOfGroups = thy groups -> size) < 2) {
            Melder_throw (U"Number of groups must be greater than one.");
        }

        TableOfReal_centreColumns_byRowLabel (mew.get());

        // Overall centroid and apriori probabilities and costs.

        autoNUMvector<double> centroid (1, dimension);
        autoNUMmatrix<double> between (1, thy numberOfGroups, 1, dimension);
        thy aprioriProbabilities = NUMvector<double> (1, thy numberOfGroups);
        thy costs = NUMmatrix<double> (1, thy numberOfGroups, 1, thy numberOfGroups);

        double sum = 0, scale;
        for (long k = 1; k <= thy numberOfGroups; k ++) {
            SSCP m = thy groups->at [k];
            sum += scale = SSCP_getNumberOfObservations (m);
            for (long j = 1; j <= dimension; j ++) {
                centroid [j] += scale * m -> centroid [j];
            }
        }

        for	(long j = 1; j <= dimension; j ++) {
            centroid [j] /= sum;
        }

        for (long k = 1; k <= thy numberOfGroups; k ++) {
            SSCP m = thy groups->at [k];
            scale = SSCP_getNumberOfObservations (m);
            thy aprioriProbabilities[k] = scale / my numberOfRows;
            for (long j = 1; j <= dimension; j ++) {
                between [k] [j] = sqrt (scale) * (m -> centroid [j] - centroid [j]);
            }
        }

        // We need to solve B'B.x = lambda W'W.x, where B'B and W'W are the between and within covariance matrices.
        // We do not calculate these covariance matrices directly from the data but instead use the GSVD to solve for
        // the eigenvalues and eigenvectors of the equation.

        thy eigen = Thing_new (Eigen);
        Eigen_initFromSquareRootPair (thy eigen.get(), between.peek(), thy numberOfGroups, dimension, mew -> data, my numberOfRows);

        // Default priors and costs

        for (long igroup = 1; igroup <= thy numberOfGroups; igroup ++) {
            for (long jgroup = igroup + 1; jgroup <= thy numberOfGroups; jgroup ++) {
                thy costs [igroup] [jgroup] = thy costs [jgroup] [igroup] = 1.0;
            }
        }
        return thee;
    } catch (MelderError) {
        Melder_throw (me, U": Discriminant not created.");
    }
}