You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by jb...@apache.org on 2017/12/05 04:20:42 UTC

[2/5] lucene-solr:branch_7x: SOLR-11485: Add olsRegress, spline and derivative Stream Evaluators

SOLR-11485: Add olsRegress, spline and derivative Stream Evaluators


Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/e3e98c68
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/e3e98c68
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/e3e98c68

Branch: refs/heads/branch_7x
Commit: e3e98c68471024c35537ac2d422d376920626a5f
Parents: 415990e
Author: Joel Bernstein <jb...@apache.org>
Authored: Mon Dec 4 21:08:58 2017 -0500
Committer: Joel Bernstein <jb...@apache.org>
Committed: Mon Dec 4 21:44:57 2017 -0500

----------------------------------------------------------------------
 .../org/apache/solr/handler/StreamHandler.java  |   6 +-
 .../solrj/io/eval/AbsoluteValueEvaluator.java   |   3 +-
 .../client/solrj/io/eval/AnovaEvaluator.java    |   2 +-
 .../solrj/io/eval/ArcCosineEvaluator.java       |   3 +-
 .../client/solrj/io/eval/ArcSineEvaluator.java  |   3 +-
 .../solrj/io/eval/ArcTangentEvaluator.java      |   2 +-
 .../client/solrj/io/eval/CeilingEvaluator.java  |   3 +-
 .../solrj/io/eval/ConvolutionEvaluator.java     |   4 +-
 .../solrj/io/eval/CorrelationEvaluator.java     |  12 +-
 .../client/solrj/io/eval/CosineEvaluator.java   |   3 +-
 .../io/eval/CosineSimilarityEvaluator.java      |   4 +-
 .../solrj/io/eval/CovarianceEvaluator.java      |   4 +-
 .../solrj/io/eval/CubedRootEvaluator.java       |   3 +-
 .../solrj/io/eval/DerivativeEvaluator.java      |  63 ++++++++
 .../client/solrj/io/eval/DescribeEvaluator.java |   2 +-
 .../client/solrj/io/eval/DistanceEvaluator.java |  16 +-
 .../solrj/io/eval/DotProductEvaluator.java      |   4 +-
 .../client/solrj/io/eval/EBEAddEvaluator.java   |   4 +-
 .../solrj/io/eval/EBEDivideEvaluator.java       |   4 +-
 .../solrj/io/eval/EBEMultiplyEvaluator.java     |   4 +-
 .../solrj/io/eval/EBESubtractEvaluator.java     |   4 +-
 .../io/eval/EmpiricalDistributionEvaluator.java |   2 +-
 .../eval/EnumeratedDistributionEvaluator.java   |   6 +-
 .../solrj/io/eval/FactorialEvaluator.java       |   2 +-
 .../solrj/io/eval/FieldValueEvaluator.java      |  11 +-
 .../solrj/io/eval/FindDelayEvaluator.java       |   4 +-
 .../client/solrj/io/eval/FloorEvaluator.java    |   3 +-
 .../solrj/io/eval/HarmonicFitEvaluator.java     |   6 +-
 .../io/eval/HyperbolicCosineEvaluator.java      |   3 +-
 .../solrj/io/eval/HyperbolicSineEvaluator.java  |   3 +-
 .../client/solrj/io/eval/LoessEvaluator.java    |  34 +++-
 .../solrj/io/eval/MeanDifferenceEvaluator.java  |   4 +-
 .../solrj/io/eval/NaturalLogEvaluator.java      |   3 +-
 .../solrj/io/eval/OLSRegressionEvaluator.java   | 123 +++++++++++++++
 .../io/eval/PolyFitDerivativeEvaluator.java     |  12 +-
 .../client/solrj/io/eval/PolyFitEvaluator.java  |  12 +-
 .../client/solrj/io/eval/PredictEvaluator.java  |  73 +++++++--
 .../client/solrj/io/eval/RankEvaluator.java     |   2 +-
 .../solrj/io/eval/RecursiveEvaluator.java       |   7 +-
 .../io/eval/RecursiveNumericEvaluator.java      |   7 +-
 .../solrj/io/eval/RegressionEvaluator.java      |  14 +-
 .../solrj/io/eval/ResidualsEvaluator.java       |  83 ----------
 .../client/solrj/io/eval/RoundEvaluator.java    |   3 +-
 .../client/solrj/io/eval/SineEvaluator.java     |   3 +-
 .../client/solrj/io/eval/SplineEvaluator.java   |  78 +++++++++
 .../solrj/io/eval/SquareRootEvaluator.java      |   3 +-
 .../solrj/io/eval/SumDifferenceEvaluator.java   |   4 +-
 .../client/solrj/io/eval/TangentEvaluator.java  |   3 +-
 .../io/eval/TimeDifferencingEvaluator.java      |   3 +-
 .../client/solrj/io/eval/VectorFunction.java    |  56 +++++++
 .../solrj/io/stream/StreamExpressionTest.java   | 157 +++++++++++++------
 51 files changed, 615 insertions(+), 262 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e3e98c68/solr/core/src/java/org/apache/solr/handler/StreamHandler.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/handler/StreamHandler.java b/solr/core/src/java/org/apache/solr/handler/StreamHandler.java
index 9446463..e3491f6 100644
--- a/solr/core/src/java/org/apache/solr/handler/StreamHandler.java
+++ b/solr/core/src/java/org/apache/solr/handler/StreamHandler.java
@@ -221,7 +221,6 @@ public class StreamHandler extends RequestHandlerBase implements SolrCoreAware,
         .withFunctionName("sequence", SequenceEvaluator.class)
         .withFunctionName("addAll", AppendEvaluator.class)
         .withFunctionName("append", AppendEvaluator.class)
-        .withFunctionName("residuals", ResidualsEvaluator.class)
         .withFunctionName("plot", PlotStream.class)
         .withFunctionName("normalDistribution", NormalDistributionEvaluator.class)
         .withFunctionName("uniformDistribution", UniformDistributionEvaluator.class)
@@ -259,7 +258,6 @@ public class StreamHandler extends RequestHandlerBase implements SolrCoreAware,
         .withFunctionName("gammaDistribution", GammaDistributionEvaluator.class)
         .withFunctionName("betaDistribution", BetaDistributionEvaluator.class)
         .withFunctionName("polyfit", PolyFitEvaluator.class)
-        .withFunctionName("polyfitDerivative", PolyFitDerivativeEvaluator.class)
         .withFunctionName("harmonicFit", HarmonicFitEvaluator.class)
         .withFunctionName("loess", LoessEvaluator.class)
         .withFunctionName("matrix", MatrixEvaluator.class)
@@ -280,6 +278,10 @@ public class StreamHandler extends RequestHandlerBase implements SolrCoreAware,
         .withFunctionName("corrPValues", CorrelationSignificanceEvaluator.class)
         .withFunctionName("normalizeSum", NormalizeSumEvaluator.class)
         .withFunctionName("geometricDistribution", GeometricDistributionEvaluator.class)
+        .withFunctionName("olsRegress", OLSRegressionEvaluator.class)
+        .withFunctionName("derivative", DerivativeEvaluator.class)
+        .withFunctionName("spline", SplineEvaluator.class)
+
 
         // Boolean Stream Evaluators
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e3e98c68/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/AbsoluteValueEvaluator.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/AbsoluteValueEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/AbsoluteValueEvaluator.java
index b5cc1c7..c6b9446 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/AbsoluteValueEvaluator.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/AbsoluteValueEvaluator.java
@@ -44,8 +44,7 @@ public class AbsoluteValueEvaluator extends RecursiveNumericEvaluator implements
       return ((List<?>)value).stream().map(innerValue -> doWork(innerValue));
     }
     else{
-      // we know it's a BigDecimal
-      return Math.abs(((BigDecimal)value).doubleValue());
+      return Math.abs(((Number)value).doubleValue());
     }
   }
 }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e3e98c68/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/AnovaEvaluator.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/AnovaEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/AnovaEvaluator.java
index c1d6d93..dec0655 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/AnovaEvaluator.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/AnovaEvaluator.java
@@ -48,7 +48,7 @@ public class AnovaEvaluator extends RecursiveNumericListEvaluator implements Man
     
     List<double[]> anovaInput = Arrays.stream(values)
         // for each List, convert to double[]
-        .map(value -> ((List<BigDecimal>)value).stream().mapToDouble(BigDecimal::doubleValue).toArray())
+        .map(value -> ((List<Number>)value).stream().mapToDouble(Number::doubleValue).toArray())
         // turn into List<double[]>
         .collect(Collectors.toList());
     

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e3e98c68/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/ArcCosineEvaluator.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/ArcCosineEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/ArcCosineEvaluator.java
index 7dfe992..57d7e7f 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/ArcCosineEvaluator.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/ArcCosineEvaluator.java
@@ -45,8 +45,7 @@ public class ArcCosineEvaluator extends RecursiveNumericEvaluator implements One
       return ((List<?>)value).stream().map(innerValue -> doWork(innerValue)).collect(Collectors.toList());
     }
     else{
-      // we know it's a BigDecimal
-      return Math.acos(((BigDecimal)value).doubleValue());
+      return Math.acos(((Number)value).doubleValue());
     }
   }
 }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e3e98c68/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/ArcSineEvaluator.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/ArcSineEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/ArcSineEvaluator.java
index 0750621..a3554d9 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/ArcSineEvaluator.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/ArcSineEvaluator.java
@@ -45,8 +45,7 @@ public class ArcSineEvaluator extends RecursiveNumericEvaluator implements OneVa
       return ((List<?>)value).stream().map(innerValue -> doWork(innerValue)).collect(Collectors.toList());
     }
     else{
-      // we know it's a BigDecimal
-      return Math.asin(((BigDecimal)value).doubleValue());
+      return Math.asin(((Number)value).doubleValue());
     }
   }
 }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e3e98c68/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/ArcTangentEvaluator.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/ArcTangentEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/ArcTangentEvaluator.java
index 95901ee..26ef73d 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/ArcTangentEvaluator.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/ArcTangentEvaluator.java
@@ -46,7 +46,7 @@ public class ArcTangentEvaluator extends RecursiveNumericEvaluator implements On
     }
     else{
       // we know it's a BigDecimal
-      return Math.atan(((BigDecimal)value).doubleValue());
+      return Math.atan(((Number)value).doubleValue());
     }
   }
 }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e3e98c68/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/CeilingEvaluator.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/CeilingEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/CeilingEvaluator.java
index 7f11900..761adb2 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/CeilingEvaluator.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/CeilingEvaluator.java
@@ -45,8 +45,7 @@ public class CeilingEvaluator extends RecursiveNumericEvaluator implements OneVa
       return ((List<?>)value).stream().map(innerValue -> doWork(innerValue)).collect(Collectors.toList());
     }
     else{
-      // we know it's a BigDecimal
-      return Math.ceil(((BigDecimal)value).doubleValue());
+      return Math.ceil(((Number)value).doubleValue());
     }
   }
 }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e3e98c68/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/ConvolutionEvaluator.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/ConvolutionEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/ConvolutionEvaluator.java
index 0d1816a..1ec38f4 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/ConvolutionEvaluator.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/ConvolutionEvaluator.java
@@ -51,8 +51,8 @@ public class ConvolutionEvaluator extends RecursiveNumericEvaluator implements T
 
     return Arrays.stream(
         MathArrays.convolve(
-          ((List)first).stream().mapToDouble(value -> ((BigDecimal)value).doubleValue()).toArray(),
-          ((List)second).stream().mapToDouble(value -> ((BigDecimal)value).doubleValue()).toArray()
+          ((List)first).stream().mapToDouble(value -> ((Number)value).doubleValue()).toArray(),
+          ((List)second).stream().mapToDouble(value -> ((Number)value).doubleValue()).toArray()
         )
     ).mapToObj(Double::new).collect(Collectors.toList());
   }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e3e98c68/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/CorrelationEvaluator.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/CorrelationEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/CorrelationEvaluator.java
index 481160c..8087248 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/CorrelationEvaluator.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/CorrelationEvaluator.java
@@ -81,21 +81,21 @@ public class CorrelationEvaluator extends RecursiveObjectEvaluator implements Ma
       if (type.equals(CorrelationType.pearsons)) {
         PearsonsCorrelation pearsonsCorrelation = new PearsonsCorrelation();
         return pearsonsCorrelation.correlation(
-            ((List) first).stream().mapToDouble(value -> ((BigDecimal) value).doubleValue()).toArray(),
-            ((List) second).stream().mapToDouble(value -> ((BigDecimal) value).doubleValue()).toArray()
+            ((List) first).stream().mapToDouble(value -> ((Number) value).doubleValue()).toArray(),
+            ((List) second).stream().mapToDouble(value -> ((Number) value).doubleValue()).toArray()
         );
       } else if (type.equals(CorrelationType.kendalls)) {
         KendallsCorrelation kendallsCorrelation = new KendallsCorrelation();
         return kendallsCorrelation.correlation(
-            ((List) first).stream().mapToDouble(value -> ((BigDecimal) value).doubleValue()).toArray(),
-            ((List) second).stream().mapToDouble(value -> ((BigDecimal) value).doubleValue()).toArray()
+            ((List) first).stream().mapToDouble(value -> ((Number) value).doubleValue()).toArray(),
+            ((List) second).stream().mapToDouble(value -> ((Number) value).doubleValue()).toArray()
         );
 
       } else if (type.equals(CorrelationType.spearmans)) {
         SpearmansCorrelation spearmansCorrelation = new SpearmansCorrelation();
         return spearmansCorrelation.correlation(
-            ((List) first).stream().mapToDouble(value -> ((BigDecimal) value).doubleValue()).toArray(),
-            ((List) second).stream().mapToDouble(value -> ((BigDecimal) value).doubleValue()).toArray()
+            ((List) first).stream().mapToDouble(value -> ((Number) value).doubleValue()).toArray(),
+            ((List) second).stream().mapToDouble(value -> ((Number) value).doubleValue()).toArray()
         );
       } else {
         return null;

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e3e98c68/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/CosineEvaluator.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/CosineEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/CosineEvaluator.java
index 4904d1b..c301f19 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/CosineEvaluator.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/CosineEvaluator.java
@@ -45,8 +45,7 @@ public class CosineEvaluator extends RecursiveNumericEvaluator implements OneVal
       return ((List<?>)value).stream().map(innerValue -> doWork(innerValue)).collect(Collectors.toList());
     }
     else{
-      // we know it's a BigDecimal
-      return Math.cos(((BigDecimal)value).doubleValue());
+      return Math.cos(((Number)value).doubleValue());
     }
   }
 }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e3e98c68/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/CosineSimilarityEvaluator.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/CosineSimilarityEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/CosineSimilarityEvaluator.java
index ea88400..37fa1cf 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/CosineSimilarityEvaluator.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/CosineSimilarityEvaluator.java
@@ -46,8 +46,8 @@ public class CosineSimilarityEvaluator extends RecursiveNumericEvaluator impleme
       throw new IOException(String.format(Locale.ROOT,"Invalid expression %s - found type %s for the second value, expecting a list of numbers",toExpression(constructingFactory), first.getClass().getSimpleName()));
     }
 
-    double[] d1 = ((List) first).stream().mapToDouble(value -> ((BigDecimal) value).doubleValue()).toArray();
-    double[] d2 = ((List) second).stream().mapToDouble(value -> ((BigDecimal) value).doubleValue()).toArray();
+    double[] d1 = ((List) first).stream().mapToDouble(value -> ((Number) value).doubleValue()).toArray();
+    double[] d2 = ((List) second).stream().mapToDouble(value -> ((Number) value).doubleValue()).toArray();
 
     return cosineSimilarity(d1, d2);
   }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e3e98c68/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/CovarianceEvaluator.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/CovarianceEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/CovarianceEvaluator.java
index 810ab33..9480578 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/CovarianceEvaluator.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/CovarianceEvaluator.java
@@ -41,8 +41,8 @@ public class CovarianceEvaluator extends RecursiveObjectEvaluator implements Man
       Covariance covariance = new Covariance();
 
       return covariance.covariance(
-          ((List) first).stream().mapToDouble(value -> ((BigDecimal) value).doubleValue()).toArray(),
-          ((List) second).stream().mapToDouble(value -> ((BigDecimal) value).doubleValue()).toArray()
+          ((List) first).stream().mapToDouble(value -> ((Number) value).doubleValue()).toArray(),
+          ((List) second).stream().mapToDouble(value -> ((Number) value).doubleValue()).toArray()
       );
     } else if(values.length == 1) {
       Matrix matrix = (Matrix) values[0];

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e3e98c68/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/CubedRootEvaluator.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/CubedRootEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/CubedRootEvaluator.java
index e041707..c0613f8 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/CubedRootEvaluator.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/CubedRootEvaluator.java
@@ -45,8 +45,7 @@ public class CubedRootEvaluator extends RecursiveNumericEvaluator implements One
       return ((List<?>)value).stream().map(innerValue -> doWork(innerValue)).collect(Collectors.toList());
     }
     else{
-      // we know it's a BigDecimal
-      return Math.cbrt(((BigDecimal)value).doubleValue());
+      return Math.cbrt(((Number)value).doubleValue());
     }
   }
 }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e3e98c68/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/DerivativeEvaluator.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/DerivativeEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/DerivativeEvaluator.java
