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 /* 19 * This is not the original file distributed by the Apache Software Foundation 20 * It has been modified by the Hipparchus project 21 */ 22 package org.hipparchus.distribution.continuous; 23 24 import org.hipparchus.exception.LocalizedCoreFormats; 25 import org.hipparchus.exception.MathIllegalArgumentException; 26 import org.hipparchus.util.FastMath; 27 import org.hipparchus.util.MathUtils; 28 29 /** 30 * Implementation of the Cauchy distribution. 31 * 32 * @see <a href="http://en.wikipedia.org/wiki/Cauchy_distribution">Cauchy distribution (Wikipedia)</a> 33 * @see <a href="http://mathworld.wolfram.com/CauchyDistribution.html">Cauchy Distribution (MathWorld)</a> 34 */ 35 public class CauchyDistribution extends AbstractRealDistribution { 36 /** Serializable version identifier */ 37 private static final long serialVersionUID = 20160320L; 38 /** The median of this distribution. */ 39 private final double median; 40 /** The scale of this distribution. */ 41 private final double scale; 42 43 /** 44 * Creates a Cauchy distribution with the median equal to zero and scale 45 * equal to one. 46 */ 47 public CauchyDistribution() { 48 this(0, 1); 49 } 50 51 52 /** 53 * Creates a Cauchy distribution. 54 * 55 * @param median Median for this distribution 56 * @param scale Scale parameter for this distribution 57 * @throws MathIllegalArgumentException if {@code scale <= 0} 58 */ 59 public CauchyDistribution(double median, double scale) 60 throws MathIllegalArgumentException { 61 if (scale <= 0) { 62 throw new MathIllegalArgumentException(LocalizedCoreFormats.SCALE, scale); 63 } 64 65 this.scale = scale; 66 this.median = median; 67 } 68 69 /** {@inheritDoc} */ 70 @Override 71 public double cumulativeProbability(double x) { 72 return 0.5 + (FastMath.atan((x - median) / scale) / FastMath.PI); 73 } 74 75 /** 76 * Access the median. 77 * 78 * @return the median for this distribution. 79 */ 80 public double getMedian() { 81 return median; 82 } 83 84 /** 85 * Access the scale parameter. 86 * 87 * @return the scale parameter for this distribution. 88 */ 89 public double getScale() { 90 return scale; 91 } 92 93 /** {@inheritDoc} */ 94 @Override 95 public double density(double x) { 96 final double dev = x - median; 97 return (1 / FastMath.PI) * (scale / (dev * dev + scale * scale)); 98 } 99 100 /** 101 * {@inheritDoc} 102 * 103 * Returns {@code Double.NEGATIVE_INFINITY} when {@code p == 0} 104 * and {@code Double.POSITIVE_INFINITY} when {@code p == 1}. 105 */ 106 @Override 107 public double inverseCumulativeProbability(double p) throws MathIllegalArgumentException { 108 MathUtils.checkRangeInclusive(p, 0, 1); 109 110 double ret; 111 if (p == 0) { 112 ret = Double.NEGATIVE_INFINITY; 113 } else if (p == 1) { 114 ret = Double.POSITIVE_INFINITY; 115 } else { 116 ret = median + scale * FastMath.tan(FastMath.PI * (p - .5)); 117 } 118 return ret; 119 } 120 121 /** 122 * {@inheritDoc} 123 * 124 * The mean is always undefined no matter the parameters. 125 * 126 * @return mean (always Double.NaN) 127 */ 128 @Override 129 public double getNumericalMean() { 130 return Double.NaN; 131 } 132 133 /** 134 * {@inheritDoc} 135 * 136 * The variance is always undefined no matter the parameters. 137 * 138 * @return variance (always Double.NaN) 139 */ 140 @Override 141 public double getNumericalVariance() { 142 return Double.NaN; 143 } 144 145 /** 146 * {@inheritDoc} 147 * 148 * The lower bound of the support is always negative infinity no matter 149 * the parameters. 150 * 151 * @return lower bound of the support (always Double.NEGATIVE_INFINITY) 152 */ 153 @Override 154 public double getSupportLowerBound() { 155 return Double.NEGATIVE_INFINITY; 156 } 157 158 /** 159 * {@inheritDoc} 160 * 161 * The upper bound of the support is always positive infinity no matter 162 * the parameters. 163 * 164 * @return upper bound of the support (always Double.POSITIVE_INFINITY) 165 */ 166 @Override 167 public double getSupportUpperBound() { 168 return Double.POSITIVE_INFINITY; 169 } 170 171 /** 172 * {@inheritDoc} 173 * 174 * The support of this distribution is connected. 175 * 176 * @return {@code true} 177 */ 178 @Override 179 public boolean isSupportConnected() { 180 return true; 181 } 182 }