<commit_before>/*
 * MultiDimensionalScalingMM.java
 *
 * Copyright (c) 2002-2015 <NAME>, <NAME> and <NAME>
 *
 * This file is part of BEAST.
 * See the NOTICE file distributed with this work for additional
 * information regarding copyright ownership and licensing.
 *
 * BEAST is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 *  BEAST 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 Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with BEAST; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA  02110-1301  USA
 */

package dr.inference.multidimensionalscaling.mm;

import dr.inference.multidimensionalscaling.MultiDimensionalScalingLikelihood;
import dr.inference.model.MatrixParameterInterface;
import dr.inference.operators.EllipticalSliceOperator;
import dr.math.distributions.GaussianProcessRandomGenerator;
import dr.xml.*;

/**
 * Created by msuchard on 12/15/15.
 */
public class MultiDimensionalScalingMM extends MMAlgorithm {

    private final MultiDimensionalScalingLikelihood likelihood;
    private final GaussianProcessRandomGenerator gp;

    private final int P; // Embedding dimension
    private final int Q; // Data dimension

    private double[] XtX = null;
    private double[] D = null;
    private double[] distance = null;

    final private double tolerance;

    public MultiDimensionalScalingLikelihood getLikelihood() { return likelihood; }

    public GaussianProcessRandomGenerator getGaussianProcess() { return gp; }

    public MultiDimensionalScalingMM(MultiDimensionalScalingLikelihood likelihood,
                                     GaussianProcessRandomGenerator gp,
                                     double tolerance) {
        super();

        this.likelihood = likelihood;
        this.gp = gp;

        this.P = likelihood.getMdsDimension();
        this.Q = likelihood.getLocationCount();

        this.tolerance = tolerance;
    }

    public void run() {

        if (gp != null) {
            double[][] precision = gp.getPrecisionMatrix();
            setPrecision(precision);
        }

//        System.err.println("");

//        System.err.println("weight: " + 1.0 / likelihood.getMDSPrecision());
        weightTree =  1.0 / likelihood.getMDSPrecision();

        double[] start = likelihood.getMatrixParameter().getParameterValues();

        System.err.println("Start: " + printArray(start));
        double penaltyStart = printLogObjective();

//        EllipticalSliceOperator.transformPoint(mode, true, true, P);
//        setParameterValues(likelihood.getMatrixParameter(), mode);
//        printLogObjective();

        double[] mode = null;

        try {
            mode = findMode(likelihood.getMatrixParameter().getParameterValues(),
                    tolerance, 100000);

        } catch (NotConvergedException e) {
            e.printStackTrace();
        }

//        System.err.println("Final: " + printArray(mode));

        setParameterValues(likelihood.getMatrixParameter(), mode);
        double penaltyEnd = printLogObjective();
//
//        if (penaltyStart - penaltyEnd > 1E-1) {

//        if (penaltyEnd < penaltyStart) {
//            throw new RuntimeException("MM moved up-hill\n\tStart: " + penaltyStart + "\n\tEnd  : " + penaltyEnd);
//            System.err.println("Revert:  MM moved up-hill?");
//            setParameterValues(likelihood.getMatrixParameter(), start);
//            double penaltyRevert = printLogObjective();
//            System.err.println("End: " + penaltyEnd);
//            System.err.println("revert : " + penaltyRevert);
           // throw new RuntimeException("out");
//
//        }

//        EllipticalSliceOperator.transformPoint(mode, true, true, P);
//
//        System.err.println("Final: " + printArray(mode));
//
//        setParameterValues(likelihood.getMatrixParameter(), mode);
//        printLogObjective();

        throw new RuntimeException("done");
    }

    private double printLogObjective() {
        double logLike = likelihood.getLogLikelihood();
        double logPenalty = gp.getLikelihood().getLogLikelihood();
        double total = logLike;
        if (weightTree != 0.0) {
            total += logPenalty;
        }
        System.err.println("obj: " + total + " = " + logLike + " + " + logPenalty);
//        return logPenalty;
        return total;
    }