new file mode 100644
index 0000000..183a47b
--- /dev/null
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/DerivativeEvaluator.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.solr.client.solrj.io.eval;
+
+import java.io.IOException;
+import java.util.Locale;
+
+import org.apache.commons.math3.analysis.DifferentiableUnivariateFunction;
+import org.apache.commons.math3.analysis.UnivariateFunction;
+import org.apache.solr.client.solrj.io.stream.expr.StreamExpression;
+import org.apache.solr.client.solrj.io.stream.expr.StreamFactory;
+
+public class DerivativeEvaluator extends RecursiveObjectEvaluator implements OneValueWorker {
+  protected static final long serialVersionUID = 1L;
+
+  public DerivativeEvaluator(StreamExpression expression, StreamFactory factory) throws IOException{
+    super(expression, factory);
+  }
+
+  @Override
+  public Object doWork(Object value) throws IOException {
+    if (null == value) {
+      throw new IOException(String.format(Locale.ROOT, "Invalid expression %s - null found for the first value", toExpression(constructingFactory)));
+    }
+
+    if (!(value instanceof VectorFunction)) {
+      throw new IOException(String.format(Locale.ROOT, "Invalid expression %s - found type %s for the first value, expecting a FunctionVector", toExpression(constructingFactory), value.getClass().getSimpleName()));
+    }
+
+    VectorFunction vectorFunction = (VectorFunction) value;
+    if(!(vectorFunction.getFunction() instanceof DifferentiableUnivariateFunction)) {
+      throw new IOException("Cannot evaluate derivative from parameter.");
+    }
+
+    DifferentiableUnivariateFunction func = (DifferentiableUnivariateFunction)vectorFunction.getFunction();
+    double[] x = (double[])vectorFunction.getFromContext("x");
+    UnivariateFunction derfunc = func.derivative();
+    double[] dvalues = new double[x.length];
+    for(int i=0; i<x.length; i++) {
+      dvalues[i] = derfunc.value(x[i]);
+    }
+
+    VectorFunction vf = new VectorFunction(derfunc, dvalues);
+    vf.addToContext("x", x);
+    vf.addToContext("y", vectorFunction.getFromContext("y"));
+
+    return vf;
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e3e98c68/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/DescribeEvaluator.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/DescribeEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/DescribeEvaluator.java
index 4509a8c..ca06cf6 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/DescribeEvaluator.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/DescribeEvaluator.java
@@ -48,7 +48,7 @@ public class DescribeEvaluator extends RecursiveNumericEvaluator implements OneV
     
     // we know each value is a BigDecimal or a list of BigDecimals
     DescriptiveStatistics descriptiveStatistics = new DescriptiveStatistics();
-    ((List<?>)value).stream().mapToDouble(innerValue -> ((BigDecimal)innerValue).doubleValue()).forEach(innerValue -> descriptiveStatistics.addValue(innerValue));
+    ((List<?>)value).stream().mapToDouble(innerValue -> ((Number)innerValue).doubleValue()).forEach(innerValue -> descriptiveStatistics.addValue(innerValue));
 
     Map<String,Number> map = new HashMap<>();
     map.put("max", descriptiveStatistics.getMax());

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e3e98c68/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/DistanceEvaluator.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/DistanceEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/DistanceEvaluator.java
index 96712da..f8d9224 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/DistanceEvaluator.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/DistanceEvaluator.java
@@ -84,27 +84,27 @@ public class DistanceEvaluator extends RecursiveObjectEvaluator implements ManyV
       if (type.equals(DistanceType.euclidean)) {
         EuclideanDistance euclideanDistance = new EuclideanDistance();
         return euclideanDistance.compute(
-            ((List) first).stream().mapToDouble(value -> ((BigDecimal) value).doubleValue()).toArray(),
-            ((List) second).stream().mapToDouble(value -> ((BigDecimal) value).doubleValue()).toArray()
+            ((List) first).stream().mapToDouble(value -> ((Number) value).doubleValue()).toArray(),
+            ((List) second).stream().mapToDouble(value -> ((Number) value).doubleValue()).toArray()
         );
       } else if (type.equals(DistanceType.manhattan)) {
         ManhattanDistance manhattanDistance = new ManhattanDistance();
         return manhattanDistance.compute(
-            ((List) first).stream().mapToDouble(value -> ((BigDecimal) value).doubleValue()).toArray(),
-            ((List) second).stream().mapToDouble(value -> ((BigDecimal) value).doubleValue()).toArray()
+            ((List) first).stream().mapToDouble(value -> ((Number) value).doubleValue()).toArray(),
+            ((List) second).stream().mapToDouble(value -> ((Number) value).doubleValue()).toArray()
         );
 
       } else if (type.equals(DistanceType.canberra)) {
         CanberraDistance canberraDistance = new CanberraDistance();
         return canberraDistance.compute(
-            ((List) first).stream().mapToDouble(value -> ((BigDecimal) value).doubleValue()).toArray(),
-            ((List) second).stream().mapToDouble(value -> ((BigDecimal) value).doubleValue()).toArray()
+            ((List) first).stream().mapToDouble(value -> ((Number) value).doubleValue()).toArray(),
+            ((List) second).stream().mapToDouble(value -> ((Number) value).doubleValue()).toArray()
         );
       } else if (type.equals(DistanceType.earthMovers)) {
         EarthMoversDistance earthMoversDistance = new EarthMoversDistance();
         return earthMoversDistance.compute(
-            ((List) first).stream().mapToDouble(value -> ((BigDecimal) value).doubleValue()).toArray(),
-            ((List) second).stream().mapToDouble(value -> ((BigDecimal) value).doubleValue()).toArray()
+            ((List) first).stream().mapToDouble(value -> ((Number) value).doubleValue()).toArray(),
+            ((List) second).stream().mapToDouble(value -> ((Number) value).doubleValue()).toArray()
         );
       } else {
         return null;

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e3e98c68/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/DotProductEvaluator.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/DotProductEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/DotProductEvaluator.java
index 3133bac..059849f 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/DotProductEvaluator.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/DotProductEvaluator.java
@@ -49,8 +49,8 @@ public class DotProductEvaluator extends RecursiveNumericEvaluator implements Tw
       throw new IOException(String.format(Locale.ROOT,"Invalid expression %s - found type %s for the second value, expecting a list of numbers",toExpression(constructingFactory), first.getClass().getSimpleName()));
     }
 
-    RealVector v = new ArrayRealVector(((List) first).stream().mapToDouble(value -> ((BigDecimal) value).doubleValue()).toArray());
-    RealVector v2 = new ArrayRealVector(((List) second).stream().mapToDouble(value -> ((BigDecimal) value).doubleValue()).toArray());
+    RealVector v = new ArrayRealVector(((List) first).stream().mapToDouble(value -> ((Number) value).doubleValue()).toArray());
+    RealVector v2 = new ArrayRealVector(((List) second).stream().mapToDouble(value -> ((Number) value).doubleValue()).toArray());
 
     return v.dotProduct(v2);
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e3e98c68/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/EBEAddEvaluator.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/EBEAddEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/EBEAddEvaluator.java
index c1eec9b..241d818 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/EBEAddEvaluator.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/EBEAddEvaluator.java
@@ -49,8 +49,8 @@ public class EBEAddEvaluator extends RecursiveNumericEvaluator implements TwoVal
     }
 
     double[] result =  MathArrays.ebeAdd(
-        ((List) first).stream().mapToDouble(value -> ((BigDecimal) value).doubleValue()).toArray(),
-        ((List) second).stream().mapToDouble(value -> ((BigDecimal) value).doubleValue()).toArray()
+        ((List) first).stream().mapToDouble(value -> ((Number) value).doubleValue()).toArray(),
+        ((List) second).stream().mapToDouble(value -> ((Number) value).doubleValue()).toArray()
     );
 
     List<Number> numbers = new ArrayList();

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e3e98c68/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/EBEDivideEvaluator.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/EBEDivideEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/EBEDivideEvaluator.java
index c457f68..a3abfa9 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/EBEDivideEvaluator.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/EBEDivideEvaluator.java
@@ -49,8 +49,8 @@ public class EBEDivideEvaluator extends RecursiveNumericEvaluator implements Two
     }
 
     double[] result =  MathArrays.ebeDivide(
-        ((List) first).stream().mapToDouble(value -> ((BigDecimal) value).doubleValue()).toArray(),
-        ((List) second).stream().mapToDouble(value -> ((BigDecimal) value).doubleValue()).toArray()
+        ((List) first).stream().mapToDouble(value -> ((Number) value).doubleValue()).toArray(),
+        ((List) second).stream().mapToDouble(value -> ((Number) value).doubleValue()).toArray()
     );
 
     List<Number> numbers = new ArrayList();

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e3e98c68/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/EBEMultiplyEvaluator.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/EBEMultiplyEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/EBEMultiplyEvaluator.java
index b3617cd..a9d3a41 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/EBEMultiplyEvaluator.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/EBEMultiplyEvaluator.java
@@ -49,8 +49,8 @@ public class EBEMultiplyEvaluator extends RecursiveNumericEvaluator implements T
     }
 
     double[] result =  MathArrays.ebeMultiply(
-        ((List) first).stream().mapToDouble(value -> ((BigDecimal) value).doubleValue()).toArray(),
-        ((List) second).stream().mapToDouble(value -> ((BigDecimal) value).doubleValue()).toArray()
+        ((List) first).stream().mapToDouble(value -> ((Number) value).doubleValue()).toArray(),
+        ((List) second).stream().mapToDouble(value -> ((Number) value).doubleValue()).toArray()
     );
 
     List<Number> numbers = new ArrayList();

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e3e98c68/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/EBESubtractEvaluator.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/EBESubtractEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/EBESubtractEvaluator.java
index 2f2f022..2a0de32 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/EBESubtractEvaluator.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/EBESubtractEvaluator.java
@@ -49,8 +49,8 @@ public class EBESubtractEvaluator extends RecursiveNumericEvaluator implements T
     }
 
     double[] result =  MathArrays.ebeSubtract(
-        ((List) first).stream().mapToDouble(value -> ((BigDecimal) value).doubleValue()).toArray(),
-        ((List) second).stream().mapToDouble(value -> ((BigDecimal) value).doubleValue()).toArray()
+        ((List) first).stream().mapToDouble(value -> ((Number) value).doubleValue()).toArray(),
+        ((List) second).stream().mapToDouble(value -> ((Number) value).doubleValue()).toArray()
     );
 
     List<Number> numbers = new ArrayList();

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e3e98c68/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/EmpiricalDistributionEvaluator.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/EmpiricalDistributionEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/EmpiricalDistributionEvaluator.java
index e89db56..ccf02e2 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/EmpiricalDistributionEvaluator.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/EmpiricalDistributionEvaluator.java
@@ -45,7 +45,7 @@ public class EmpiricalDistributionEvaluator extends RecursiveNumericEvaluator im
 
     EmpiricalDistribution empiricalDistribution = new EmpiricalDistribution();
     
