001    package calhoun.analysis.crf.solver;
002    
003    import java.util.List;
004    
005    import calhoun.analysis.crf.CRFTraining;
006    import calhoun.analysis.crf.ModelManager;
007    import calhoun.analysis.crf.io.TrainingSequence;
008    
009    /** a two pass optimizer that does an initial optimization and then uses the weights generated from that as the start of a second optimization.  It is configured with
010     * two separate CRFOptimizer oibjects for the two passes and additionally needs a CRFObjectiveFunctionGradient for the first pass. 
011     * <p>
012     * This optimizer has two configuration properties that must be set and control the optimization process
013     * <ul>
014     * <li> <b><code>firstPass</code></b> - A reference to a configured {@link CRFTraining} object that will be used to optimize the 
015     * weights in the first pass of the optimization. 
016     * <li> <b><code>secondPass</code></b> - A reference to a configured {@link CRFTraining} object that will be used to optimize the 
017     * weights in the second pass of the optimization.  The second pass will begin using the weights computed during the first
018     *  pass.
019     */
020    public class TwoPassOptimizer implements CRFTraining {
021    
022            CRFTraining firstPass;
023    
024            CRFTraining secondPass;
025    
026            public double[] optimize(ModelManager fm, List<? extends TrainingSequence<?>> data) {
027                    double[] startingWeights = firstPass.optimize(fm, data);
028    
029                    secondPass.setStarts(startingWeights);
030                    return secondPass.optimize(fm, data);
031            }
032    
033            public void setStarts(double[] weights) {
034                    firstPass.setStarts(weights);
035            }
036    
037            /**
038             * @return the firstPass
039             */
040            public CRFTraining getFirstPass() {
041                    return firstPass;
042            }
043    
044            /**
045             * @param firstPass the firstPass to set
046             */
047            public void setFirstPass(CRFTraining firstPass) {
048                    this.firstPass = firstPass;
049            }
050    
051            /**
052             * @return the secondPass
053             */
054            public CRFTraining getSecondPass() {
055                    return secondPass;
056            }
057    
058            /**
059             * @param secondPass the secondPass to set
060             */
061            public void setSecondPass(CRFTraining secondPass) {
062                    this.secondPass = secondPass;
063            }
064    }