@Override public String toString() { return new StringBuilder().append("{f(x) = ") .append(getAmplitude()).append(" * ") .append("sin(x * ").append(getFrequency()) .append(" * 2pi - pi * ").append(getPhaseShift()) .append(") + ").append(getHeight()).append("}") .toString(); }
@Override public boolean equals(Object o) { if (o == this) { return true; } if (o instanceof IntensityFunctions.SineIntensity) { IntensityFunctions.SineIntensity that = (IntensityFunctions.SineIntensity) o; return (Double.doubleToLongBits(this.amplitude) == Double.doubleToLongBits(that.getAmplitude())) && (Double.doubleToLongBits(this.frequency) == Double.doubleToLongBits(that.getFrequency())) && (Double.doubleToLongBits(this.height) == Double.doubleToLongBits(that.getHeight())) && (Double.doubleToLongBits(this.phaseShift) == Double.doubleToLongBits(that.getPhaseShift())); } return false; }
@Override public Double apply(@Nullable Double x) { if (x == null) { throw new IllegalArgumentException(); } return Math.max(0d, getAmplitude() * Math.sin(x * getFrequency() * TWO_PI - Math.PI * getPhaseShift()) + getHeight()); }
assertEquals( .369903, IntensityFunctions.areaByIntegration(sine, 0, 1d / sine.getFrequency()), 0.000001); assertEquals( .31831, IntensityFunctions.areaByIntegration(sine, 0, 1d / sine.getFrequency()), 0.00001); assertEquals( .269903, IntensityFunctions.areaByIntegration(sine, 0, 1d / sine.getFrequency()), 0.000001); assertEquals( 36000, IntensityFunctions.areaByIntegration(sine, 0, 1d / sine.getFrequency()), 0.00001); assertEquals( 27.2065, IntensityFunctions.areaByIntegration(sine, 0, 1d / sine.getFrequency()), 0.0001);
final SineIntensity si = (SineIntensity) ((NonHomogenous) poisson).lambd; final double period = 1d / si.getFrequency(); final double periods = length / period; final double totalEvents = si.area() * periods;
/** * Computes the area under this sine function and above y=0 in the range * [0,period). Where period is defined as <code>1/frequency</code>. * @return The computed area. */ public double area() { // in this computation the phase shift is ignored as it doesn't have any // effect for one period. final double a = getAmplitude(); final double b = getHeight(); final double c = getFrequency(); final double[] roots = roots(); final double d = roots[0]; final double e = roots[1]; return a * Math.sin(Math.PI * c * (d - e)) * Math.sin(HALF_PI - Math.PI * c * (d + e)) / (Math.PI * c) + b * (e - d); }
double[] roots() { final double a = getAmplitude(); // we need to cap height since if it is higher there are no roots final double b = Math.min(getHeight(), a); final double c = getFrequency(); final double n1 = -1; final double n2 = 0; final double common = Math.asin(b / a) / (TWO_PI * c); final double rootA = -ONE_FOURTH / c + common - n1 / c; final double rootB = ONE_FOURTH / c - common - n2 / c; if (rootA > rootB) { return new double[] {rootB, rootA}; } return new double[] {rootA, rootB}; }