All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.github.msdk.featdet.ADAP3D.common.algorithms.Math Maven / Gradle / Ivy

There is a newer version: 0.0.27
Show newest version
/*
 * (C) Copyright 2015-2017 by MSDK Development Team
 *
 * This software is dual-licensed under either
 *
 * (a) the terms of the GNU Lesser General Public License version 2.1 as published by the Free
 * Software Foundation
 *
 * or (per the licensee's choosing)
 *
 * (b) the terms of the Eclipse Public License v1.0 as published by the Eclipse Foundation.
 */
package io.github.msdk.featdet.ADAP3D.common.algorithms;

import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.NavigableMap;
import java.util.NoSuchElementException;
import java.util.SortedSet;
import java.util.TreeMap;
import java.util.TreeSet;

/**
 * This class contains mathematical functions
 *
 * @author aleksandrsmirnov Modified by Dharak Shah to include in MSDK
 */
public class Math {

  /**
   * 

* interpolate. *

* * @param x_values a {@link java.util.SortedSet} object. * @param y_values a {@link java.util.NavigableMap} object. * @return an array of double. */ static public double[] interpolate(final SortedSet x_values, final NavigableMap y_values) { double[] result = new double[x_values.size()]; int index = 0; final Map.Entry firstEntry = y_values.firstEntry(); Iterator> it = y_values.entrySet().iterator(); Map.Entry entry = it.next(); for (double x : x_values) { // Loop over y_values until we find x while (entry.getKey() < x && it.hasNext()) entry = it.next(); // Get y-value and interpolate if necessary double key = entry.getKey(); if (key == x) // y_values contains x result[index++] = entry.getValue(); else if (entry.equals(firstEntry)) // x is less the any in y_values index++; else if (x < key) { // Interpolate Map.Entry prevEntry = y_values.lowerEntry(key); result[index++] = (entry.getValue() - prevEntry.getValue()) / (entry.getKey() - prevEntry.getKey()) * (x - prevEntry.getKey()) + prevEntry.getValue(); } else index++; } return result; } /** *

* interpolate. *

* * @param x_value a double. * @param y_values a {@link java.util.NavigableMap} object. * @return a double. */ static public double interpolate(final double x_value, final NavigableMap y_values) { SortedSet x_values = new TreeSet<>(); x_values.add(x_value); double[] interpolatedValues = interpolate(x_values, y_values); if (interpolatedValues.length != 1) throw new IllegalArgumentException("Cannot interpolate " + y_values + " at value " + x_value); return interpolatedValues[0]; } /** *

* continuous_dot_product. *

* * @param f1 a {@link java.util.NavigableMap} object. * @param f2 a {@link java.util.NavigableMap} object. * @return a double. */ static public double continuous_dot_product(final NavigableMap f1, final NavigableMap f2) { // Create a sorted union of x-values SortedSet x_union = new TreeSet<>(f1.navigableKeySet()); SortedSet x_union2 = new TreeSet<>(f2.navigableKeySet()); x_union.addAll(x_union2); double[] f1interpolated = interpolate(x_union, f1); double[] f2interpolated = interpolate(x_union, f2); NavigableMap product = new TreeMap<>(); int index = 0; for (double x : x_union) { product.put(x, f1interpolated[index] * f2interpolated[index]); ++index; } return integrate(product); } /** *

* continuous_dot_product. *

* * @param f1 a {@link java.util.Map} object. * @param f2 a {@link java.util.Map} object. * @return a double. */ static public double continuous_dot_product(final Map f1, final Map f2) { return continuous_dot_product(new TreeMap(f1), new TreeMap(f2)); } /** *

* pearson_correlation. *

* * @param f1 a {@link java.util.NavigableMap} object. * @param f2 a {@link java.util.NavigableMap} object. * @return a double. */ static public double pearson_correlation(final NavigableMap f1, final NavigableMap f2) { // Create a sorted union of x-values SortedSet x_union = new TreeSet<>(f1.navigableKeySet()); SortedSet x_union2 = new TreeSet<>(f2.navigableKeySet()); x_union.addAll(x_union2); double[] f1interpolated = interpolate(x_union, f1); double[] f2interpolated = interpolate(x_union, f2); int size = x_union.size(); double sum_x = 0.0; double sum_y = 0.0; double sum_xy = 0.0; double sum_x2 = 0.0; double sum_y2 = 0.0; for (int i = 0; i < size; ++i) { double x = f1interpolated[i]; double y = f2interpolated[i]; sum_x += x; sum_y += y; sum_xy += x * y; sum_x2 += x * x; sum_y2 += y * y; } double ave_x = sum_x / size; double ave_y = sum_y / size; double ave_xy = sum_xy / size; double ave_x2 = sum_x2 / size; double ave_y2 = sum_y2 / size; return (ave_xy - ave_x * ave_y) / java.lang.Math.sqrt(ave_x2 - ave_x * ave_x) / java.lang.Math.sqrt(ave_y2 - ave_y * ave_y); } /** *

* integrate. *

* * @param func a {@link java.util.NavigableMap} object. * @return a double. */ static public double integrate(final NavigableMap func) { Iterator> it = func.entrySet().iterator(); Map.Entry prevEntry = it.next(); double result = 0.0; while (it.hasNext()) { Map.Entry entry = it.next(); result += 0.5 * (prevEntry.getValue() + entry.getValue()) * (entry.getKey() - prevEntry.getKey()); prevEntry = entry; } return result; } /** *

* discrete_dot_product. *

* * @param f1 a {@link java.util.NavigableMap} object. * @param f2 a {@link java.util.NavigableMap} object. * @param tolerance a double. * @return a double. */ static public double discrete_dot_product(final NavigableMap f1, final NavigableMap f2, double tolerance) { double result = 0.0; if (f1.isEmpty() || f2.isEmpty()) return result; Iterator> it1 = f1.entrySet().iterator(); Iterator> it2 = f2.entrySet().iterator(); Map.Entry entry1 = it1.next(); Map.Entry entry2 = it2.next(); while (true) { try { if (entry1.getKey() < entry2.getKey() - tolerance) // x1 < x2 - tolerance entry1 = it1.next(); else if (entry2.getKey() < entry1.getKey() - tolerance) // x2 < x1 - tolerance entry2 = it2.next(); else { // |x1 - x2| < tolerance result += entry1.getValue() * entry2.getValue(); entry1 = it1.next(); entry2 = it2.next(); } } catch (NoSuchElementException e) { break; } } return result; } /** *

* discrete_dot_product. *

* * @param f1 a {@link java.util.Map} object. * @param f2 a {@link java.util.Map} object. * @param tolerance a double. * @return a double. */ static public double discrete_dot_product(final Map f1, final Map f2, double tolerance) { return discrete_dot_product(new TreeMap(f1), new TreeMap(f2), tolerance); } /** * Find derivative of func using two-sided rule for the central points and one-sided rule for the * end-points * * @param func a {@link java.util.NavigableMap} object. * @return a {@link java.util.NavigableMap} object. */ static public NavigableMap differentiate( final NavigableMap func) { NavigableMap result = new TreeMap<>(); if (func.size() < 3) return result; Iterator> it = func.entrySet().iterator(); Map.Entry center = it.next(); Map.Entry right = it.next(); double leftX, leftY; double centerX = center.getKey(), centerY = center.getValue(); double rightX = right.getKey(), rightY = right.getValue(); // Right-hand side derivative at the first entry result.put(centerX, (rightY - centerY) / (rightX - centerX)); while (it.hasNext()) { Map.Entry entry = it.next(); leftX = centerX; leftY = centerY; centerX = rightX; centerY = rightY; rightX = entry.getKey(); rightY = entry.getValue(); // Two-side derivative at the central entries result.put(centerX, (rightY - leftY) / (rightX - leftX)); } // Left-hand side derivative at the last entry result.put(rightX, (rightY - centerY) / (rightX - centerX)); return result; } /** * Convolution of two functions * * @param f1 a {@link java.util.NavigableMap} object. * @param f2 a {@link java.util.NavigableMap} object. * @param shift a double. * @return a double. */ static public double convolution(final NavigableMap f1, final NavigableMap f2, final double shift) { NavigableMap shifted2 = new TreeMap<>(); for (final Map.Entry entry : f2.entrySet()) shifted2.put(entry.getKey() + shift, entry.getValue()); return continuous_dot_product(f1, shifted2); } /** * Multiplies function by scale * * @param func a {@link java.util.NavigableMap} object. * @param scale a double. * @return a {@link java.util.NavigableMap} object. */ static public NavigableMap scale(final NavigableMap func, final double scale) { NavigableMap result = new TreeMap<>(); for (Map.Entry entry : func.entrySet()) result.put(entry.getKey(), scale * entry.getValue()); return result; } /** *

* linearCombination. *

* * @param functions a {@link java.util.List} object. * @param coefficients an array of double. * @return a {@link java.util.NavigableMap} object. */ static public NavigableMap linearCombination( final List> functions, final double[] coefficients) { NavigableMap result = new TreeMap<>(); int size = Integer.min(functions.size(), coefficients.length); for (int i = 0; i < size; ++i) { for (Entry e : functions.get(i).entrySet()) { double key = e.getKey(); double value = coefficients[i] * e.getValue(); result.put(key, result.getOrDefault(key, 0.0) + value); } } return result; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy