-- refactoring

This commit is contained in:
mrFendel 2023-05-05 18:45:54 +03:00
parent 1e27af9cf5
commit 16385b5f4e
3 changed files with 51 additions and 52 deletions

View File

@ -3,19 +3,19 @@
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
package space.kscience.kmath.series package space.kscience.kmath.distributions
import space.kscience.kmath.operations.DoubleField.pow import space.kscience.kmath.operations.DoubleField.pow
import kotlin.math.PI import kotlin.math.PI
import kotlin.math.absoluteValue import kotlin.math.absoluteValue
import kotlin.math.exp import kotlin.math.exp
public fun zSNormalCDF(x: Double): Double {
/** /**
* Zelen & Severo approximation for the standard normal CDF. * Zelen & Severo approximation for the standard normal CDF.
* The error is bounded by 7.5 * 10e-8. * The error is bounded by 7.5 * 10e-8.
* */ * */
public fun zSNormalCDF(x: Double): Double {
val t = 1 / (1 + 0.2316419 * x.absoluteValue) val t = 1 / (1 + 0.2316419 * x.absoluteValue)
val summ = 0.319381530*t - 0.356563782*t.pow(2) + 1.781477937*t.pow(3) - 1.821255978*t.pow(4) + 1.330274429*t.pow(5) val summ = 0.319381530*t - 0.356563782*t.pow(2) + 1.781477937*t.pow(3) - 1.821255978*t.pow(4) + 1.330274429*t.pow(5)

View File

@ -216,7 +216,7 @@ public open class SeriesAlgebra<T, out A : Ring<T>, out BA : BufferAlgebra<T, A>
override fun multiply(left: Buffer<T>, right: Buffer<T>): Buffer<T> = left.zip(right) { l, r -> l * r } override fun multiply(left: Buffer<T>, right: Buffer<T>): Buffer<T> = left.zip(right) { l, r -> l * r }
public fun Buffer<T>.diff(shift: Int=1): Buffer<T> = this.zipWithShift(shift) {l, r -> r - l} public fun Buffer<T>.difference(shift: Int=1): Buffer<T> = this.zipWithShift(shift) {l, r -> r - l}
public companion object public companion object
} }

View File

@ -5,6 +5,7 @@
package space.kscience.kmath.series package space.kscience.kmath.series
import space.kscience.kmath.distributions.zSNormalCDF
import space.kscience.kmath.operations.DoubleField.pow import space.kscience.kmath.operations.DoubleField.pow
import space.kscience.kmath.operations.algebra import space.kscience.kmath.operations.algebra
import space.kscience.kmath.operations.bufferAlgebra import space.kscience.kmath.operations.bufferAlgebra
@ -12,14 +13,12 @@ import space.kscience.kmath.operations.fold
import kotlin.math.absoluteValue import kotlin.math.absoluteValue
// TODO: add p-value with formula: 2*(1 - cdf(|zScore|))
public data class VarianceRatioTestResult(val varianceRatio: Double=1.0, val zScore: Double=0.0, val pValue: Double=0.5)
/** /**
* Container class for Variance Ratio Test result: * Container class for Variance Ratio Test result:
* ratio itself, corresponding Z-score, also it's p-value * ratio itself, corresponding Z-score, also it's p-value
* **/ * **/
public data class VarianceRatioTestResult(val varianceRatio: Double=1.0, val zScore: Double=0.0, val pValue: Double=0.5)
public fun varianceRatioTest(series: Series<Double>, shift: Int, homoscedastic: Boolean=true): VarianceRatioTestResult {
/** /**
* Calculates the Z-statistic and the p-value for the Lo and MacKinlay's Variance Ratio test (1987) * Calculates the Z-statistic and the p-value for the Lo and MacKinlay's Variance Ratio test (1987)
@ -27,14 +26,15 @@ public fun varianceRatioTest(series: Series<Double>, shift: Int, homoscedastic:
* with two-sided p-value test * with two-sided p-value test
* https://ssrn.com/abstract=346975 * https://ssrn.com/abstract=346975
* **/ * **/
public fun SeriesAlgebra<Double, *, *, *>.varianceRatioTest(series: Series<Double>, shift: Int, homoscedastic: Boolean=true): VarianceRatioTestResult {
require(shift > 1) {"Shift must be greater than one"} require(shift > 1) {"Shift must be greater than one"}
require(shift < series.size) {"Shift must be smaller than sample size"} require(shift < series.size) {"Shift must be smaller than sample size"}
val sum = { x: Double, y: Double -> x + y } val sum = { x: Double, y: Double -> x + y }
with(Double.algebra.bufferAlgebra.seriesAlgebra()) {
val mean = series.fold(0.0, sum) / series.size val mean = series.fold(0.0, sum) / series.size
val demeanedSquares = series.map { power(it - mean, 2) } val demeanedSquares = series.map { (it - mean).pow(2) }
val variance = demeanedSquares.fold(0.0, sum) val variance = demeanedSquares.fold(0.0, sum)
if (variance == 0.0) return VarianceRatioTestResult() if (variance == 0.0) return VarianceRatioTestResult()
@ -44,7 +44,7 @@ public fun varianceRatioTest(series: Series<Double>, shift: Int, homoscedastic:
seriesAgg = seriesAgg.zip(series.moveTo(i)) { v1, v2 -> v1 + v2 } seriesAgg = seriesAgg.zip(series.moveTo(i)) { v1, v2 -> v1 + v2 }
} }
val demeanedSquaresAgg = seriesAgg.map { power(it - shift * mean, 2) } val demeanedSquaresAgg = seriesAgg.map { (it - shift * mean).pow(2) }
val varianceAgg = demeanedSquaresAgg.fold(0.0, sum) val varianceAgg = demeanedSquaresAgg.fold(0.0, sum)
val varianceRatio = val varianceRatio =
@ -68,7 +68,6 @@ public fun varianceRatioTest(series: Series<Double>, shift: Int, homoscedastic:
val pValue = 2*(1 - zSNormalCDF(zScore.absoluteValue)) val pValue = 2*(1 - zSNormalCDF(zScore.absoluteValue))
return VarianceRatioTestResult(varianceRatio, zScore, pValue) return VarianceRatioTestResult(varianceRatio, zScore, pValue)
} }
}