-    double[] backingValues = ((List<?>)value).stream().mapToDouble(innerValue -> ((BigDecimal)innerValue).doubleValue()).sorted().toArray();
+    double[] backingValues = ((List<?>)value).stream().mapToDouble(innerValue -> ((Number)innerValue).doubleValue()).sorted().toArray();
     empiricalDistribution.load(backingValues);
 
     return empiricalDistribution;

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e3e98c68/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/EnumeratedDistributionEvaluator.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/EnumeratedDistributionEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/EnumeratedDistributionEvaluator.java
index 4a8b7f7..7e36e26 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/EnumeratedDistributionEvaluator.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/EnumeratedDistributionEvaluator.java
@@ -41,13 +41,13 @@ public class EnumeratedDistributionEvaluator extends RecursiveNumericEvaluator i
 
     if(values.length == 1) {
       List<Number> first = (List<Number>)values[0];
-      int[] samples = ((List) first).stream().mapToInt(value -> ((BigDecimal) value).intValue()).toArray();
+      int[] samples = ((List) first).stream().mapToInt(value -> ((Number) value).intValue()).toArray();
       return new EnumeratedIntegerDistribution(samples);
     } else {
       List<Number> first = (List<Number>)values[0];
       List<Number> second = (List<Number>)values[1];
-      int[] singletons = ((List) first).stream().mapToInt(value -> ((BigDecimal) value).intValue()).toArray();
-      double[] probs = ((List) second).stream().mapToDouble(value -> ((BigDecimal) value).doubleValue()).toArray();
+      int[] singletons = ((List) first).stream().mapToInt(value -> ((Number) value).intValue()).toArray();
+      double[] probs = ((List) second).stream().mapToDouble(value -> ((Number) value).doubleValue()).toArray();
       return new EnumeratedIntegerDistribution(singletons, probs);
     }
   }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e3e98c68/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/FactorialEvaluator.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/FactorialEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/FactorialEvaluator.java
index bd8f88d..e394495 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/FactorialEvaluator.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/FactorialEvaluator.java
@@ -48,7 +48,7 @@ public class FactorialEvaluator extends RecursiveNumericEvaluator implements One
       return ((List<?>)value).stream().map(innerValue -> doWork(innerValue)).collect(Collectors.toList());
     }
     else{
-      return CombinatoricsUtils.factorialDouble(((BigDecimal)value).intValue());
+      return CombinatoricsUtils.factorialDouble(((Number)value).intValue());
     }
   }
 }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e3e98c68/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/FieldValueEvaluator.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/FieldValueEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/FieldValueEvaluator.java
index 066fcc9..fac4274 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/FieldValueEvaluator.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/FieldValueEvaluator.java
@@ -72,8 +72,9 @@ public class FieldValueEvaluator extends SourceEvaluator {
         return list;
       } else if(value instanceof Matrix) {
         return value;
-      }
-      else if(value instanceof Iterable && !(value instanceof List<?>)){
+      } else if(value instanceof VectorFunction) {
+        return value;
+      } else if(value instanceof Iterable && !(value instanceof List<?>)){
         Iterable<?> iter = (Iterable<?>)value;
         List<Object> list = new ArrayList<Object>();
         for(Object obj : iter){
@@ -82,7 +83,11 @@ public class FieldValueEvaluator extends SourceEvaluator {
         return list;
       }
     }
-    
+
+    if(value == null) {
+      return fieldName;
+    }
+
     return value;
   }
   

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e3e98c68/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/FindDelayEvaluator.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/FindDelayEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/FindDelayEvaluator.java
index f50a521..58486ab 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/FindDelayEvaluator.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/FindDelayEvaluator.java
@@ -53,10 +53,10 @@ public class FindDelayEvaluator extends RecursiveNumericEvaluator implements Two
     }
 
     // Get first and second lists as arrays, where second is in reverse order
-    double[] firstArray = ((List)first).stream().mapToDouble(value -> ((BigDecimal)value).doubleValue()).toArray();
+    double[] firstArray = ((List)first).stream().mapToDouble(value -> ((Number)value).doubleValue()).toArray();
     double[] secondArray = StreamSupport.stream(Spliterators.spliteratorUnknownSize(
         ((LinkedList)((List)second).stream().collect(Collectors.toCollection(LinkedList::new))).descendingIterator(),
-        Spliterator.ORDERED), false).mapToDouble(value -> ((BigDecimal)value).doubleValue()).toArray();
+        Spliterator.ORDERED), false).mapToDouble(value -> ((Number)value).doubleValue()).toArray();
     
     double[] convolution = MathArrays.convolve(firstArray, secondArray);
     double maxValue = -Double.MAX_VALUE;

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e3e98c68/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/FloorEvaluator.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/FloorEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/FloorEvaluator.java
index c6d8b84..26cd54f 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/FloorEvaluator.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/FloorEvaluator.java
@@ -45,8 +45,7 @@ public class FloorEvaluator extends RecursiveNumericEvaluator implements OneValu
       return ((List<?>)value).stream().map(innerValue -> doWork(innerValue)).collect(Collectors.toList());
     }
     else{
-      // we know it's a BigDecimal
-      return Math.floor(((BigDecimal)value).doubleValue());
+      return Math.floor(((Number)value).doubleValue());
     }
   }
 }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e3e98c68/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/HarmonicFitEvaluator.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/HarmonicFitEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/HarmonicFitEvaluator.java
index 09ed8df..932c113 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/HarmonicFitEvaluator.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/HarmonicFitEvaluator.java
@@ -49,7 +49,7 @@ public class HarmonicFitEvaluator extends RecursiveNumericEvaluator implements M
     if(objects.length == 1) {
       //Only the y values passed
 
-      y = ((List) first).stream().mapToDouble(value -> ((BigDecimal) value).doubleValue()).toArray();
+      y = ((List) first).stream().mapToDouble(value -> ((Number) value).doubleValue()).toArray();
       x = new double[y.length];
       for(int i=0; i<y.length; i++) {
         x[i] = i;
@@ -58,8 +58,8 @@ public class HarmonicFitEvaluator extends RecursiveNumericEvaluator implements M
     } else if(objects.length == 2) {
         // x and y passed
         Object second = objects[1];
-        x = ((List) first).stream().mapToDouble(value -> ((BigDecimal) value).doubleValue()).toArray();
-        y = ((List) second).stream().mapToDouble(value -> ((BigDecimal) value).doubleValue()).toArray();
+        x = ((List) first).stream().mapToDouble(value -> ((Number) value).doubleValue()).toArray();
+        y = ((List) second).stream().mapToDouble(value -> ((Number) value).doubleValue()).toArray();
 
 
     }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e3e98c68/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/HyperbolicCosineEvaluator.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/HyperbolicCosineEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/HyperbolicCosineEvaluator.java
index a9e7c0a..883aad2 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/HyperbolicCosineEvaluator.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/HyperbolicCosineEvaluator.java
@@ -45,8 +45,7 @@ public class HyperbolicCosineEvaluator extends RecursiveNumericEvaluator impleme
       return ((List<?>)value).stream().map(innerValue -> doWork(innerValue)).collect(Collectors.toList());
     }
     else{
-      // we know it's a BigDecimal
-      return Math.cosh(((BigDecimal)value).doubleValue());
+      return Math.cosh(((Number)value).doubleValue());
     }
   }
 }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e3e98c68/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/HyperbolicSineEvaluator.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/HyperbolicSineEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/HyperbolicSineEvaluator.java
