<commit_before>/*
 * RandomWalkOperator.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.operators;

import dr.inference.model.Bounds;
import dr.inference.model.Parameter;
import dr.inferencexml.operators.RandomWalkOperatorParser;
import dr.math.MathUtils;
import dr.util.Transform;

import java.util.ArrayList;
import java.util.List;

/**
 * A generic random walk operator for use with a multi-dimensional parameters.
 *
 * @author <NAME>
 * @author <NAME>
 * @version $Id: RandomWalkOperator.java,v 1.16 2005/06/14 10:40:34 rambaut Exp $
 */
public class RandomWalkOperator extends AbstractAdaptableOperator {

    public enum BoundaryCondition {
        rejecting,
        reflecting,
        absorbing,
        log,
        logit
    }

    public RandomWalkOperator(Parameter parameter, double windowSize, BoundaryCondition bc, double weight, AdaptationMode mode) {
        this(parameter, null, windowSize, bc, weight, mode);
    }

    public RandomWalkOperator(Parameter parameter, Parameter updateIndex, double windowSize, BoundaryCondition boundaryCondition,
                              double weight, AdaptationMode mode) {
        super(mode);
        this.parameter = parameter;
        this.windowSize = windowSize;
        this.boundaryCondition = boundaryCondition;

        setWeight(weight);
        if (updateIndex != null) {
            updateMap = new ArrayList<Integer>();
            for (int i = 0; i < updateIndex.getDimension(); i++) {
                if (updateIndex.getParameterValue(i) == 1.0)
                    updateMap.add(i);
            }
            updateMapSize=updateMap.size();
        }
    }

    /**
     * @return the parameter this operator acts on.
     */
    public Parameter getParameter() {
        return parameter;
    }

    public final double getWindowSize() {
        return windowSize;
    }

    public final BoundaryCondition getBoundaryCondition() {
        return boundaryCondition;
    }

    /**
     * change the parameter and return the hastings ratio.
     */
    public double doOperation() {

        // a random dimension to perturb
        if (parameter.getDimension() <= 0) {
            throw new RuntimeException("Illegal Dimension");
        }

        int dim;
        if (updateMap == null) {
            dim = MathUtils.nextInt(parameter.getDimension());
        } else {
            dim = updateMap.get(MathUtils.nextInt(updateMapSize));
        }

        // a random point around old value within windowSize * 2
        double draw = (2.0 * MathUtils.nextDouble() - 1.0) * windowSize;

        double oldValue = parameter.getParameterValue(dim);

        final Bounds<Double> bounds = parameter.getBounds();
        final double lower = bounds.getLowerLimit(dim);
        final double upper = bounds.getUpperLimit(dim);

        if (boundaryCondition == BoundaryCondition.logit) {
            // scale oldValue to [0,1]
            double x1 = (oldValue - lower) / (upper - lower);
            // logit transform it, add the draw, inverse transform it
            double x2 = Transform.LOGIT.inverse(Transform.LOGIT.transform(x1) + draw);

            // parameter takes new value scaled back into interval [lower, upper]
            parameter.setParameterValue(dim, (x2 * (upper - lower)) + lower);
            
            // HR is the ratio of Jacobians for the before and after values in interval [0,1]
            return Transform.LOGIT.getLogJacobian(x1) - Transform.LOGIT.getLogJacobian(x2);

        } else if (boundaryCondition == BoundaryCondition.log) {
            // offset oldValue to [0,+Inf]
            double x1 = oldValue - lower;
            // logit transform it, add the draw, inverse transform it
            double x2 = Transform.LOG.inverse(Transform.LOG.transform(x1) + draw);

            // parameter takes new value tranlated back into interval [lower, +Inf]
            parameter.setParameterValue(dim, x2 + lower);

            // HR is the ratio of Jacobians for the before and after values
            return Transform.LOG.getLogJacobian(x1) - Transform.LOG.getLogJacobian(x2);

        } else {
            double newValue = oldValue + draw;
            if (boundaryCondition == BoundaryCondition.reflecting) {
                newValue = reflectValue(newValue, lower, upper);
            } else if (boundaryCondition == BoundaryCondition.absorbing && (newValue < lower || newValue > upper)) {
                return 0.0;
            } else if (boundaryCondition == BoundaryCondition.rejecting && (newValue < lower || newValue > upper)) {
                return Double.NEGATIVE_INFINITY;
            }

            parameter.setParameterValue(dim, newValue);

            return 0.0;
        }

}

