| 1 | package com.github.sanity.pav | |
| 2 | ||
| 3 | import com.github.sanity.pav.PairAdjacentViolators.InterpolationStrategy.SPLINE | |
| 4 | import com.github.sanity.pav.spline.MonotoneSpline | |
| 5 | import java.io.Serializable | |
| 6 | import java.util.* | |
| 7 | ||
| 8 | /** | |
| 9 | * Implements the "pair adjacent violators" algorithm, also known as "pool adjacent violators", for isotonic regression. | |
| 10 | */ | |
| 11 | ||
| 12 | ||
| 13 | class PairAdjacentViolators @JvmOverloads constructor(originalPoints: Iterable<Point>, mode: PAVMode = PAVMode.INCREASING) : Serializable { | |
| 14 | ||
| 15 | companion object { | |
| 16 | private const val serialVersionUID: Long = -5624398625406 | |
| 17 | } | |
| 18 | ||
| 19 | /** | |
| 20 | * The points after the regression, should either be increasing or decreasing depending | |
| 21 | * on how the PairAdjacentViolators object is configured. | |
| 22 | */ | |
| 23 |
1
1. getIsotonicPoints : mutated return of Object value for com/github/sanity/pav/PairAdjacentViolators::getIsotonicPoints to ( if (x != null) null else throw new RuntimeException ) → KILLED |
val isotonicPoints: ArrayList<Point> |
| 24 | ||
| 25 | init { | |
| 26 | val points: PairSubstitutingDoublyLinkedList<Point> = PairSubstitutingDoublyLinkedList.createFromList(originalPoints.sortedBy { it.x }) | |
| 27 |
1
1. |
points.iterate { cursor -> |
| 28 | val previous = cursor.previousValue | |
| 29 | val next = cursor.nextValue | |
| 30 |
1
1. invoke : negated conditional → KILLED |
if (previous != null) { |
| 31 | val shouldMerge = | |
| 32 | previous.x == next.x || ( | |
| 33 |
2
1. invoke : negated conditional → KILLED 2. invoke : negated conditional → KILLED |
when (mode) { |
| 34 |
2
1. invoke : changed conditional boundary → KILLED 2. invoke : negated conditional → KILLED |
PAVMode.INCREASING -> previous.y >= next.y |
| 35 |
2
1. invoke : changed conditional boundary → KILLED 2. invoke : negated conditional → KILLED |
PAVMode.DECREASING -> previous.y <= next.y |
| 36 | }) | |
| 37 |
1
1. invoke : negated conditional → KILLED |
if (shouldMerge) { |
| 38 | previous.merge(next) | |
| 39 | } else { | |
| 40 | null | |
| 41 | } | |
| 42 | } else { | |
| 43 | null | |
| 44 |
1
1. invoke : mutated return of Object value for com/github/sanity/pav/PairAdjacentViolators$1::invoke to ( if (x != null) null else throw new RuntimeException ) → KILLED |
} |
| 45 | } | |
| 46 | ||
| 47 | isotonicPoints = points.toArrayList() | |
| 48 | } | |
| 49 | ||
| 50 | @JvmOverloads fun interpolator(strategy: InterpolationStrategy = SPLINE): (Double) -> Double { | |
| 51 | when (strategy) { | |
| 52 |
1
1. interpolator : mutated return of Object value for com/github/sanity/pav/PairAdjacentViolators::interpolator to ( if (x != null) null else throw new RuntimeException ) → KILLED |
SPLINE -> return { |
| 53 |
1
1. invoke : replaced return of double value with -(x + 1) for com/github/sanity/pav/PairAdjacentViolators$interpolator$1::invoke → KILLED |
MonotoneSpline(isotonicPoints).interpolate(it) |
| 54 | } | |
| 55 | } | |
| 56 | } | |
| 57 | ||
| 58 | @JvmOverloads fun inverseInterpolator(strategy: InterpolationStrategy = SPLINE): (Double) -> Double { | |
| 59 | when (strategy) { | |
| 60 |
1
1. inverseInterpolator : mutated return of Object value for com/github/sanity/pav/PairAdjacentViolators::inverseInterpolator to ( if (x != null) null else throw new RuntimeException ) → KILLED |
SPLINE -> return { |
| 61 | val spline = MonotoneSpline(isotonicPoints.map {Point(it.y, it.x)}) | |
| 62 |
1
1. invoke : replaced return of double value with -(x + 1) for com/github/sanity/pav/PairAdjacentViolators$inverseInterpolator$1::invoke → KILLED |
spline.interpolate(it) |
| 63 | } | |
| 64 | } | |
| 65 | } | |
| 66 | ||
| 67 | enum class InterpolationStrategy { | |
| 68 | SPLINE | |
| 69 | } | |
| 70 | ||
| 71 | enum class PAVMode { | |
| 72 | INCREASING, DECREASING | |
| 73 | } | |
| 74 | } | |
Mutations | ||
| 23 |
1.1 |
|
| 27 |
1.1 |
|
| 30 |
1.1 |
|
| 33 |
1.1 2.2 |
|
| 34 |
1.1 2.2 |
|
| 35 |
1.1 2.2 |
|
| 37 |
1.1 |
|
| 44 |
1.1 |
|
| 52 |
1.1 |
|
| 53 |
1.1 |
|
| 60 |
1.1 |
|
| 62 |
1.1 |
|
| 77 |
1.1 |