index c23f64e..e4d1fed 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/HyperbolicSineEvaluator.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/HyperbolicSineEvaluator.java
@@ -45,8 +45,7 @@ public class HyperbolicSineEvaluator extends RecursiveNumericEvaluator implement
       return ((List<?>)value).stream().map(innerValue -> doWork(innerValue)).collect(Collectors.toList());
     }
     else{
-      // we know it's a BigDecimal
-      return Math.sinh(((BigDecimal)value).doubleValue());
+      return Math.sinh(((Number)value).doubleValue());
     }
   }
 }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e3e98c68/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/LoessEvaluator.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/LoessEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/LoessEvaluator.java
index 5824f61..31f6962 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/LoessEvaluator.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/LoessEvaluator.java
@@ -17,11 +17,13 @@
 package org.apache.solr.client.solrj.io.eval;
 
 import java.io.IOException;
-import java.math.BigDecimal;
 import java.util.List;
 import java.util.ArrayList;
+import java.util.Map;
 
 import org.apache.commons.math3.analysis.interpolation.LoessInterpolator;
+import org.apache.commons.math3.analysis.polynomials.PolynomialSplineFunction;
+import org.apache.solr.client.solrj.io.Tuple;
 import org.apache.solr.client.solrj.io.stream.expr.StreamExpression;
 import org.apache.solr.client.solrj.io.stream.expr.StreamExpressionNamedParameter;
 import org.apache.solr.client.solrj.io.stream.expr.StreamFactory;
@@ -59,25 +61,45 @@ public class LoessEvaluator extends RecursiveNumericEvaluator implements ManyVal
 
     if(objects.length == 1) {
       //Only the y values passed
-      y = ((List) first).stream().mapToDouble(value -> ((BigDecimal) value).doubleValue()).toArray();
+      y = ((List) first).stream().mapToDouble(value -> ((Number) value).doubleValue()).toArray();
       x = new double[y.length];
       for(int i=0; i<y.length; i++) {
         x[i] = i;
       }
     } else if(objects.length == 2) {
       Object second = objects[1];
-      x = ((List) first).stream().mapToDouble(value -> ((BigDecimal) value).doubleValue()).toArray();
-      y = ((List) second).stream().mapToDouble(value -> ((BigDecimal) value).doubleValue()).toArray();
+      x = ((List) first).stream().mapToDouble(value -> ((Number) value).doubleValue()).toArray();
+      y = ((List) second).stream().mapToDouble(value -> ((Number) value).doubleValue()).toArray();
     }
 
     LoessInterpolator interpolator = new LoessInterpolator(bandwidth, robustIterations);
     double[] smooth = interpolator.smooth(x, y);
 
-    List list = new ArrayList();
+    List<Number> list = new ArrayList();
     for(double yvalue : smooth) {
       list.add(yvalue);
     }
 
-    return list;
+    PolynomialSplineFunction spline = interpolator.interpolate(x, y);
+
+    VectorFunction vec = new VectorFunction(spline, list);
+    vec.addToContext("x", x);
+    vec.addToContext("y", y);
+
+    return vec;
+  }
+
+
+  public static class LoessRegressionTuple extends Tuple {
+    private PolynomialSplineFunction spline;
+
+    public LoessRegressionTuple(PolynomialSplineFunction spline, Map<?,?> map) {
+      super(map);
+      this.spline = spline;
+    }
+
+    public double predict(double value) {
+      return spline.value(value);
+    }
   }
 }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e3e98c68/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/MeanDifferenceEvaluator.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/MeanDifferenceEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/MeanDifferenceEvaluator.java
index c93c97a..ff9ddb1 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/MeanDifferenceEvaluator.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/MeanDifferenceEvaluator.java
@@ -48,8 +48,8 @@ public class MeanDifferenceEvaluator extends RecursiveNumericEvaluator implement
     }
 
     return StatUtils.meanDifference(
-        ((List) first).stream().mapToDouble(value -> ((BigDecimal) value).doubleValue()).toArray(),
-        ((List) second).stream().mapToDouble(value -> ((BigDecimal) value).doubleValue()).toArray()
+        ((List) first).stream().mapToDouble(value -> ((Number) value).doubleValue()).toArray(),
+        ((List) second).stream().mapToDouble(value -> ((Number) value).doubleValue()).toArray()
     );
   }
 }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e3e98c68/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/NaturalLogEvaluator.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/NaturalLogEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/NaturalLogEvaluator.java
index b59ba38..54b62a0 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/NaturalLogEvaluator.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/NaturalLogEvaluator.java
@@ -45,8 +45,7 @@ public class NaturalLogEvaluator extends RecursiveNumericEvaluator implements On
       return ((List<?>)value).stream().map(innerValue -> doWork(innerValue)).collect(Collectors.toList());
     }
     else{
-      // we know it's a BigDecimal
-      return Math.log(((BigDecimal)value).doubleValue());
+      return Math.log(((Number)value).doubleValue());
     }
   }
 }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e3e98c68/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/OLSRegressionEvaluator.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/OLSRegressionEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/OLSRegressionEvaluator.java
