SumOfLogs.java

  1. /*
  2.  * Licensed to the Apache Software Foundation (ASF) under one or more
  3.  * contributor license agreements.  See the NOTICE file distributed with
  4.  * this work for additional information regarding copyright ownership.
  5.  * The ASF licenses this file to You under the Apache License, Version 2.0
  6.  * (the "License"); you may not use this file except in compliance with
  7.  * the License.  You may obtain a copy of the License at
  8.  *
  9.  *      https://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */

  17. /*
  18.  * This is not the original file distributed by the Apache Software Foundation
  19.  * It has been modified by the Hipparchus project
  20.  */
  21. package org.hipparchus.stat.descriptive.summary;

  22. import java.io.Serializable;

  23. import org.hipparchus.exception.MathIllegalArgumentException;
  24. import org.hipparchus.exception.NullArgumentException;
  25. import org.hipparchus.stat.descriptive.AbstractStorelessUnivariateStatistic;
  26. import org.hipparchus.stat.descriptive.AggregatableStatistic;
  27. import org.hipparchus.util.FastMath;
  28. import org.hipparchus.util.MathArrays;
  29. import org.hipparchus.util.MathUtils;

  30. /**
  31.  * Returns the sum of the natural logs for this collection of values.
  32.  * <p>
  33.  * Uses {@link org.hipparchus.util.FastMath#log(double)} to compute the logs.
  34.  * Therefore,
  35.  * <ul>
  36.  * <li>If any of values are &lt; 0, the result is <code>NaN.</code></li>
  37.  * <li>If all values are non-negative and less than
  38.  * <code>Double.POSITIVE_INFINITY</code>,  but at least one value is 0, the
  39.  * result is <code>Double.NEGATIVE_INFINITY.</code></li>
  40.  * <li>If both <code>Double.POSITIVE_INFINITY</code> and
  41.  * <code>Double.NEGATIVE_INFINITY</code> are among the values, the result is
  42.  * <code>NaN.</code></li>
  43.  * </ul>
  44.  * <p>
  45.  * <strong>Note that this implementation is not synchronized.</strong> If
  46.  * multiple threads access an instance of this class concurrently, and at least
  47.  * one of the threads invokes the <code>increment()</code> or
  48.  * <code>clear()</code> method, it must be synchronized externally.
  49.  */
  50. public class SumOfLogs extends AbstractStorelessUnivariateStatistic
  51.     implements AggregatableStatistic<SumOfLogs>, Serializable {

  52.     /** Serializable version identifier */
  53.     private static final long serialVersionUID = 20150412L;

  54.     /** Number of values that have been added */
  55.     private int n;

  56.     /** The currently running value */
  57.     private double value;

  58.     /**
  59.      * Create a SumOfLogs instance.
  60.      */
  61.     public SumOfLogs() {
  62.        value = 0d;
  63.        n = 0;
  64.     }

  65.     /**
  66.      * Copy constructor, creates a new {@code SumOfLogs} identical
  67.      * to the {@code original}.
  68.      *
  69.      * @param original the {@code SumOfLogs} instance to copy
  70.      * @throws NullArgumentException if original is null
  71.      */
  72.     public SumOfLogs(SumOfLogs original) throws NullArgumentException {
  73.         MathUtils.checkNotNull(original);
  74.         this.n     = original.n;
  75.         this.value = original.value;
  76.     }

  77.     /** {@inheritDoc} */
  78.     @Override
  79.     public void increment(final double d) {
  80.         value += FastMath.log(d);
  81.         n++;
  82.     }

  83.     /** {@inheritDoc} */
  84.     @Override
  85.     public double getResult() {
  86.         return value;
  87.     }

  88.     /** {@inheritDoc} */
  89.     @Override
  90.     public long getN() {
  91.         return n;
  92.     }

  93.     /** {@inheritDoc} */
  94.     @Override
  95.     public void clear() {
  96.         value = 0d;
  97.         n = 0;
  98.     }

  99.     /** {@inheritDoc} */
  100.     @Override
  101.     public void aggregate(SumOfLogs other) {
  102.         MathUtils.checkNotNull(other);
  103.         if (other.n > 0) {
  104.             this.n     += other.n;
  105.             this.value += other.value;
  106.         }
  107.     }

  108.     /**
  109.      * Returns the sum of the natural logs of the entries in the specified portion of
  110.      * the input array, or <code>Double.NaN</code> if the designated subarray
  111.      * is empty.
  112.      *
  113.      * @param values the input array
  114.      * @param begin index of the first array element to include
  115.      * @param length the number of elements to include
  116.      * @return the sum of the natural logs of the values or 0 if
  117.      * length = 0
  118.      * @throws MathIllegalArgumentException if the array is null or the array index
  119.      *  parameters are not valid
  120.      */
  121.     @Override
  122.     public double evaluate(final double[] values, final int begin, final int length)
  123.         throws MathIllegalArgumentException {

  124.         double sumLog = Double.NaN;
  125.         if (MathArrays.verifyValues(values, begin, length, true)) {
  126.             sumLog = 0.0;
  127.             for (int i = begin; i < begin + length; i++) {
  128.                 sumLog += FastMath.log(values[i]);
  129.             }
  130.         }
  131.         return sumLog;
  132.     }

  133.     /** {@inheritDoc} */
  134.     @Override
  135.     public SumOfLogs copy() {
  136.         return new SumOfLogs(this);
  137.     }

  138. }