package de.lmu.ifi.dbs.elki.math.linearalgebra.pca; /* This file is part of ELKI: Environment for Developing KDD-Applications Supported by Index-Structures Copyright (C) 2011 Ludwig-Maximilians-Universität München Lehr- und Forschungseinheit für Datenbanksysteme ELKI Development Team This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ import java.util.ArrayList; import java.util.List; import de.lmu.ifi.dbs.elki.logging.Logging; import de.lmu.ifi.dbs.elki.math.linearalgebra.EigenPair; import de.lmu.ifi.dbs.elki.math.linearalgebra.SortedEigenPairs; import de.lmu.ifi.dbs.elki.utilities.documentation.Description; import de.lmu.ifi.dbs.elki.utilities.documentation.Title; import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID; import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.GreaterEqualConstraint; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter; /** * The FirstNEigenPairFilter marks the n highest eigenpairs as strong * eigenpairs, where n is a user specified number. * * @author Elke Achtert */ // todo parameter comments @Title("First n Eigenpair filter") @Description("Sorts the eigenpairs in decending order of their eigenvalues and marks the first n eigenpairs as strong eigenpairs.") public class FirstNEigenPairFilter implements EigenPairFilter { /** * The logger for this class. */ private static final Logging logger = Logging.getLogger(FirstNEigenPairFilter.class); /** * Paremeter n */ public static final OptionID EIGENPAIR_FILTER_N = OptionID.getOrCreateOptionID("pca.filter.n", "The number of strong eigenvectors: n eigenvectors with the n highest" + "eigenvalues are marked as strong eigenvectors."); /** * The threshold for strong eigenvectors: n eigenvectors with the n highest * eigenvalues are marked as strong eigenvectors. */ private int n; /** * Constructor. * * @param n */ public FirstNEigenPairFilter(int n) { super(); this.n = n; } @Override public FilteredEigenPairs filter(SortedEigenPairs eigenPairs) { StringBuffer msg = new StringBuffer(); if(logger.isDebugging()) { msg.append("sortedEigenPairs ").append(eigenPairs.toString()); msg.append("\nn = ").append(n); } // init strong and weak eigenpairs List strongEigenPairs = new ArrayList(); List weakEigenPairs = new ArrayList(); // determine strong and weak eigenpairs for(int i = 0; i < eigenPairs.size(); i++) { EigenPair eigenPair = eigenPairs.getEigenPair(i); if(i < n) { strongEigenPairs.add(eigenPair); } else { weakEigenPairs.add(eigenPair); } } if(logger.isDebugging()) { msg.append("\nstrong EigenPairs = ").append(strongEigenPairs); msg.append("\nweak EigenPairs = ").append(weakEigenPairs); logger.debugFine(msg.toString()); } return new FilteredEigenPairs(weakEigenPairs, strongEigenPairs); } /** * Parameterization class. * * @author Erich Schubert * * @apiviz.exclude */ public static class Parameterizer extends AbstractParameterizer { /** * The number of eigenpairs to keep. */ protected int n = 0; @Override protected void makeOptions(Parameterization config) { super.makeOptions(config); IntParameter nP = new IntParameter(EIGENPAIR_FILTER_N, new GreaterEqualConstraint(0)); if(config.grab(nP)) { n = nP.getValue(); } } @Override protected FirstNEigenPairFilter makeInstance() { return new FirstNEigenPairFilter(n); } } }