new file mode 100644
index 0000000..c708a14
--- /dev/null
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/OLSRegressionEvaluator.java
@@ -0,0 +1,123 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.solr.client.solrj.io.eval;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.HashMap;
+
+import org.apache.commons.math3.stat.regression.MultipleLinearRegression;
+import org.apache.commons.math3.stat.regression.OLSMultipleLinearRegression;
+import org.apache.solr.client.solrj.io.Tuple;
+import org.apache.solr.client.solrj.io.stream.expr.StreamExpression;
+import org.apache.solr.client.solrj.io.stream.expr.StreamFactory;
+
+public class OLSRegressionEvaluator extends RecursiveObjectEvaluator implements ManyValueWorker {
+  protected static final long serialVersionUID = 1L;
+
+  public OLSRegressionEvaluator(StreamExpression expression, StreamFactory factory) throws IOException{
+    super(expression, factory);
+  }
+
+  @Override
+  public Object doWork(Object ... values) throws IOException {
+
+    Matrix observations = null;
+    List<Number> outcomes = null;
+
+    if(values[0] instanceof Matrix) {
+      observations = (Matrix)values[0];
+    } else {
+      throw new IOException("The first parameter for olsRegress should be the observation matrix.");
+    }
+
+    if(values[1] instanceof List) {
+      outcomes = (List) values[1];
+    } else {
+      throw new IOException("The second parameter for olsRegress should be outcome array. ");
+    }
+
+    double[][] observationData = observations.getData();
+    double[] outcomeData = new double[outcomes.size()];
+    for(int i=0; i<outcomeData.length; i++) {
+      outcomeData[i] = outcomes.get(i).doubleValue();
+    }
+
+    OLSMultipleLinearRegression multipleLinearRegression = (OLSMultipleLinearRegression)regress(observationData, outcomeData);
+
+    Map map = new HashMap();
+
+    map.put("regressandVariance", multipleLinearRegression.estimateRegressandVariance());
+    map.put("regressionParameters", list(multipleLinearRegression.estimateRegressionParameters()));
+    map.put("RSquared", multipleLinearRegression.calculateRSquared());
+    map.put("adjustedRSquared", multipleLinearRegression.calculateAdjustedRSquared());
+    map.put("residualSumSquares", multipleLinearRegression.calculateResidualSumOfSquares());
+
+    try {
+      map.put("regressionParametersStandardErrors", list(multipleLinearRegression.estimateRegressionParametersStandardErrors()));
+      map.put("regressionParametersVariance", new Matrix(multipleLinearRegression.estimateRegressionParametersVariance()));
+    } catch (Exception e) {
+      //Exception is thrown if the matrix is singular
+    }
+
+    return new MultipleRegressionTuple(multipleLinearRegression, map);
+  }
+
+  private List<Number> list(double[] values) {
+    List list = new ArrayList();
+    for(double d : values) {
+      list.add(d);
+    }
+    return list;
+  }
+
+  protected MultipleLinearRegression regress(double[][] observations, double[] outcomes) {
+    OLSMultipleLinearRegression olsMultipleLinearRegression = new OLSMultipleLinearRegression();
+    olsMultipleLinearRegression.newSampleData(outcomes, observations);
+    return olsMultipleLinearRegression;
+  }
+
+  public static class MultipleRegressionTuple extends Tuple {
+
+    private MultipleLinearRegression multipleLinearRegression;
+
+
+    public MultipleRegressionTuple(MultipleLinearRegression multipleLinearRegression, Map<?,?> map) {
+      super(map);
+      this.multipleLinearRegression = multipleLinearRegression;
+    }
+
+    public double predict(double[] values) {
+      List<Number> weights = (List<Number>)get("regressionParameters");
+      double prediction = 0.0;
+      List<Number> predictors = new ArrayList();
+      predictors.add(1.0D);
+      for(double d : values) {
+        predictors.add(d);
+      }
+      for(int i=0; i< predictors.size(); i++) {
+        prediction += weights.get(i).doubleValue()*predictors.get(i).doubleValue();
+      }
+
+      return prediction;
+    }
+  }
+}
+

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e3e98c68/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/PolyFitDerivativeEvaluator.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/PolyFitDerivativeEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/PolyFitDerivativeEvaluator.java
index 1aacb9e..7756938 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/PolyFitDerivativeEvaluator.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/PolyFitDerivativeEvaluator.java
@@ -52,7 +52,7 @@ public class PolyFitDerivativeEvaluator extends RecursiveNumericEvaluator implem
     if(objects.length == 1) {
       //Only the y values passed
 
-      y = ((List) first).stream().mapToDouble(value -> ((BigDecimal) value).doubleValue()).toArray();
+      y = ((List) first).stream().mapToDouble(value -> ((Number) value).doubleValue()).toArray();
       x = new double[y.length];
       for(int i=0; i<y.length; i++) {
         x[i] = i;
@@ -62,18 +62,18 @@ public class PolyFitDerivativeEvaluator extends RecursiveNumericEvaluator implem
       // x, y and degree passed
 
       Object second = objects[1];
-      x = ((List) first).stream().mapToDouble(value -> ((BigDecimal) value).doubleValue()).toArray();
-      y = ((List) second).stream().mapToDouble(value -> ((BigDecimal) value).doubleValue()).toArray();
+      x = ((List) first).stream().mapToDouble(value -> ((Number) value).doubleValue()).toArray();
+      y = ((List) second).stream().mapToDouble(value -> ((Number) value).doubleValue()).toArray();
       degree = ((Number)objects[2]).intValue();
     } else if(objects.length == 2) {
       if(objects[1] instanceof List) {
         // x and y passed
         Object second = objects[1];
-        x = ((List) first).stream().mapToDouble(value -> ((BigDecimal) value).doubleValue()).toArray();
-        y = ((List) second).stream().mapToDouble(value -> ((BigDecimal) value).doubleValue()).toArray();
+        x = ((List) first).stream().mapToDouble(value -> ((Number) value).doubleValue()).toArray();
+        y = ((List) second).stream().mapToDouble(value -> ((Number) value).doubleValue()).toArray();
       } else {
         // y and degree passed
-        y = ((List) first).stream().mapToDouble(value -> ((BigDecimal) value).doubleValue()).toArray();
+        y = ((List) first).stream().mapToDouble(value -> ((Number) value).doubleValue()).toArray();
         x = new double[y.length];
         for(int i=0; i<y.length; i++) {
           x[i] = i;

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e3e98c68/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/PolyFitEvaluator.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/PolyFitEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/PolyFitEvaluator.java
index 2c0bf2a..0536565 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/PolyFitEvaluator.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/PolyFitEvaluator.java
@@ -51,7 +51,7 @@ public class PolyFitEvaluator extends RecursiveNumericEvaluator implements ManyV
     if(objects.length == 1) {
       //Only the y values passed
 
-      y = ((List) first).stream().mapToDouble(value -> ((BigDecimal) value).doubleValue()).toArray();
+      y = ((List) first).stream().mapToDouble(value -> ((Number) value).doubleValue()).toArray();
       x = new double[y.length];
       for(int i=0; i<y.length; i++) {
         x[i] = i;
@@ -61,18 +61,18 @@ public class PolyFitEvaluator extends RecursiveNumericEvaluator implements ManyV
       // x, y and degree passed
 
       Object second = objects[1];
-      x = ((List) first).stream().mapToDouble(value -> ((BigDecimal) value).doubleValue()).toArray();
-      y = ((List) second).stream().mapToDouble(value -> ((BigDecimal) value).doubleValue()).toArray();
+      x = ((List) first).stream().mapToDouble(value -> ((Number) value).doubleValue()).toArray();
+      y = ((List) second).stream().mapToDouble(value -> ((Number) value).doubleValue()).toArray();
       degree = ((Number)objects[2]).intValue();
     } else if(objects.length == 2) {
       if(objects[1] instanceof List) {
         // x and y passed
         Object second = objects[1];
-        x = ((List) first).stream().mapToDouble(value -> ((BigDecimal) value).doubleValue()).toArray();
-        y = ((List) second).stream().mapToDouble(value -> ((BigDecimal) value).doubleValue()).toArray();
+        x = ((List) first).stream().mapToDouble(value -> ((Number) value).doubleValue()).toArray();
+        y = ((List) second).stream().mapToDouble(value -> ((Number) value).doubleValue()).toArray();
       } else {
         // y and degree passed
-        y = ((List) first).stream().mapToDouble(value -> ((BigDecimal) value).doubleValue()).toArray();
+        y = ((List) first).stream().mapToDouble(value -> ((Number) value).doubleValue()).toArray();
         x = new double[y.length];
         for(int i=0; i<y.length; i++) {
           x[i] = i;

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e3e98c68/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/PredictEvaluator.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/PredictEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/PredictEvaluator.java
index 5d9368b..075a1b3 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/PredictEvaluator.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/PredictEvaluator.java
@@ -17,10 +17,12 @@
 package org.apache.solr.client.solrj.io.eval;
 
 import java.io.IOException;
+import java.util.ArrayList;
 import java.util.List;
 import java.util.Locale;
 import java.util.stream.Collectors;
 
+import org.apache.commons.math3.analysis.UnivariateFunction;
 import org.apache.solr.client.solrj.io.stream.expr.StreamExpression;
 import org.apache.solr.client.solrj.io.stream.expr.StreamFactory;
 
@@ -32,28 +34,65 @@ public class PredictEvaluator extends RecursiveObjectEvaluator implements TwoVal
   }
 
   @Override
-  public Object doWork(Object first, Object second) throws IOException{
-    if(null == first){
-      throw new IOException(String.format(Locale.ROOT,"Invalid expression %s - null found for the first value",toExpression(constructingFactory)));
+  public Object doWork(Object first, Object second) throws IOException {
+    if (null == first) {
+      throw new IOException(String.format(Locale.ROOT, "Invalid expression %s - null found for the first value", toExpression(constructingFactory)));
     }
-    if(null == second){
-      throw new IOException(String.format(Locale.ROOT,"Invalid expression %s - null found for the second value",toExpression(constructingFactory)));
+    if (null == second) {
+      throw new IOException(String.format(Locale.ROOT, "Invalid expression %s - null found for the second value", toExpression(constructingFactory)));
     }
-    if(!(first instanceof RegressionEvaluator.RegressionTuple)){
-      throw new IOException(String.format(Locale.ROOT,"Invalid expression %s - found type %s for the first value, expecting a RegressionTuple",toExpression(constructingFactory), first.getClass().getSimpleName()));
-    }
-    if(!(second instanceof Number) && !(second instanceof List<?>)){
-      throw new IOException(String.format(Locale.ROOT,"Invalid expression %s - found type %s for the second value, expecting a Number",toExpression(constructingFactory), first.getClass().getSimpleName()));
+
+    if (!(first instanceof VectorFunction) && !(first instanceof RegressionEvaluator.RegressionTuple) && !(first instanceof OLSRegressionEvaluator.MultipleRegressionTuple)) {
+      throw new IOException(String.format(Locale.ROOT, "Invalid expression %s - found type %s for the first value, expecting a RegressionTuple", toExpression(constructingFactory), first.getClass().getSimpleName()));
     }
-    
-    RegressionEvaluator.RegressionTuple regressedTuple = (RegressionEvaluator.RegressionTuple)first;
 
-    if(second instanceof Number){
-      return regressedTuple.predict(((Number)second).doubleValue());
+    if (!(second instanceof Number) && !(second instanceof List<?>) && !(second instanceof Matrix)) {
+      throw new IOException(String.format(Locale.ROOT, "Invalid expression %s - found type %s for the second value, expecting a Number, Array or Matrix", toExpression(constructingFactory), first.getClass().getSimpleName()));
     }
-    else{
-      return ((List<?>)second).stream().map(value -> regressedTuple.predict(((Number)value).doubleValue())).collect(Collectors.toList());
+
+    if (first instanceof RegressionEvaluator.RegressionTuple) {
+
+      RegressionEvaluator.RegressionTuple regressedTuple = (RegressionEvaluator.RegressionTuple) first;
+      if (second instanceof Number) {
+        return regressedTuple.predict(((Number) second).doubleValue());
+      } else {
+        return ((List<?>) second).stream().map(value -> regressedTuple.predict(((Number) value).doubleValue())).collect(Collectors.toList());
+      }
+
+    } else if (first instanceof OLSRegressionEvaluator.MultipleRegressionTuple) {
+
+      OLSRegressionEvaluator.MultipleRegressionTuple regressedTuple = (OLSRegressionEvaluator.MultipleRegressionTuple) first;
+      if (second instanceof List) {
+        List<Number> list = (List<Number>) second;
+        double[] predictors = new double[list.size()];
+
+        for (int i = 0; i < list.size(); i++) {
+          predictors[i] = list.get(i).doubleValue();
+        }
+
+        return regressedTuple.predict(predictors);
+      } else if (second instanceof Matrix) {
+
+        Matrix m = (Matrix) second;
+        double[][] data = m.getData();
+        List<Number> predictions = new ArrayList();
+        for (double[] predictors : data) {
+          predictions.add(regressedTuple.predict(predictors));
+        }
+        return predictions;
+      }
+
+    } else if (first instanceof VectorFunction) {
+      VectorFunction vectorFunction = (VectorFunction) first;
+      UnivariateFunction univariateFunction = (UnivariateFunction)vectorFunction.getFunction();
+      if (second instanceof Number) {
+        double x = ((Number)second).doubleValue();
+        return univariateFunction.value(x);
+      } else {
+        return ((List<?>) second).stream().map(value -> univariateFunction.value(((Number) value).doubleValue())).collect(Collectors.toList());
+      }
     }
+
+    return null;
   }
-  
 }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e3e98c68/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/RankEvaluator.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/RankEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/RankEvaluator.java
index 3b193c7..9a7665f 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/RankEvaluator.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/RankEvaluator.java
@@ -48,7 +48,7 @@ public class RankEvaluator extends RecursiveNumericEvaluator implements OneValue
       return Arrays.stream(rank.rank(((List<?>)value).stream().mapToDouble(innerValue -> ((Number)innerValue).doubleValue()).toArray())).mapToObj(Double::new).collect(Collectors.toList());
     }
     else{
-      return doWork(Arrays.asList((BigDecimal)value));
+      return doWork(Arrays.asList((Number)value));
     }
   }
 }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e3e98c68/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/RecursiveEvaluator.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/RecursiveEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/RecursiveEvaluator.java
index 6c5ae41..b94c5dc 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/RecursiveEvaluator.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/RecursiveEvaluator.java
@@ -55,6 +55,8 @@ public abstract class RecursiveEvaluator implements StreamEvaluator, ValueWorker
   protected Object normalizeInputType(Object value){
     if(null == value){
       return null;
+    } else if (value instanceof VectorFunction) {
+      return value;
     }
     else if(value instanceof Double){
       if(Double.isNaN((Double)value)){
@@ -97,8 +99,9 @@ public abstract class RecursiveEvaluator implements StreamEvaluator, ValueWorker
   protected Object normalizeOutputType(Object value) {
     if(null == value){
       return null;
-    }
-    else if(value instanceof BigDecimal){
+    } else if (value instanceof VectorFunction) {
+      return value;
+    } else if(value instanceof BigDecimal){
       BigDecimal bd = (BigDecimal)value;
       if(bd.signum() == 0 || bd.scale() <= 0 || bd.stripTrailingZeros().scale() <= 0){
         try{

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e3e98c68/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/RecursiveNumericEvaluator.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/RecursiveNumericEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/RecursiveNumericEvaluator.java
index a1cdeb5..948f003 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/RecursiveNumericEvaluator.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/RecursiveNumericEvaluator.java
@@ -34,10 +34,11 @@ public abstract class RecursiveNumericEvaluator extends RecursiveEvaluator {
   }
     
   public Object normalizeInputType(Object value) throws StreamEvaluatorException {
-    if(null == value){
+    if(null == value) {
       return null;
-    }
-    else if(value instanceof Double){
+    } else if (value instanceof VectorFunction) {
+      return value;
+    } else if(value instanceof Double){
       if(Double.isNaN((Double)value)){
         return Double.NaN;
       }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e3e98c68/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/RegressionEvaluator.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/RegressionEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/RegressionEvaluator.java
index b38b6b3..3562749 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/RegressionEvaluator.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/RegressionEvaluator.java
@@ -17,7 +17,6 @@
 package org.apache.solr.client.solrj.io.eval;
 
 import java.io.IOException;
-import java.math.BigDecimal;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Locale;
@@ -50,8 +49,8 @@ public class RegressionEvaluator extends RecursiveNumericEvaluator implements Tw
       throw new IOException(String.format(Locale.ROOT,"Invalid expression %s - found type %s for the second value, expecting a list of numbers",toExpression(constructingFactory), first.getClass().getSimpleName()));
     }
     
-    List<?> l1 = (List<?>)first;
-    List<?> l2 = (List<?>)second;
+    List<Number> l1 = (List<Number>)first;
+    List<Number> l2 = (List<Number>)second;
     
     if(l2.size() < l1.size()){
       throw new IOException(String.format(Locale.ROOT,"Invalid expression %s - first list (%d) has more values than the second list (%d)",toExpression(constructingFactory), l1.size(), l2.size()));      
@@ -59,22 +58,22 @@ public class RegressionEvaluator extends RecursiveNumericEvaluator implements Tw
 
     SimpleRegression regression = new SimpleRegression();
     for(int idx = 0; idx < l1.size(); ++idx){
-      regression.addData(((BigDecimal)l1.get(idx)).doubleValue(), ((BigDecimal)l2.get(idx)).doubleValue());
+      regression.addData(l1.get(idx).doubleValue(), l2.get(idx).doubleValue());
     }
     
-    Map<String,Number> map = new HashMap<>();
+    Map<String, Object> map = new HashMap<>();
     map.put("slope", regression.getSlope());
     map.put("intercept", regression.getIntercept());
     map.put("R", regression.getR());
     map.put("N", regression.getN());
-    map.put("RSquare", regression.getRSquare());
+    map.put("RSquared", regression.getRSquare());
     map.put("regressionSumSquares", regression.getRegressionSumSquares());
     map.put("slopeConfidenceInterval", regression.getSlopeConfidenceInterval());
     map.put("interceptStdErr", regression.getInterceptStdErr());
     map.put("totalSumSquares", regression.getTotalSumSquares());
     map.put("significance", regression.getSignificance());
     map.put("meanSquareError", regression.getMeanSquareError());
-    
+
     return new RegressionTuple(regression, map);
   }
   
@@ -90,5 +89,4 @@ public class RegressionEvaluator extends RecursiveNumericEvaluator implements Tw
       return this.simpleRegression.predict(value);
     }
   }
-
 }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e3e98c68/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/ResidualsEvaluator.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/ResidualsEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/ResidualsEvaluator.java
deleted file mode 100644
index 8c5ca34..0000000
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/ResidualsEvaluator.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.solr.client.solrj.io.eval;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Locale;
-
-import org.apache.solr.client.solrj.io.stream.expr.StreamExpression;
-import org.apache.solr.client.solrj.io.stream.expr.StreamFactory;
-
-public class ResidualsEvaluator extends RecursiveObjectEvaluator implements ManyValueWorker {
-  protected static final long serialVersionUID = 1L;
-  
-  public ResidualsEvaluator(StreamExpression expression, StreamFactory factory) throws IOException{
-    super(expression, factory);
-  }
-
-  @Override
-  public Object doWork(Object ... values) throws IOException{
-    if(3 != values.length){
-      throw new IOException(String.format(Locale.ROOT,"Invalid expression %s - three values expected but found %d",toExpression(constructingFactory), values.length));
-    }
-    
-    if(Arrays.stream(values).filter(value -> null == value).count() > 0){
-      throw new IOException(String.format(Locale.ROOT,"Invalid expression %s - null value found",toExpression(constructingFactory)));
-    }
-
-    if(!(values[0] instanceof RegressionEvaluator.RegressionTuple)){
-      throw new IOException(String.format(Locale.ROOT,"Invalid expression %s - found type %s for the first value, expecting a RegressionTuple",toExpression(constructingFactory), values[0].getClass().getSimpleName()));
-    }
-    if(!(values[1] instanceof List<?>)){
-      throw new IOException(String.format(Locale.ROOT,"Invalid expression %s - found type %s for the second value, expecting a list",toExpression(constructingFactory), values[1].getClass().getSimpleName()));
-    }
-    if(!(values[2] instanceof List<?>)){
-      throw new IOException(String.format(Locale.ROOT,"Invalid expression %s - found type %s for the third value, expecting a list",toExpression(constructingFactory), values[2].getClass().getSimpleName()));
-    }
-    if(((List<?>)values[1]).stream().filter(value -> !(value instanceof Number)).count() > 0){
-      throw new IOException(String.format(Locale.ROOT,"Invalid expression %s - expecting a list of numbers for the second value",toExpression(constructingFactory)));
-    }
-    if(((List<?>)values[2]).stream().filter(value -> !(value instanceof Number)).count() > 0){
-      throw new IOException(String.format(Locale.ROOT,"Invalid expression %s - expecting a list of numbers for the third value",toExpression(constructingFactory)));
-    }    
-    
-    RegressionEvaluator.RegressionTuple regressedTuple = (RegressionEvaluator.RegressionTuple)values[0];
-    List<?> l1 = (List<?>)values[1];
-    List<?> l2 = (List<?>)values[2];
-    
-    if(l2.size() < l1.size()){
-      throw new IOException(String.format(Locale.ROOT,"Invalid expression %s - first list (%d) has more values than the second list (%d)",toExpression(constructingFactory), l1.size(), l2.size()));      
-    }
-    
-    List<Number> residuals = new ArrayList<>();
-    for(int idx = 0; idx < l1.size(); ++idx){
-      double value1 = ((Number)l1.get(idx)).doubleValue();
-      double value2 = ((Number)l2.get(idx)).doubleValue();
-      
-      double prediction = regressedTuple.predict(value1);
-      double residual = value2 - prediction;
-      
-      residuals.add(residual);
-    }
-    
-    return residuals;
-  }
-  
-}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e3e98c68/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/RoundEvaluator.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/RoundEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/RoundEvaluator.java
index 0cfb3d4..9f506e0 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/RoundEvaluator.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/RoundEvaluator.java
@@ -45,8 +45,7 @@ public class RoundEvaluator extends RecursiveNumericEvaluator implements OneValu
       return ((List<?>)value).stream().map(innerValue -> doWork(innerValue)).collect(Collectors.toList());
     }
     else{
-      // we know it's a BigDecimal
-      return Math.round(((BigDecimal)value).doubleValue());
+      return Math.round(((Number)value).doubleValue());
     }
   }
 }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e3e98c68/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/SineEvaluator.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/SineEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/SineEvaluator.java
index 5426100..134d378 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/SineEvaluator.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/SineEvaluator.java
@@ -45,8 +45,7 @@ public class SineEvaluator extends RecursiveNumericEvaluator implements OneValue
       return ((List<?>)value).stream().map(innerValue -> doWork(innerValue)).collect(Collectors.toList());
     }
     else{
-      // we know it's a BigDecimal
-      return Math.sin(((BigDecimal)value).doubleValue());
+      return Math.sin(((Number)value).doubleValue());
     }
   }
 }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e3e98c68/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/SplineEvaluator.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/SplineEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/SplineEvaluator.java
new file mode 100644
index 0000000..18b7fd1
--- /dev/null
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/SplineEvaluator.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.solr.client.solrj.io.eval;
+
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.util.HashMap;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Map;
+
+import org.apache.commons.math3.analysis.UnivariateFunction;
+import org.apache.commons.math3.analysis.interpolation.SplineInterpolator;
+import org.apache.commons.math3.analysis.polynomials.PolynomialSplineFunction;
+import org.apache.commons.math3.stat.regression.SimpleRegression;
+import org.apache.solr.client.solrj.io.Tuple;
+import org.apache.solr.client.solrj.io.stream.expr.StreamExpression;
+import org.apache.solr.client.solrj.io.stream.expr.StreamExpressionNamedParameter;
+import org.apache.solr.client.solrj.io.stream.expr.StreamFactory;
+
+public class SplineEvaluator extends RecursiveNumericEvaluator implements ManyValueWorker {
+  protected static final long serialVersionUID = 1L;
+
+  public SplineEvaluator(StreamExpression expression, StreamFactory factory) throws IOException{
+    super(expression, factory);
+  }
+
+  @Override
+  public Object doWork(Object... objects) throws IOException{
+
+    Object first = objects[0];
+
+    double[] x = null;
+    double[] y = null;
+
+    if(objects.length == 1) {
+      //Only the y values passed
+      y = ((List) first).stream().mapToDouble(value -> ((Number) value).doubleValue()).toArray();
+      x = new double[y.length];
+      for(int i=0; i<y.length; i++) {
+        x[i] = i;
+      }
+    } else if(objects.length == 2) {
+      Object second = objects[1];
+      x = ((List) first).stream().mapToDouble(value -> ((Number) value).doubleValue()).toArray();
+      y = ((List) second).stream().mapToDouble(value -> ((Number) value).doubleValue()).toArray();
+    }
+
+    SplineInterpolator interpolator = new SplineInterpolator();
+    PolynomialSplineFunction spline = interpolator.interpolate(x, y);
+
+    List<Number> list = new ArrayList();
+    for(double xvalue : x) {
+      list.add(spline.value(xvalue));
+    }
+
+    VectorFunction vec = new VectorFunction(spline, list);
+    vec.addToContext("x", x);
+    vec.addToContext("y", y);
+
+    return vec;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e3e98c68/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/SquareRootEvaluator.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/SquareRootEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/SquareRootEvaluator.java
index e20109e..0e8e427 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/SquareRootEvaluator.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/SquareRootEvaluator.java
@@ -45,8 +45,7 @@ public class SquareRootEvaluator extends RecursiveNumericEvaluator implements On
       return ((List<?>)value).stream().map(innerValue -> doWork(innerValue)).collect(Collectors.toList());
     }
     else{
-      // we know it's a BigDecimal
-      return Math.sqrt(((BigDecimal)value).doubleValue());
+      return Math.sqrt(((Number)value).doubleValue());
     }
   }
 }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e3e98c68/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/SumDifferenceEvaluator.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/SumDifferenceEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/SumDifferenceEvaluator.java
index 7402888..0b8a51f 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/SumDifferenceEvaluator.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/SumDifferenceEvaluator.java
@@ -48,8 +48,8 @@ public class SumDifferenceEvaluator extends RecursiveNumericEvaluator implements
     }
 
     return StatUtils.sumDifference(
-        ((List) first).stream().mapToDouble(value -> ((BigDecimal) value).doubleValue()).toArray(),
-        ((List) second).stream().mapToDouble(value -> ((BigDecimal) value).doubleValue()).toArray()
+        ((List) first).stream().mapToDouble(value -> ((Number) value).doubleValue()).toArray(),
+        ((List) second).stream().mapToDouble(value -> ((Number) value).doubleValue()).toArray()
     );
   }
 }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e3e98c68/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/TangentEvaluator.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/TangentEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/TangentEvaluator.java
index eb7e4dc..7b951cd 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/TangentEvaluator.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/TangentEvaluator.java
@@ -45,8 +45,7 @@ public class TangentEvaluator extends RecursiveNumericEvaluator implements OneVa
       return ((List<?>)value).stream().map(innerValue -> doWork(innerValue)).collect(Collectors.toList());
     }
     else{
-      // we know it's a BigDecimal
-      return Math.tan(((BigDecimal)value).doubleValue());
+      return Math.tan(((Number)value).doubleValue());
     }
   }
 }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/e3e98c68/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/TimeDifferencingEvaluator.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/TimeDifferencingEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/TimeDifferencingEvaluator.java
index bd26b79..6424d0a 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/TimeDifferencingEvaluator.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/TimeDifferencingEvaluator.java
@@ -18,7 +18,6 @@
 package org.apache.solr.client.solrj.io.eval;
 
 import java.io.IOException;
-import java.math.BigDecimal;
 import java.util.List;
 import java.util.Locale;
 import java.util.stream.Collectors;
@@ -42,7 +41,7 @@ public class TimeDifferencingEvaluator extends RecursiveNumericEvaluator impleme
     if (!(1 == values.length ||  values.length == 2)){
       throw new IOException(String.format(Locale.ROOT,"%s(...) only works with 1 or 2 values but %d were provided", constructingFactory.getFunctionName(getClass()), values.length));
     }
-    List<BigDecimal> timeseriesValues = (List<BigDecimal> )values[0];
+    List<Number> timeseriesValues = (List<Number> )values[0];
     Number lagValue = 1;
 
     if(1 == values.length) {