001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.commons.math4.legacy.stat.descriptive.summary; 018 019import org.apache.commons.math4.legacy.exception.MathIllegalArgumentException; 020import org.apache.commons.math4.legacy.exception.NullArgumentException; 021import org.apache.commons.math4.legacy.stat.descriptive.AbstractStorelessUnivariateStatistic; 022import org.apache.commons.math4.legacy.core.MathArrays; 023 024 025/** 026 * Returns the sum of the available values. 027 * <p> 028 * If there are no values in the dataset, then 0 is returned. 029 * If any of the values are 030 * <code>NaN</code>, then <code>NaN</code> is returned.</p> 031 * <p> 032 * <strong>Note that this implementation is not synchronized.</strong> If 033 * multiple threads access an instance of this class concurrently, and at least 034 * one of the threads invokes the <code>increment()</code> or 035 * <code>clear()</code> method, it must be synchronized externally.</p> 036 */ 037public class Sum extends AbstractStorelessUnivariateStatistic { 038 /** */ 039 private long n; 040 041 /** 042 * The currently running sum. 043 */ 044 private double value; 045 046 /** 047 * Create a Sum instance. 048 */ 049 public Sum() { 050 n = 0; 051 value = 0; 052 } 053 054 /** 055 * Copy constructor, creates a new {@code Sum} identical 056 * to the {@code original}. 057 * 058 * @param original the {@code Sum} instance to copy 059 * @throws NullArgumentException if original is null 060 */ 061 public Sum(Sum original) throws NullArgumentException { 062 copy(original, this); 063 } 064 065 /** 066 * {@inheritDoc} 067 */ 068 @Override 069 public void increment(final double d) { 070 value += d; 071 n++; 072 } 073 074 /** 075 * {@inheritDoc} 076 */ 077 @Override 078 public double getResult() { 079 return value; 080 } 081 082 /** 083 * {@inheritDoc} 084 */ 085 @Override 086 public long getN() { 087 return n; 088 } 089 090 /** 091 * {@inheritDoc} 092 */ 093 @Override 094 public void clear() { 095 value = 0; 096 n = 0; 097 } 098 099 /** 100 * The sum of the entries in the specified portion of the input array, 101 * or 0 if the designated subarray is empty. 102 * <p> 103 * Throws <code>MathIllegalArgumentException</code> if the array is null.</p> 104 * 105 * @param values the input array 106 * @param begin index of the first array element to include 107 * @param length the number of elements to include 108 * @return the sum of the values or 0 if length = 0 109 * @throws MathIllegalArgumentException if the array is null or the array index 110 * parameters are not valid 111 */ 112 @Override 113 public double evaluate(final double[] values, final int begin, final int length) 114 throws MathIllegalArgumentException { 115 116 double sum = Double.NaN; 117 if (MathArrays.verifyValues(values, begin, length, true)) { 118 sum = 0.0; 119 for (int i = begin; i < begin + length; i++) { 120 sum += values[i]; 121 } 122 } 123 return sum; 124 } 125 126 /** 127 * The weighted sum of the entries in the specified portion of 128 * the input array, or 0 if the designated subarray 129 * is empty. 130 * <p> 131 * Throws <code>MathIllegalArgumentException</code> if any of the following are true: 132 * <ul><li>the values array is null</li> 133 * <li>the weights array is null</li> 134 * <li>the weights array does not have the same length as the values array</li> 135 * <li>the weights array contains one or more infinite values</li> 136 * <li>the weights array contains one or more NaN values</li> 137 * <li>the weights array contains negative values</li> 138 * <li>the start and length arguments do not determine a valid array</li> 139 * </ul> 140 * <p> 141 * Uses the formula, <pre> 142 * weighted sum = Σ(values[i] * weights[i]) 143 * </pre> 144 * 145 * @param values the input array 146 * @param weights the weights array 147 * @param begin index of the first array element to include 148 * @param length the number of elements to include 149 * @return the sum of the values or 0 if length = 0 150 * @throws MathIllegalArgumentException if the parameters are not valid 151 * @since 2.1 152 */ 153 public double evaluate(final double[] values, final double[] weights, 154 final int begin, final int length) throws MathIllegalArgumentException { 155 double sum = Double.NaN; 156 if (MathArrays.verifyValues(values, weights, begin, length, true)) { 157 sum = 0.0; 158 for (int i = begin; i < begin + length; i++) { 159 sum += values[i] * weights[i]; 160 } 161 } 162 return sum; 163 } 164 165 /** 166 * The weighted sum of the entries in the input array. 167 * <p> 168 * Throws <code>MathIllegalArgumentException</code> if any of the following are true: 169 * <ul><li>the values array is null</li> 170 * <li>the weights array is null</li> 171 * <li>the weights array does not have the same length as the values array</li> 172 * <li>the weights array contains one or more infinite values</li> 173 * <li>the weights array contains one or more NaN values</li> 174 * <li>the weights array contains negative values</li> 175 * </ul> 176 * <p> 177 * Uses the formula, <pre> 178 * weighted sum = Σ(values[i] * weights[i]) 179 * </pre> 180 * 181 * @param values the input array 182 * @param weights the weights array 183 * @return the sum of the values or Double.NaN if length = 0 184 * @throws MathIllegalArgumentException if the parameters are not valid 185 * @since 2.1 186 */ 187 public double evaluate(final double[] values, final double[] weights) throws MathIllegalArgumentException { 188 return evaluate(values, weights, 0, values.length); 189 } 190 191 /** 192 * {@inheritDoc} 193 */ 194 @Override 195 public Sum copy() { 196 Sum result = new Sum(); 197 // No try-catch or advertised exception because args are valid 198 copy(this, result); 199 return result; 200 } 201 202 /** 203 * Copies source to dest. 204 * <p>Neither source nor dest can be null.</p> 205 * 206 * @param source Sum to copy 207 * @param dest Sum to copy to 208 * @throws NullArgumentException if either source or dest is null 209 */ 210 public static void copy(Sum source, Sum dest) 211 throws NullArgumentException { 212 NullArgumentException.check(source); 213 NullArgumentException.check(dest); 214 dest.n = source.n; 215 dest.value = source.value; 216 } 217}