    private void setParameterValues(MatrixParameterInterface mat, double[] values) {

//        for (int i = 0; i < values.length; ++i) {
//            mat.setValue(i, values[i]);
//        }
        mat.setAllParameterValuesQuietly(values, 0);
        mat.setParameterValueNotifyChangedAll(0, 0, values[0]); // Fire changed<commit_msg>use mode finder for intiial value<commit_after>/*
 * MultiDimensionalScalingMM.java
 *
 * Copyright (c) 2002-2015 <NAME>, <NAME> and <NAME>
 *
 * This file is part of BEAST.
 * See the NOTICE file distributed with this work for additional
 * information regarding copyright ownership and licensing.
 *
 * BEAST is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 *  BEAST 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 Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with BEAST; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA  02110-1301  USA
 */

package dr.inference.multidimensionalscaling.mm;

import dr.inference.multidimensionalscaling.MultiDimensionalScalingLikelihood;
import dr.inference.model.MatrixParameterInterface;
import dr.inference.operators.EllipticalSliceOperator;
import dr.math.distributions.GaussianProcessRandomGenerator;
import dr.xml.*;

/**
 * Created by msuchard on 12/15/15.
 */
public class MultiDimensionalScalingMM extends MMAlgorithm {

    private final MultiDimensionalScalingLikelihood likelihood;
    private final GaussianProcessRandomGenerator gp;

    private final int P; // Embedding dimension
    private final int Q; // Data dimension

    private double[] XtX = null;
    private double[] D = null;
    private double[] distance = null;

    final private double tolerance;

    public MultiDimensionalScalingLikelihood getLikelihood() { return likelihood; }

    public GaussianProcessRandomGenerator getGaussianProcess() { return gp; }

    public MultiDimensionalScalingMM(MultiDimensionalScalingLikelihood likelihood,
                                     GaussianProcessRandomGenerator gp,
                                     double tolerance) {
        super();

        this.likelihood = likelihood;
        this.gp = gp;

        this.P = likelihood.getMdsDimension();
        this.Q = likelihood.getLocationCount();

        this.tolerance = tolerance;
    }

    public void run() {

        if (gp != null) {
            double[][] precision = gp.getPrecisionMatrix();
            setPrecision(precision);
        }

//        System.err.println("");

//        System.err.println("weight: " + 1.0 / likelihood.getMDSPrecision());
        weightTree =  1.0 / likelihood.getMDSPrecision();

        double[] start = likelihood.getMatrixParameter().getParameterValues();

        System.err.println("Start: " + printArray(start));
        double penaltyStart = printLogObjective();

//        EllipticalSliceOperator.transformPoint(mode, true, true, P);
//        setParameterValues(likelihood.getMatrixParameter(), mode);
//        printLogObjective();

        double[] mode = null;

        try {
            mode = findMode(likelihood.getMatrixParameter().getParameterValues(),
                    tolerance, 100000);

        } catch (NotConvergedException e) {
            e.printStackTrace();
        }

//        System.err.println("Final: " + printArray(mode));

        setParameterValues(likelihood.getMatrixParameter(), mode);
        double penaltyEnd = printLogObjective();
//
//        if (penaltyStart - penaltyEnd > 1E-1) {

//        if (penaltyEnd < penaltyStart) {
//            throw new RuntimeException("MM moved up-hill\n\tStart: " + penaltyStart + "\n\tEnd  : " + penaltyEnd);
//            System.err.println("Revert:  MM moved up-hill?");
//            setParameterValues(likelihood.getMatrixParameter(), start);
//            double penaltyRevert = printLogObjective();
//            System.err.println("End: " + penaltyEnd);
//            System.err.println("revert : " + penaltyRevert);
           // throw new RuntimeException("out");
//
//        }

//        EllipticalSliceOperator.transformPoint(mode, true, true, P);
//
//        System.err.println("Final: " + printArray(mode));
//
//        setParameterValues(likelihood.getMatrixParameter(), mode);
//        printLogObjective();

//        throw new RuntimeException("done");
    }

    private double printLogObjective() {
        double logLike = likelihood.getLogLikelihood();
        double logPenalty = gp.getLikelihood().getLogLikelihood();
        double total = logLike;
        if (weightTree != 0.0) {
            total += logPenalty;
        }
        System.err.println("obj: " + total + " = " + logLike + " + " + logPenalty);
//        return logPenalty;
        return total;
    }

    private void setParameterValues(MatrixParameterInterface mat, double[] values) {

//        for (int i = 0; i < values.length; ++i) {
//            mat.setValue(i, values[i]);
//        }
        mat.setAllParameterValuesQuietly(values, 0);
        mat.setParameterValueNotifyChangedAll(0, 0, values[0]); // Fire changed
{'fraction_non_alphanumeric': 0.10676017923241769, 'fraction_numerical': 0.008766803039158387, 'mean_word_length': 2.7118582791033985, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3635666', 'n_tokens_mistral': 2842, 'n_tokens_neox': 2693, 'n_words': 746}