Home | History | Annotate | Download | only in summary
      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  *      http://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 package org.apache.commons.math.stat.descriptive.summary;
     18 
     19 import java.io.Serializable;
     20 
     21 import org.apache.commons.math.stat.descriptive.AbstractStorelessUnivariateStatistic;
     22 import org.apache.commons.math.util.FastMath;
     23 
     24 /**
     25  * Returns the sum of the natural logs for this collection of values.
     26  * <p>
     27  * Uses {@link java.lang.Math#log(double)} to compute the logs.  Therefore,
     28  * <ul>
     29  * <li>If any of values are < 0, the result is <code>NaN.</code></li>
     30  * <li>If all values are non-negative and less than
     31  * <code>Double.POSITIVE_INFINITY</code>,  but at least one value is 0, the
     32  * result is <code>Double.NEGATIVE_INFINITY.</code></li>
     33  * <li>If both <code>Double.POSITIVE_INFINITY</code> and
     34  * <code>Double.NEGATIVE_INFINITY</code> are among the values, the result is
     35  * <code>NaN.</code></li>
     36  * </ul></p>
     37  * <p>
     38  * <strong>Note that this implementation is not synchronized.</strong> If
     39  * multiple threads access an instance of this class concurrently, and at least
     40  * one of the threads invokes the <code>increment()</code> or
     41  * <code>clear()</code> method, it must be synchronized externally.</p>
     42  *
     43  * @version $Revision: 1006299 $ $Date: 2010-10-10 16:47:17 +0200 (dim. 10 oct. 2010) $
     44  */
     45 public class SumOfLogs extends AbstractStorelessUnivariateStatistic implements Serializable {
     46 
     47     /** Serializable version identifier */
     48     private static final long serialVersionUID = -370076995648386763L;
     49 
     50     /**Number of values that have been added */
     51     private int n;
     52 
     53     /**
     54      * The currently running value
     55      */
     56     private double value;
     57 
     58     /**
     59      * Create a SumOfLogs instance
     60      */
     61     public SumOfLogs() {
     62        value = 0d;
     63        n = 0;
     64     }
     65 
     66     /**
     67      * Copy constructor, creates a new {@code SumOfLogs} identical
     68      * to the {@code original}
     69      *
     70      * @param original the {@code SumOfLogs} instance to copy
     71      */
     72     public SumOfLogs(SumOfLogs original) {
     73         copy(original, this);
     74     }
     75 
     76     /**
     77      * {@inheritDoc}
     78      */
     79     @Override
     80     public void increment(final double d) {
     81         value += FastMath.log(d);
     82         n++;
     83     }
     84 
     85     /**
     86      * {@inheritDoc}
     87      */
     88     @Override
     89     public double getResult() {
     90         if (n > 0) {
     91             return value;
     92         } else {
     93             return Double.NaN;
     94         }
     95     }
     96 
     97     /**
     98      * {@inheritDoc}
     99      */
    100     public long getN() {
    101         return n;
    102     }
    103 
    104     /**
    105      * {@inheritDoc}
    106      */
    107     @Override
    108     public void clear() {
    109         value = 0d;
    110         n = 0;
    111     }
    112 
    113     /**
    114      * Returns the sum of the natural logs of the entries in the specified portion of
    115      * the input array, or <code>Double.NaN</code> if the designated subarray
    116      * is empty.
    117      * <p>
    118      * Throws <code>IllegalArgumentException</code> if the array is null.</p>
    119      * <p>
    120      * See {@link SumOfLogs}.</p>
    121      *
    122      * @param values the input array
    123      * @param begin index of the first array element to include
    124      * @param length the number of elements to include
    125      * @return the sum of the natural logs of the values or Double.NaN if
    126      * length = 0
    127      * @throws IllegalArgumentException if the array is null or the array index
    128      *  parameters are not valid
    129      */
    130     @Override
    131     public double evaluate(final double[] values, final int begin, final int length) {
    132         double sumLog = Double.NaN;
    133         if (test(values, begin, length)) {
    134             sumLog = 0.0;
    135             for (int i = begin; i < begin + length; i++) {
    136                 sumLog += FastMath.log(values[i]);
    137             }
    138         }
    139         return sumLog;
    140     }
    141 
    142     /**
    143      * {@inheritDoc}
    144      */
    145     @Override
    146     public SumOfLogs copy() {
    147         SumOfLogs result = new SumOfLogs();
    148         copy(this, result);
    149         return result;
    150     }
    151 
    152     /**
    153      * Copies source to dest.
    154      * <p>Neither source nor dest can be null.</p>
    155      *
    156      * @param source SumOfLogs to copy
    157      * @param dest SumOfLogs to copy to
    158      * @throws NullPointerException if either source or dest is null
    159      */
    160     public static void copy(SumOfLogs source, SumOfLogs dest) {
    161         dest.setData(source.getDataRef());
    162         dest.n = source.n;
    163         dest.value = source.value;
    164     }
    165 }
    166