    public static double reflectValue(double value, double lower, double upper) {

        double newValue = value;

        if (upper == lower) {
            newValue = upper;
        }
        else if (value < lower) {
            if (Double.isInfinite(upper)) {
                // we are only going to reflect once as the upper bound is at infinity...
                newValue = lower + (lower - value);
            } else {
                double remainder = lower - value;

                double widths = Math.floor(remainder / (upper - lower));
                remainder -= (upper - lower) * widths;

                // even reflections
                if (widths % 2 == 0) {
                    newValue = lower + remainder;
                    // odd reflections
                } else {
                    newValue = upper - remainder;
                }
            }<commit_msg>should have reformatted code in the last commit<commit_after>/*
 * RandomWalkOperator.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.operators;

import dr.inference.model.Bounds;
import dr.inference.model.Parameter;
import dr.inferencexml.operators.RandomWalkOperatorParser;
import dr.math.MathUtils;
import dr.util.Transform;

import java.util.ArrayList;
import java.util.List;

/**
 * A generic random walk operator for use with a multi-dimensional parameters.
 *
 * @author <NAME>
 * @author <NAME>
 * @version $Id: RandomWalkOperator.java,v 1.16 2005/06/14 10:40:34 rambaut Exp $
 */
public class RandomWalkOperator extends AbstractAdaptableOperator {

    public enum BoundaryCondition {
        rejecting,
        reflecting,
        absorbing,
        log,
        logit
    }

    public RandomWalkOperator(Parameter parameter, double windowSize, BoundaryCondition bc, double weight, AdaptationMode mode) {
        this(parameter, null, windowSize, bc, weight, mode);
    }

    public RandomWalkOperator(Parameter parameter, Parameter updateIndex, double windowSize, BoundaryCondition boundaryCondition,
                              double weight, AdaptationMode mode) {
        super(mode);
        this.parameter = parameter;
        this.windowSize = windowSize;
        this.boundaryCondition = boundaryCondition;

        setWeight(weight);
        if (updateIndex != null) {
            updateMap = new ArrayList<Integer>();
            for (int i = 0; i < updateIndex.getDimension(); i++) {
                if (updateIndex.getParameterValue(i) == 1.0)
                    updateMap.add(i);
            }
            updateMapSize=updateMap.size();
        }
    }

    /**
     * @return the parameter this operator acts on.
     */
    public Parameter getParameter() {
        return parameter;
    }

    public final double getWindowSize() {
        return windowSize;
    }

    public final BoundaryCondition getBoundaryCondition() {
        return boundaryCondition;
    }

    /**
     * change the parameter and return the hastings ratio.
     */
    public double doOperation() {

        // a random dimension to perturb
        if (parameter.getDimension() <= 0) {
            throw new RuntimeException("Illegal Dimension");
        }

        int dim;
        if (updateMap == null) {
            dim = MathUtils.nextInt(parameter.getDimension());
        } else {
            dim = updateMap.get(MathUtils.nextInt(updateMapSize));
        }

        // a random point around old value within windowSize * 2
        double draw = (2.0 * MathUtils.nextDouble() - 1.0) * windowSize;

        double oldValue = parameter.getParameterValue(dim);

        final Bounds<Double> bounds = parameter.getBounds();
        final double lower = bounds.getLowerLimit(dim);
        final double upper = bounds.getUpperLimit(dim);

        if (boundaryCondition == BoundaryCondition.logit) {
            // scale oldValue to [0,1]
            double x1 = (oldValue - lower) / (upper - lower);
            // logit transform it, add the draw, inverse transform it
            double x2 = Transform.LOGIT.inverse(Transform.LOGIT.transform(x1) + draw);

            // parameter takes new value scaled back into interval [lower, upper]
            parameter.setParameterValue(dim, (x2 * (upper - lower)) + lower);
            
            // HR is the ratio of Jacobians for the before and after values in interval [0,1]
            return Transform.LOGIT.getLogJacobian(x1) - Transform.LOGIT.getLogJacobian(x2);

        } else if (boundaryCondition == BoundaryCondition.log) {
            // offset oldValue to [0,+Inf]
            double x1 = oldValue - lower;
            // logit transform it, add the draw, inverse transform it
            double x2 = Transform.LOG.inverse(Transform.LOG.transform(x1) + draw);

            // parameter takes new value tranlated back into interval [lower, +Inf]
            parameter.setParameterValue(dim, x2 + lower);

            // HR is the ratio of Jacobians for the before and after values
            return Transform.LOG.getLogJacobian(x1) - Transform.LOG.getLogJacobian(x2);

        } else {
            double newValue = oldValue + draw;
            if (boundaryCondition == BoundaryCondition.reflecting) {
                newValue = reflectValue(newValue, lower, upper);
            } else if (boundaryCondition == BoundaryCondition.absorbing && (newValue < lower || newValue > upper)) {
                return 0.0;
            } else if (boundaryCondition == BoundaryCondition.rejecting && (newValue < lower || newValue > upper)) {
                return Double.NEGATIVE_INFINITY;
            }

            parameter.setParameterValue(dim, newValue);

            return 0.0;
        }

}

    public static double reflectValue(double value, double lower, double upper) {

        double newValue = value;

        if (upper == lower) {
            newValue = upper;
        } else if (value < lower) {
            if (Double.isInfinite(upper)) {
                // we are only going to reflect once as the upper bound is at infinity...
                newValue = lower + (lower - value);
            } else {
                double remainder = lower - value;

                double widths = Math.floor(remainder / (upper - lower));
                remainder -= (upper - lower) * widths;

                // even reflections
                if (widths % 2 == 0) {
                    newValue = lower + remainder;
                    // odd reflections
                } else {
                    newValue = upper - remainder;
                }
            }
{'fraction_non_alphanumeric': 0.08840624044050169, 'fraction_numerical': 0.01055368614255124, 'mean_word_length': 2.184851436921578, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7053338', 'n_tokens_mistral': 3513, 'n_tokens_neox': 3281, 'n_words': 1121}