Repository: jtablesaw/tablesaw
Pull request #745 (2020-01-24 21:50:37)

Add cumMin and cumMax
Thanks for contributing.

- [X] Tick to sign-off your agreement to the [Developer Certificate of Origin (DCO) 1.1](https://developercertificate.org)

## Description

Added new `cumMin` and `cumMax` methods

## Testing

Added new tests


sonarcloud[bot]: Kudos, SonarCloud Quality Gate passed!

[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug.png' alt='Bug' width='16' height='16' />](https://sonarcloud.io/project/issues?id=jtablesaw_tablesaw&pullRequest=745&resolved=false&types=BUG) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/issues?id=jtablesaw_tablesaw&pullRequest=745&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=jtablesaw_tablesaw&pullRequest=745&resolved=false&types=BUG)  
[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability.png' alt='Vulnerability' width='16' height='16' />](https://sonarcloud.io/project/issues?id=jtablesaw_tablesaw&pullRequest=745&resolved=false&types=VULNERABILITY) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/issues?id=jtablesaw_tablesaw&pullRequest=745&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=jtablesaw_tablesaw&pullRequest=745&resolved=false&types=VULNERABILITY) (and [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot.png' alt='Security Hotspot' width='16' height='16' />](https://sonarcloud.io/project/issues?id=jtablesaw_tablesaw&pullRequest=745&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/issues?id=jtablesaw_tablesaw&pullRequest=745&resolved=false&types=SECURITY_HOTSPOT) to review)  
[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell.png' alt='Code Smell' width='16' height='16' />](https://sonarcloud.io/project/issues?id=jtablesaw_tablesaw&pullRequest=745&resolved=false&types=CODE_SMELL) [<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A.png' alt='A' width='16' height='16' />](https://sonarcloud.io/project/issues?id=jtablesaw_tablesaw&pullRequest=745&resolved=false&types=CODE_SMELL) [0 Code Smells](https://sonarcloud.io/project/issues?id=jtablesaw_tablesaw&pullRequest=745&resolved=false&types=CODE_SMELL)

[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/100.png' alt='100.0%' width='16' height='16' />](https://sonarcloud.io/component_measures?id=jtablesaw_tablesaw&pullRequest=745&metric=new_coverage&view=list) [100.0% Coverage](https://sonarcloud.io/component_measures?id=jtablesaw_tablesaw&pullRequest=745&metric=new_coverage&view=list)  
[<img src='https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/3.png' alt='0.0%' width='16' height='16' />](https://sonarcloud.io/component_measures?id=jtablesaw_tablesaw&pullRequest=745&metric=new_duplicated_lines_density&view=list) [0.0% Duplication](https://sonarcloud.io/component_measures?id=jtablesaw_tablesaw&pullRequest=745&metric=new_duplicated_lines_density&view=list)



Patch:
diff --git a/core/src/main/java/tech/tablesaw/columns/numbers/NumberMapFunctions.java b/core/src/main/java/tech/tablesaw/columns/numbers/NumberMapFunctions.java
index 5ad23a60..f2faba90 100644
--- a/core/src/main/java/tech/tablesaw/columns/numbers/NumberMapFunctions.java
+++ b/core/src/main/java/tech/tablesaw/columns/numbers/NumberMapFunctions.java
@@ -385,6 +385,34 @@ public interface NumberMapFunctions {
     return newColumn;
   }
 
+  /** Returns a new column with a cumulative maximum calculated */
+  default DoubleColumn cumMax() {
+    double max = DoubleColumnType.missingValueIndicator();
+    DoubleColumn newColumn = DoubleColumn.create(name() + "[cumMax]", size());
+    for (int i = 0; i < size(); i++) {
+      double value = getDouble(i);
+      if (!DoubleColumnType.valueIsMissing(value)) {
+        max = DoubleColumnType.valueIsMissing(max) ? value : Math.max(max, value);
+      }
+      newColumn.set(i, max);
+    }
+    return newColumn;
+  }
+
+  /** Returns a new column with a cumulative maximum calculated */
+  default DoubleColumn cumMin() {
+    double min = DoubleColumnType.missingValueIndicator();
+    DoubleColumn newColumn = DoubleColumn.create(name() + "[cumMin]", size());
+    for (int i = 0; i < size(); i++) {
+      double value = getDouble(i);
+      if (!DoubleColumnType.valueIsMissing(value)) {
+        min = DoubleColumnType.valueIsMissing(min) ? value : Math.min(min, value);
+      }
+      newColumn.set(i, min);
+    }
+    return newColumn;
+  }
+
   /** Returns a new column with a percent change calculated */
   default DoubleColumn pctChange() {
     DoubleColumn newColumn = DoubleColumn.create(name() + "[pctChange]", size());


Test patch:
diff --git a/core/src/test/java/tech/tablesaw/api/NumberColumnTest.java b/core/src/test/java/tech/tablesaw/api/NumberColumnTest.java
index 5cb03a0d..96885bcb 100644
--- a/core/src/test/java/tech/tablesaw/api/NumberColumnTest.java
+++ b/core/src/test/java/tech/tablesaw/api/NumberColumnTest.java
@@ -682,6 +682,40 @@ public class NumberColumnTest {
     }
   }
 
+  @Test
+  public void testCumMax() {
+    double[] originalValues = new double[] {MISSING, 32, 42, MISSING, 57, 52, -10, 0};
+    double[] expectedValues = new double[] {MISSING, 32, 42, 42, 57, 57, 57, 57};
+    DoubleColumn initial = DoubleColumn.create("Test", originalValues);
+    DoubleColumn cumMax = initial.cumMax();
+
+    assertEquals(
+        expectedValues.length, cumMax.size(), "Both sets of data should be the same size.");
+
+    for (int index = 0; index < cumMax.size(); index++) {
+      double actual = cumMax.get(index);
+      assertEquals(
+          expectedValues[index], actual, 0, "cumMax() operation at index:" + index + " failed");
+    }
+  }
+
+  @Test
+  public void testCumMin() {
+    double[] originalValues = new double[] {MISSING, 32, 42, MISSING, 57, 52, -10, 0};
+    double[] expectedValues = new double[] {MISSING, 32, 32, 32, 32, 32, -10, -10};
+    DoubleColumn initial = DoubleColumn.create("Test", originalValues);
+    DoubleColumn cumMin = initial.cumMin();
+
+    assertEquals(
+        expectedValues.length, cumMin.size(), "Both sets of data should be the same size.");
+
+    for (int index = 0; index < cumMin.size(); index++) {
+      double actual = cumMin.get(index);
+      assertEquals(
+          expectedValues[index], actual, 0, "cumMin() operation at index:" + index + " failed");
+    }
+  }
+
   @Test
   public void testSubtract2Columns() {
     double[] col1Values = new double[] {32.5, MISSING, 42, 57, 52};