/* * Apache License * Version 2.0, January 2004 * http://www.apache.org/licenses/ * * Copyright 2013 Aurelian Tutuianu * Copyright 2014 Aurelian Tutuianu * Copyright 2015 Aurelian Tutuianu * Copyright 2016 Aurelian Tutuianu * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package rapaio.experiment.math.regression; /** * Taken from * <p> * http://tullo.ch/articles/speeding-up-isotonic-regression/ * <p> * and translated to java * <p> * Created by <a href="mailto:padreati@yahoo.com">Aurelian Tutuianu</a> on 2/5/16. */ public class IsotonicRegression { public double[] isotonic_regression(double[] y, double[] weight) { double[] solution = new double[y.length]; double numerator, denominator; int i, pooled, n, k; n = y.length; // The algorithm proceeds by iteratively updating the solution array. for (i = 0; i < n; i++) solution[i] = y[i]; if (n <= 1) return solution; n -= 1; while (true) { // repeat until there are no more adjacent violators. i = 0; pooled = 0; while (i < n) { k = i; while (k < n && solution[k] >= solution[k + 1]) k += 1; if (solution[i] != solution[k]) { // solution[i:k + 1] is a decreasing subsequence, so // replace each point in the subsequence with the // weighted average of the subsequence. numerator = 0.0; denominator = 0.0; for (int j = i; j < k + 1; j++) { numerator += solution[j] * weight[j]; denominator += weight[j]; } for (int j = i; j < k + 1; j++) solution[j] = numerator / denominator; pooled = 1; } i = k + 1; } // Check for convergence if (pooled == 0) break; } return solution; } }