From 16211410a5d151c54047040ba497edef82d26461 Mon Sep 17 00:00:00 2001 From: leahmcguire Date: Wed, 27 Mar 2019 16:13:54 -0700 Subject: [PATCH 01/10] converted math transformers to standard binary transformers --- .../op/dsl/RichNumericFeature.scala | 66 ++--------- .../impl/feature/MathTransformers.scala | 104 ++++++++++++++++++ 2 files changed, 112 insertions(+), 58 deletions(-) create mode 100644 core/src/main/scala/com/salesforce/op/stages/impl/feature/MathTransformers.scala diff --git a/core/src/main/scala/com/salesforce/op/dsl/RichNumericFeature.scala b/core/src/main/scala/com/salesforce/op/dsl/RichNumericFeature.scala index 3c5006c264..1d73cf21de 100644 --- a/core/src/main/scala/com/salesforce/op/dsl/RichNumericFeature.scala +++ b/core/src/main/scala/com/salesforce/op/dsl/RichNumericFeature.scala @@ -71,22 +71,8 @@ trait RichNumericFeature { * @tparam I2 that feature output type * @return transformed feature */ - def /[I2 <: OPNumeric[_] : TypeTag](that: FeatureLike[I2]): FeatureLike[Real] = { - f.transformWith[I2, Real]( - stage = new BinaryLambdaTransformer[I, I2, Real]( - operationName = "divide", - transformFn = (i1: I, i2: I2) => { - val result = for { - x <- i1.toDouble - y <- i2.toDouble - } yield x / y - - result filter Number.isValid toReal - } - ), - f = that - ) - } + def /[I2 <: OPNumeric[_] : TypeTag](that: FeatureLike[I2]): FeatureLike[Real] = + new DivideTransformer[I, I2]().setInput(f, that).getOutput() /** * Apply Multiply transformer shortcut function @@ -102,22 +88,8 @@ trait RichNumericFeature { * @tparam I2 that feature output type * @return transformed feature */ - def *[I2 <: OPNumeric[_] : TypeTag](that: FeatureLike[I2]): FeatureLike[Real] = { - f.transformWith[I2, Real]( - stage = new BinaryLambdaTransformer[I, I2, Real]( - operationName = "multiply", - transformFn = (i1: I, i2: I2) => { - val result = for { - x <- i1.toDouble - y <- i2.toDouble - } yield x * y - - result filter Number.isValid toReal - } - ), - f = that - ) - } + def *[I2 <: OPNumeric[_] : TypeTag](that: FeatureLike[I2]): FeatureLike[Real] = + new MultiplyTransformer[I, I2]().setInput(f, that).getOutput() /** * Apply Plus transformer shortcut function @@ -133,15 +105,8 @@ trait RichNumericFeature { * @tparam I2 that feature output type * @return transformed feature */ - def +[I2 <: OPNumeric[_] : TypeTag](that: FeatureLike[I2]): FeatureLike[Real] = { - f.transformWith[I2, Real]( - stage = new BinaryLambdaTransformer[I, I2, Real]( - operationName = "plus", - transformFn = (i1: I, i2: I2) => (i1.toDouble -> i2.toDouble).map(_ + _).toReal - ), - f = that - ) - } + def +[I2 <: OPNumeric[_] : TypeTag](that: FeatureLike[I2]): FeatureLike[Real] = + new AdditionTransformer[I, I2]().setInput(f, that).getOutput() /** * Apply Minus transformer shortcut function @@ -157,23 +122,8 @@ trait RichNumericFeature { * @tparam I2 that feature output type * @return transformed feature */ - def -[I2 <: OPNumeric[_] : TypeTag](that: FeatureLike[I2]): FeatureLike[Real] = { - f.transformWith[I2, Real]( - stage = new BinaryLambdaTransformer[I, I2, Real]( - operationName = "minus", - transformFn = (i1: I, i2: I2) => { - val optZ = (i1.toDouble, i2.toDouble) match { - case (Some(x), Some(y)) => Some(x - y) - case (Some(x), None) => Some(x) - case (None, Some(y)) => Some(-y) - case (None, None) => None - } - optZ.toReal - } - ), - f = that - ) - } + def -[I2 <: OPNumeric[_] : TypeTag](that: FeatureLike[I2]): FeatureLike[Real] = + new SubtractionTransformer[I, I2]().setInput(f, that).getOutput() /** * Apply Divide scalar transformer shortcut function diff --git a/core/src/main/scala/com/salesforce/op/stages/impl/feature/MathTransformers.scala b/core/src/main/scala/com/salesforce/op/stages/impl/feature/MathTransformers.scala new file mode 100644 index 0000000000..320e98426b --- /dev/null +++ b/core/src/main/scala/com/salesforce/op/stages/impl/feature/MathTransformers.scala @@ -0,0 +1,104 @@ +package com.salesforce.op.stages.impl.feature + +import com.salesforce.op.UID +import com.salesforce.op.features.types._ +import com.salesforce.op.stages.base.binary.BinaryTransformer +import com.salesforce.op.utils.numeric.Number +import com.salesforce.op.utils.tuples.RichTuple._ + +import scala.reflect.runtime.universe.TypeTag + +/** + * Plus function truth table (Real as example): + * + * Real.empty + Real.empty = Real.empty + * Real.empty + Real(x) = Real(x) + * Real(x) + Real.empty = Real(x) + * Real(x) + Real(y) = Real(x + y) + **/ +class AdditionTransformer[I1 <: OPNumeric[_], I2 <: OPNumeric[_]] +( + uid: String = UID[AdditionTransformer[_, _]] +)( + implicit override val tti1: TypeTag[I1], + override val tti2: TypeTag[I2] +) extends BinaryTransformer[I1, I2, Real](operationName = "addition", uid = uid){ + override def transformFn: (I1, I2) => Real = (i1: I1, i2: I2) => (i1.toDouble -> i2.toDouble).map(_ + _).toReal +} + +/** + * Minus function truth table (Real as example): + * + * Real.empty - Real.empty = Real.empty + * Real.empty - Real(x) = Real(-x) + * Real(x) - Real.empty = Real(x) + * Real(x) - Real(y) = Real(x - y) + */ +class SubtractionTransformer[I1 <: OPNumeric[_], I2 <: OPNumeric[_]] +( + uid: String = UID[SubtractionTransformer[_, _]] +)( + implicit override val tti1: TypeTag[I1], + override val tti2: TypeTag[I2] +) extends BinaryTransformer[I1, I2, Real](operationName = "minus", uid = uid){ + override def transformFn: (I1, I2) => Real = (i1: I1, i2: I2) => { + val optZ = (i1.toDouble, i2.toDouble) match { + case (Some(x), Some(y)) => Some(x - y) + case (Some(x), None) => Some(x) + case (None, Some(y)) => Some(-y) + case (None, None) => None + } + optZ.toReal + } +} + + +/** + * Multiply function truth table (Real as example): + * + * Real.empty * Real.empty = Real.empty + * Real.empty * Real(x) = Real.empty + * Real(x) * Real.empty = Real.empty + * Real(x) * Real(y) = Real(x * y) filter ("is not NaN or Infinity") + */ +class MultiplyTransformer[I1 <: OPNumeric[_], I2 <: OPNumeric[_]] +( + uid: String = UID[MultiplyTransformer[_, _]] +)( + implicit override val tti1: TypeTag[I1], + override val tti2: TypeTag[I2] +) extends BinaryTransformer[I1, I2, Real](operationName = "multiply", uid = uid){ + override def transformFn: (I1, I2) => Real = (i1: I1, i2: I2) => { + val result = for { + x <- i1.toDouble + y <- i2.toDouble + } yield x * y + + result filter Number.isValid toReal + } +} + +/** + * Divide function truth table (Real as example): + * + * Real.empty / Real.empty = Real.empty + * Real.empty / Real(x) = Real.empty + * Real(x) / Real.empty = Real.empty + * Real(x) / Real(y) = Real(x * y) filter ("is not NaN or Infinity") + */ +class DivideTransformer[I1 <: OPNumeric[_], I2 <: OPNumeric[_]] +( + uid: String = UID[MultiplyTransformer[_, _]] +)( + implicit override val tti1: TypeTag[I1], + override val tti2: TypeTag[I2] +) extends BinaryTransformer[I1, I2, Real](operationName = "divide", uid = uid){ + override def transformFn: (I1, I2) => Real = (i1: I1, i2: I2) => { + val result = for { + x <- i1.toDouble + y <- i2.toDouble + } yield x / y + + result filter Number.isValid toReal + } +} From 5901083cab9968ea08f2ad617f860b3d81d986f8 Mon Sep 17 00:00:00 2001 From: leahmcguire Date: Thu, 28 Mar 2019 11:50:37 -0700 Subject: [PATCH 02/10] made concrete math transformers --- .../op/dsl/RichNumericFeature.scala | 50 +++------- .../impl/feature/MathTransformers.scala | 96 ++++++++++++++++++- .../op/dsl/RichNumericFeatureTest.scala | 52 ++++++++-- 3 files changed, 151 insertions(+), 47 deletions(-) diff --git a/core/src/main/scala/com/salesforce/op/dsl/RichNumericFeature.scala b/core/src/main/scala/com/salesforce/op/dsl/RichNumericFeature.scala index 1d73cf21de..fc821553bc 100644 --- a/core/src/main/scala/com/salesforce/op/dsl/RichNumericFeature.scala +++ b/core/src/main/scala/com/salesforce/op/dsl/RichNumericFeature.scala @@ -32,13 +32,9 @@ package com.salesforce.op.dsl import com.salesforce.op.features.FeatureLike import com.salesforce.op.features.types._ -import com.salesforce.op.stages.base.binary.BinaryLambdaTransformer -import com.salesforce.op.stages.base.unary.UnaryLambdaTransformer import com.salesforce.op.stages.impl.feature._ -import com.salesforce.op.stages.impl.preparators.{CorrelationType, CorrelationExclusion, SanityChecker} +import com.salesforce.op.stages.impl.preparators.{CorrelationExclusion, CorrelationType, SanityChecker} import com.salesforce.op.stages.impl.regression.IsotonicRegressionCalibrator -import com.salesforce.op.utils.tuples.RichTuple._ -import com.salesforce.op.utils.numeric.Number import scala.language.postfixOps import scala.reflect.ClassTag @@ -72,7 +68,7 @@ trait RichNumericFeature { * @return transformed feature */ def /[I2 <: OPNumeric[_] : TypeTag](that: FeatureLike[I2]): FeatureLike[Real] = - new DivideTransformer[I, I2]().setInput(f, that).getOutput() + f.transformWith(new DivideTransformer[I, I2](), that) /** * Apply Multiply transformer shortcut function @@ -89,7 +85,7 @@ trait RichNumericFeature { * @return transformed feature */ def *[I2 <: OPNumeric[_] : TypeTag](that: FeatureLike[I2]): FeatureLike[Real] = - new MultiplyTransformer[I, I2]().setInput(f, that).getOutput() + f.transformWith(new MultiplyTransformer[I, I2](), that) /** * Apply Plus transformer shortcut function @@ -106,7 +102,7 @@ trait RichNumericFeature { * @return transformed feature */ def +[I2 <: OPNumeric[_] : TypeTag](that: FeatureLike[I2]): FeatureLike[Real] = - new AdditionTransformer[I, I2]().setInput(f, that).getOutput() + f.transformWith(new AddTransformer[I, I2](), that) /** * Apply Minus transformer shortcut function @@ -123,7 +119,7 @@ trait RichNumericFeature { * @return transformed feature */ def -[I2 <: OPNumeric[_] : TypeTag](that: FeatureLike[I2]): FeatureLike[Real] = - new SubtractionTransformer[I, I2]().setInput(f, that).getOutput() + f.transformWith(new SubtractTransformer[I, I2](), that) /** * Apply Divide scalar transformer shortcut function @@ -133,13 +129,8 @@ trait RichNumericFeature { * @tparam N value type * @return transformed feature */ - def /[N](v: N)(implicit n: Numeric[N]): FeatureLike[Real] = { - f.transformWith( - new UnaryLambdaTransformer[I, Real]( - operationName = "divideS", - transformFn = r => r.toDouble.map(_ / n.toDouble(v)).filter(Number.isValid).toReal) - ) - } + def /[N](v: N)(implicit n: Numeric[N]): FeatureLike[Real] = + f.transformWith(new ScalarDivideTransformer(scalar = v)) /** * Apply Multiply scalar transformer shortcut function @@ -149,13 +140,8 @@ trait RichNumericFeature { * @tparam N value type * @return transformed feature */ - def *[N](v: N)(implicit n: Numeric[N]): FeatureLike[Real] = { - f.transformWith( - new UnaryLambdaTransformer[I, Real]( - operationName = "multiplyS", - transformFn = r => r.toDouble.map(_ * n.toDouble(v)).filter(Number.isValid).toReal) - ) - } + def *[N](v: N)(implicit n: Numeric[N]): FeatureLike[Real] = + f.transformWith(new ScalarMultiplyTransformer(scalar = v)) /** * Apply Plus scalar transformer shortcut function @@ -165,13 +151,8 @@ trait RichNumericFeature { * @tparam N value type * @return transformed feature */ - def +[N](v: N)(implicit n: Numeric[N]): FeatureLike[Real] = { - f.transformWith( - new UnaryLambdaTransformer[I, Real]( - operationName = "plusS", - transformFn = r => r.toDouble.map(_ + n.toDouble(v)).toReal) - ) - } + def +[N](v: N)(implicit n: Numeric[N]): FeatureLike[Real] = + f.transformWith(new ScalarAddTransformer[I, N](scalar = v)) /** * Apply Minus scalar transformer shortcut function @@ -181,13 +162,8 @@ trait RichNumericFeature { * @tparam N value type * @return transformed feature */ - def -[N](v: N)(implicit n: Numeric[N]): FeatureLike[Real] = { - f.transformWith( - new UnaryLambdaTransformer[I, Real]( - operationName = "minusS", - transformFn = r => r.toDouble.map(_ - n.toDouble(v)).toReal) - ) - } + def -[N](v: N)(implicit n: Numeric[N]): FeatureLike[Real] = + f.transformWith(new ScalarSubtractTransformer[I, N](scalar = v)) } diff --git a/core/src/main/scala/com/salesforce/op/stages/impl/feature/MathTransformers.scala b/core/src/main/scala/com/salesforce/op/stages/impl/feature/MathTransformers.scala index 320e98426b..21e173985d 100644 --- a/core/src/main/scala/com/salesforce/op/stages/impl/feature/MathTransformers.scala +++ b/core/src/main/scala/com/salesforce/op/stages/impl/feature/MathTransformers.scala @@ -3,6 +3,7 @@ package com.salesforce.op.stages.impl.feature import com.salesforce.op.UID import com.salesforce.op.features.types._ import com.salesforce.op.stages.base.binary.BinaryTransformer +import com.salesforce.op.stages.base.unary.UnaryTransformer import com.salesforce.op.utils.numeric.Number import com.salesforce.op.utils.tuples.RichTuple._ @@ -16,9 +17,9 @@ import scala.reflect.runtime.universe.TypeTag * Real(x) + Real.empty = Real(x) * Real(x) + Real(y) = Real(x + y) **/ -class AdditionTransformer[I1 <: OPNumeric[_], I2 <: OPNumeric[_]] +class AddTransformer[I1 <: OPNumeric[_], I2 <: OPNumeric[_]] ( - uid: String = UID[AdditionTransformer[_, _]] + uid: String = UID[AddTransformer[_, _]] )( implicit override val tti1: TypeTag[I1], override val tti2: TypeTag[I2] @@ -26,6 +27,28 @@ class AdditionTransformer[I1 <: OPNumeric[_], I2 <: OPNumeric[_]] override def transformFn: (I1, I2) => Real = (i1: I1, i2: I2) => (i1.toDouble -> i2.toDouble).map(_ + _).toReal } +/** + * Scalar addition transformer + * + * @param scalar scalar value + * @param uid uid for instance + * @param tti type tag for input + * @param n value converter + * @tparam I input feature type + * @tparam N value type + */ +class ScalarAddTransformer[I <: OPNumeric[_], N] +( + val scalar: N, + uid: String = UID[ScalarAddTransformer[_, _]] +)( + implicit override val tti: TypeTag[I], + n: Numeric[N] +) extends UnaryTransformer[I, Real](operationName = "scalarAddition", uid = uid){ + override def transformFn: I => Real = (i: I) => i.toDouble.map(_ + n.toDouble(scalar)).toReal +} + + /** * Minus function truth table (Real as example): * @@ -34,9 +57,9 @@ class AdditionTransformer[I1 <: OPNumeric[_], I2 <: OPNumeric[_]] * Real(x) - Real.empty = Real(x) * Real(x) - Real(y) = Real(x - y) */ -class SubtractionTransformer[I1 <: OPNumeric[_], I2 <: OPNumeric[_]] +class SubtractTransformer[I1 <: OPNumeric[_], I2 <: OPNumeric[_]] ( - uid: String = UID[SubtractionTransformer[_, _]] + uid: String = UID[SubtractTransformer[_, _]] )( implicit override val tti1: TypeTag[I1], override val tti2: TypeTag[I2] @@ -53,6 +76,27 @@ class SubtractionTransformer[I1 <: OPNumeric[_], I2 <: OPNumeric[_]] } +/** + * Scalar subtract transformer + * + * @param scalar scalar value + * @param uid uid for instance + * @param tti type tag for input + * @param n value converter + * @tparam I input feature type + * @tparam N value type + */ +class ScalarSubtractTransformer[I <: OPNumeric[_], N] +( + val scalar: N, + uid: String = UID[ScalarSubtractTransformer[_, _]] +)( + implicit override val tti: TypeTag[I], + n: Numeric[N] +) extends UnaryTransformer[I, Real](operationName = "scalarSubtract", uid = uid){ + override def transformFn: I => Real = (i: I) => i.toDouble.map(_ - n.toDouble(scalar)).toReal +} + /** * Multiply function truth table (Real as example): * @@ -78,6 +122,28 @@ class MultiplyTransformer[I1 <: OPNumeric[_], I2 <: OPNumeric[_]] } } +/** + * Scalar multiply transformer + * + * @param scalar scalar value + * @param uid uid for instance + * @param tti type tag for input + * @param n value converter + * @tparam I input feature type + * @tparam N value type + */ +class ScalarMultiplyTransformer[I <: OPNumeric[_], N] +( + val scalar: N, + uid: String = UID[ScalarMultiplyTransformer[_, _]] +)( + implicit override val tti: TypeTag[I], + n: Numeric[N] +) extends UnaryTransformer[I, Real](operationName = "scalarMultiply", uid = uid){ + override def transformFn: I => Real = (i: I) => i.toDouble.map(_ * n.toDouble(scalar)).filter(Number.isValid).toReal +} + + /** * Divide function truth table (Real as example): * @@ -102,3 +168,25 @@ class DivideTransformer[I1 <: OPNumeric[_], I2 <: OPNumeric[_]] result filter Number.isValid toReal } } + + +/** + * Scalar divide transformer + * + * @param scalar scalar value + * @param uid uid for instance + * @param tti type tag for input + * @param n value converter + * @tparam I input feature type + * @tparam N value type + */ +class ScalarDivideTransformer[I <: OPNumeric[_], N] +( + val scalar: N, + uid: String = UID[ScalarDivideTransformer[_, _]] +)( + implicit override val tti: TypeTag[I], + n: Numeric[N] +) extends UnaryTransformer[I, Real](operationName = "scalarDivide", uid = uid){ + override def transformFn: I => Real = (i: I) => i.toDouble.map(_ / n.toDouble(scalar)).filter(Number.isValid).toReal +} diff --git a/core/src/test/scala/com/salesforce/op/dsl/RichNumericFeatureTest.scala b/core/src/test/scala/com/salesforce/op/dsl/RichNumericFeatureTest.scala index 962c0aaf25..001d8981a7 100644 --- a/core/src/test/scala/com/salesforce/op/dsl/RichNumericFeatureTest.scala +++ b/core/src/test/scala/com/salesforce/op/dsl/RichNumericFeatureTest.scala @@ -134,15 +134,55 @@ class RichNumericFeatureTest extends FlatSpec with FeatureTestBase with RichNume // TODO: add vectorize() test } - Spec[RichRealNNFeature] should "have tests" in { - // TODO: add tests + Spec[RichRealNNFeature] should "perform math functions correctly" in { + val checkAddition = testOp[RealNN, RealNN, Real](x => y => x + y) + checkAddition of(5.0.toRealNN, 2.0.toRealNN) expecting 7.0.toReal + + val checkSubtraction = testOp[RealNN, RealNN, Real](x => y => x - y) + checkSubtraction of(5.0.toRealNN, 2.0.toRealNN) expecting 3.0.toReal + + val checkMultiplication = testOp[RealNN, RealNN, Real](x => y => x * y) + checkMultiplication of(5.0.toRealNN, 2.0.toRealNN) expecting 10.toReal + checkMultiplication of(Double.NaN.toRealNN, 2.0.toRealNN) expecting Real.empty + + val checkDivision = testOp[RealNN, RealNN, Real](x => y => x / y) + checkDivision of(5.0.toRealNN, 2.0.toRealNN) expecting 2.5.toReal + checkDivision of(2.0.toRealNN, 0.0.toRealNN) expecting Real.empty } - Spec[RichBinaryFeature] should "have tests" in { - // TODO: add tests + Spec[RichBinaryFeature] should "perform math functions" in { + val checkAddition = testOp[Binary, Binary, Real](x => y => x + y) + checkAddition of(true.toBinary, true.toBinary) expecting 2.0.toReal + checkAddition of(true.toBinary, Binary.empty) expecting 1.0.toReal + + val checkSubtraction = testOp[Binary, Binary, Real](x => y => x - y) + checkSubtraction of(true.toBinary, true.toBinary) expecting 0.0.toReal + checkSubtraction of(true.toBinary, Binary.empty) expecting 1.0.toReal + + val checkMultiplication = testOp[Binary, Binary, Real](x => y => x * y) + checkMultiplication of(true.toBinary, true.toBinary) expecting 1.0.toReal + checkMultiplication of(true.toBinary, Binary.empty) expecting Real.empty + + val checkDivision = testOp[Binary, Binary, Real](x => y => x / y) + checkDivision of(true.toBinary, true.toBinary) expecting 1.0.toReal + checkDivision of(true.toBinary, false.toBinary) expecting Real.empty } - Spec[RichIntegralFeature[_]] should "have tests" in { - // TODO: add tests + Spec[RichIntegralFeature[_]] should "perform math functions" in { + val checkAddition = testOp[Integral, Integral, Real](x => y => x + y) + checkAddition of(5.toIntegral, 2.toIntegral) expecting 7.0.toReal + checkAddition of(Integral.empty, 2.toIntegral) expecting 2.0.toReal + + val checkSubtraction = testOp[Integral, Integral, Real](x => y => x - y) + checkSubtraction of(5.toIntegral, 2.toIntegral) expecting 3.0.toReal + checkSubtraction of(Integral.empty, 2.toIntegral) expecting (-2.0).toReal + + val checkMultiplication = testOp[Integral, Integral, Real](x => y => x * y) + checkMultiplication of(5.toIntegral, 2.toIntegral) expecting 10.toReal + checkMultiplication of(Integral.empty, 2.toIntegral) expecting Real.empty + + val checkDivision = testOp[Integral, Integral, Real](x => y => x / y) + checkDivision of(5.toIntegral, 2.toIntegral) expecting 2.5.toReal + checkDivision of(2.toIntegral, 0.toIntegral) expecting Real.empty } } From 0549f5f546a3cb2997e70fddcb1c659479b283f5 Mon Sep 17 00:00:00 2001 From: leahmcguire Date: Thu, 28 Mar 2019 12:48:13 -0700 Subject: [PATCH 03/10] fixed style --- .../impl/feature/MathTransformers.scala | 32 ++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/core/src/main/scala/com/salesforce/op/stages/impl/feature/MathTransformers.scala b/core/src/main/scala/com/salesforce/op/stages/impl/feature/MathTransformers.scala index 21e173985d..0fb7f9b025 100644 --- a/core/src/main/scala/com/salesforce/op/stages/impl/feature/MathTransformers.scala +++ b/core/src/main/scala/com/salesforce/op/stages/impl/feature/MathTransformers.scala @@ -1,3 +1,33 @@ +/* + * Copyright (c) 2017, Salesforce.com, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + package com.salesforce.op.stages.impl.feature import com.salesforce.op.UID @@ -16,7 +46,7 @@ import scala.reflect.runtime.universe.TypeTag * Real.empty + Real(x) = Real(x) * Real(x) + Real.empty = Real(x) * Real(x) + Real(y) = Real(x + y) - **/ + */ class AddTransformer[I1 <: OPNumeric[_], I2 <: OPNumeric[_]] ( uid: String = UID[AddTransformer[_, _]] From 4c052cac8b42da34ab360998161e21e50ffeb8a0 Mon Sep 17 00:00:00 2001 From: leahmcguire Date: Thu, 28 Mar 2019 15:13:27 -0700 Subject: [PATCH 04/10] added ceil, floor, abs transformers --- .../impl/feature/MathTransformers.scala | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/core/src/main/scala/com/salesforce/op/stages/impl/feature/MathTransformers.scala b/core/src/main/scala/com/salesforce/op/stages/impl/feature/MathTransformers.scala index 0fb7f9b025..8a173e0a60 100644 --- a/core/src/main/scala/com/salesforce/op/stages/impl/feature/MathTransformers.scala +++ b/core/src/main/scala/com/salesforce/op/stages/impl/feature/MathTransformers.scala @@ -220,3 +220,55 @@ class ScalarDivideTransformer[I <: OPNumeric[_], N] ) extends UnaryTransformer[I, Real](operationName = "scalarDivide", uid = uid){ override def transformFn: I => Real = (i: I) => i.toDouble.map(_ / n.toDouble(scalar)).filter(Number.isValid).toReal } + + +/** + * Absolute value transformer + * + * @param uid uid for instance + * @param tti type tag for input + * @tparam I input feature type + */ +class AbsoluteValueTransformer[I <: OPNumeric[_]] +( + uid: String = UID[AbsoluteValueTransformer[_]] +)( + implicit override val tti: TypeTag[I] +) extends UnaryTransformer[I, Real](operationName = "abs", uid = uid){ + override def transformFn: I => Real = (i: I) => i.toDouble.map(math.abs).toReal +} + +/** + * Ceil transformer + * + * @param uid uid for instance + * @param tti type tag for input + * @tparam I input feature type + */ +class CeilTransformer[I <: OPNumeric[_]] +( + uid: String = UID[CeilTransformer[_]] +)( + implicit override val tti: TypeTag[I] +) extends UnaryTransformer[I, Integral](operationName = "ceil", uid = uid){ + override def transformFn: I => Integral = (i: I) => i.toDouble.map(v => math.round(math.ceil(v))).toIntegral +} + + +/** + * Floor transformer + * + * @param uid uid for instance + * @param tti type tag for input + * @tparam I input feature type + */ +class FloorTransformer[I <: OPNumeric[_]] +( + uid: String = UID[FloorTransformer[_]] +)( + implicit override val tti: TypeTag[I] +) extends UnaryTransformer[I, Integral](operationName = "floor", uid = uid){ + override def transformFn: I => Integral = (i: I) => i.toDouble.map(v => math.round(math.floor(v))).toIntegral +} + + From 69834ebf8466dd51e20dcc238b2b439e2ffb89a0 Mon Sep 17 00:00:00 2001 From: leahmcguire Date: Thu, 28 Mar 2019 15:52:13 -0700 Subject: [PATCH 05/10] put back names and added transformer spec tests --- .../impl/feature/MathTransformers.scala | 15 +-- .../impl/feature/MathTransformersTest.scala | 110 ++++++++++++++++++ 2 files changed, 118 insertions(+), 7 deletions(-) create mode 100644 core/src/test/scala/com/salesforce/op/stages/impl/feature/MathTransformersTest.scala diff --git a/core/src/main/scala/com/salesforce/op/stages/impl/feature/MathTransformers.scala b/core/src/main/scala/com/salesforce/op/stages/impl/feature/MathTransformers.scala index 0fb7f9b025..9395eace8c 100644 --- a/core/src/main/scala/com/salesforce/op/stages/impl/feature/MathTransformers.scala +++ b/core/src/main/scala/com/salesforce/op/stages/impl/feature/MathTransformers.scala @@ -53,7 +53,7 @@ class AddTransformer[I1 <: OPNumeric[_], I2 <: OPNumeric[_]] )( implicit override val tti1: TypeTag[I1], override val tti2: TypeTag[I2] -) extends BinaryTransformer[I1, I2, Real](operationName = "addition", uid = uid){ +) extends BinaryTransformer[I1, I2, Real](operationName = "plus", uid = uid){ override def transformFn: (I1, I2) => Real = (i1: I1, i2: I2) => (i1.toDouble -> i2.toDouble).map(_ + _).toReal } @@ -73,8 +73,8 @@ class ScalarAddTransformer[I <: OPNumeric[_], N] uid: String = UID[ScalarAddTransformer[_, _]] )( implicit override val tti: TypeTag[I], - n: Numeric[N] -) extends UnaryTransformer[I, Real](operationName = "scalarAddition", uid = uid){ + val n: Numeric[N] +) extends UnaryTransformer[I, Real](operationName = "scalarPlus", uid = uid){ override def transformFn: I => Real = (i: I) => i.toDouble.map(_ + n.toDouble(scalar)).toReal } @@ -122,8 +122,8 @@ class ScalarSubtractTransformer[I <: OPNumeric[_], N] uid: String = UID[ScalarSubtractTransformer[_, _]] )( implicit override val tti: TypeTag[I], - n: Numeric[N] -) extends UnaryTransformer[I, Real](operationName = "scalarSubtract", uid = uid){ + val n: Numeric[N] +) extends UnaryTransformer[I, Real](operationName = "scalarMinus", uid = uid){ override def transformFn: I => Real = (i: I) => i.toDouble.map(_ - n.toDouble(scalar)).toReal } @@ -168,7 +168,7 @@ class ScalarMultiplyTransformer[I <: OPNumeric[_], N] uid: String = UID[ScalarMultiplyTransformer[_, _]] )( implicit override val tti: TypeTag[I], - n: Numeric[N] + val n: Numeric[N] ) extends UnaryTransformer[I, Real](operationName = "scalarMultiply", uid = uid){ override def transformFn: I => Real = (i: I) => i.toDouble.map(_ * n.toDouble(scalar)).filter(Number.isValid).toReal } @@ -216,7 +216,8 @@ class ScalarDivideTransformer[I <: OPNumeric[_], N] uid: String = UID[ScalarDivideTransformer[_, _]] )( implicit override val tti: TypeTag[I], - n: Numeric[N] + val n: Numeric[N] ) extends UnaryTransformer[I, Real](operationName = "scalarDivide", uid = uid){ override def transformFn: I => Real = (i: I) => i.toDouble.map(_ / n.toDouble(scalar)).filter(Number.isValid).toReal } + diff --git a/core/src/test/scala/com/salesforce/op/stages/impl/feature/MathTransformersTest.scala b/core/src/test/scala/com/salesforce/op/stages/impl/feature/MathTransformersTest.scala new file mode 100644 index 0000000000..d58fbb8211 --- /dev/null +++ b/core/src/test/scala/com/salesforce/op/stages/impl/feature/MathTransformersTest.scala @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2017, Salesforce.com, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.salesforce.op.stages.impl.feature + +import com.salesforce.op.features.types._ +import com.salesforce.op.test.{OpTransformerSpec, TestFeatureBuilder} +import org.junit.runner.RunWith +import org.scalatest.junit.JUnitRunner + +@RunWith(classOf[JUnitRunner]) +class AddTransformerTest extends OpTransformerSpec[Real, AddTransformer[Real, Real]] { + val sample = Seq((Real(1.0), Real(2.0)), (Real(4.0), Real(4.0)), (Real.empty, Real(5.0)), + (Real(5.0), Real.empty), (Real(2.0), Real(0.0))) + val (inputData, f1, f2) = TestFeatureBuilder(sample) + val transformer: AddTransformer[Real, Real] = new AddTransformer[Real, Real]().setInput(f1, f2) + override val expectedResult: Seq[Real] = Seq(Real(3.0), Real(8.0), Real(5.0), Real(5.0), Real(2.0)) +} + +@RunWith(classOf[JUnitRunner]) +class ScalarAddTransformerTest extends OpTransformerSpec[Real, ScalarAddTransformer[Real, Double]] { + val sample = Seq(Real(1.0), Real(4.0), Real.empty, Real(-1.0), Real(2.0)) + val (inputData, f1) = TestFeatureBuilder(sample) + val transformer: ScalarAddTransformer[Real, Double] = new ScalarAddTransformer[Real, Double](5.0).setInput(f1) + override val expectedResult: Seq[Real] = Seq(Real(6.0), Real(9.0), Real.empty, Real(4.0), Real(7.0)) +} + +@RunWith(classOf[JUnitRunner]) +class SubtractTransformerTest extends OpTransformerSpec[Real, SubtractTransformer[Real, Real]] { + val sample = Seq((Real(1.0), Real(2.0)), (Real(4.0), Real(4.0)), (Real.empty, Real(5.0)), + (Real(5.0), Real.empty), (Real(2.0), Real(0.0))) + val (inputData, f1, f2) = TestFeatureBuilder(sample) + val transformer: SubtractTransformer[Real, Real] = new SubtractTransformer[Real, Real]().setInput(f1, f2) + override val expectedResult: Seq[Real] = Seq(Real(-1.0), Real(0.0), Real(-5.0), Real(5.0), Real(2.0)) +} + +@RunWith(classOf[JUnitRunner]) +class ScalarSubtractTransformerTest extends OpTransformerSpec[Real, ScalarSubtractTransformer[Real, Double]] { + val sample = Seq(Real(1.0), Real(4.0), Real.empty, Real(-1.0), Real(2.0)) + val (inputData, f1) = TestFeatureBuilder(sample) + val transformer: ScalarSubtractTransformer[Real, Double] = new ScalarSubtractTransformer[Real, Double](5.0).setInput(f1) + override val expectedResult: Seq[Real] = Seq(Real(-4.0), Real(-1.0), Real.empty, Real(-6.0), Real(-3.0)) +} + + +@RunWith(classOf[JUnitRunner]) +class MultiplyTransformerTest extends OpTransformerSpec[Real, MultiplyTransformer[Real, Real]] { + val sample = Seq((Real(1.0), Real(2.0)), (Real(4.0), Real(4.0)), (Real.empty, Real(5.0)), + (Real(5.0), Real.empty), (Real(2.0), Real(0.0))) + val (inputData, f1, f2) = TestFeatureBuilder(sample) + val transformer: MultiplyTransformer[Real, Real] = new MultiplyTransformer[Real, Real]().setInput(f1, f2) + override val expectedResult: Seq[Real] = Seq(Real(2.0), Real(16.0), Real.empty, Real.empty, Real(0.0)) +} + +@RunWith(classOf[JUnitRunner]) +class ScalarMultiplyTransformerTest extends OpTransformerSpec[Real, ScalarMultiplyTransformer[Real, Double]] { + val sample = Seq(Real(1.0), Real(4.0), Real.empty, Real(-1.0), Real(2.0)) + val (inputData, f1) = TestFeatureBuilder(sample) + val transformer: ScalarMultiplyTransformer[Real, Double] = new ScalarMultiplyTransformer[Real, Double](5.0).setInput(f1) + override val expectedResult: Seq[Real] = Seq(Real(5.0), Real(20.0), Real.empty, Real(-5.0), Real(10.0)) +} + +@RunWith(classOf[JUnitRunner]) +class DivideTransformerTest extends OpTransformerSpec[Real, DivideTransformer[Real, Real]] { + val sample = Seq((Real(1.0), Real(2.0)), (Real(4.0), Real(4.0)), (Real.empty, Real(5.0)), + (Real(5.0), Real.empty), (Real(2.0), Real(0.0))) + val (inputData, f1, f2) = TestFeatureBuilder(sample) + val transformer: DivideTransformer[Real, Real] = new DivideTransformer[Real, Real]().setInput(f1, f2) + override val expectedResult: Seq[Real] = Seq(Real(0.5), Real(1.0), Real.empty, Real.empty, Real.empty) +} + +@RunWith(classOf[JUnitRunner]) +class ScalarDivideTransformerTest extends OpTransformerSpec[Real, ScalarDivideTransformer[Real, Double]] { + val sample = Seq(Real(1.0), Real(4.0), Real.empty, Real(-1.0), Real(2.0)) + val (inputData, f1) = TestFeatureBuilder(sample) + val transformer: ScalarDivideTransformer[Real, Double] = new ScalarDivideTransformer[Real, Double](2.0).setInput(f1) + override val expectedResult: Seq[Real] = Seq(Real(0.5), Real(2.0), Real.empty, Real(-0.5), Real(1.0)) +} + + + + + From 9deaf8a58cc64873520ec14810302313ce21fb53 Mon Sep 17 00:00:00 2001 From: leahmcguire Date: Thu, 28 Mar 2019 15:58:04 -0700 Subject: [PATCH 06/10] style --- .../stages/impl/feature/MathTransformersTest.scala | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/core/src/test/scala/com/salesforce/op/stages/impl/feature/MathTransformersTest.scala b/core/src/test/scala/com/salesforce/op/stages/impl/feature/MathTransformersTest.scala index d58fbb8211..78a4df17ef 100644 --- a/core/src/test/scala/com/salesforce/op/stages/impl/feature/MathTransformersTest.scala +++ b/core/src/test/scala/com/salesforce/op/stages/impl/feature/MathTransformersTest.scala @@ -48,7 +48,8 @@ class AddTransformerTest extends OpTransformerSpec[Real, AddTransformer[Real, Re class ScalarAddTransformerTest extends OpTransformerSpec[Real, ScalarAddTransformer[Real, Double]] { val sample = Seq(Real(1.0), Real(4.0), Real.empty, Real(-1.0), Real(2.0)) val (inputData, f1) = TestFeatureBuilder(sample) - val transformer: ScalarAddTransformer[Real, Double] = new ScalarAddTransformer[Real, Double](5.0).setInput(f1) + val transformer: ScalarAddTransformer[Real, Double] = new ScalarAddTransformer[Real, Double](5.0) + .setInput(f1) override val expectedResult: Seq[Real] = Seq(Real(6.0), Real(9.0), Real.empty, Real(4.0), Real(7.0)) } @@ -65,7 +66,8 @@ class SubtractTransformerTest extends OpTransformerSpec[Real, SubtractTransforme class ScalarSubtractTransformerTest extends OpTransformerSpec[Real, ScalarSubtractTransformer[Real, Double]] { val sample = Seq(Real(1.0), Real(4.0), Real.empty, Real(-1.0), Real(2.0)) val (inputData, f1) = TestFeatureBuilder(sample) - val transformer: ScalarSubtractTransformer[Real, Double] = new ScalarSubtractTransformer[Real, Double](5.0).setInput(f1) + val transformer: ScalarSubtractTransformer[Real, Double] = new ScalarSubtractTransformer[Real, Double](5.0) + .setInput(f1) override val expectedResult: Seq[Real] = Seq(Real(-4.0), Real(-1.0), Real.empty, Real(-6.0), Real(-3.0)) } @@ -83,7 +85,8 @@ class MultiplyTransformerTest extends OpTransformerSpec[Real, MultiplyTransforme class ScalarMultiplyTransformerTest extends OpTransformerSpec[Real, ScalarMultiplyTransformer[Real, Double]] { val sample = Seq(Real(1.0), Real(4.0), Real.empty, Real(-1.0), Real(2.0)) val (inputData, f1) = TestFeatureBuilder(sample) - val transformer: ScalarMultiplyTransformer[Real, Double] = new ScalarMultiplyTransformer[Real, Double](5.0).setInput(f1) + val transformer: ScalarMultiplyTransformer[Real, Double] = new ScalarMultiplyTransformer[Real, Double](5.0) + .setInput(f1) override val expectedResult: Seq[Real] = Seq(Real(5.0), Real(20.0), Real.empty, Real(-5.0), Real(10.0)) } @@ -100,7 +103,8 @@ class DivideTransformerTest extends OpTransformerSpec[Real, DivideTransformer[Re class ScalarDivideTransformerTest extends OpTransformerSpec[Real, ScalarDivideTransformer[Real, Double]] { val sample = Seq(Real(1.0), Real(4.0), Real.empty, Real(-1.0), Real(2.0)) val (inputData, f1) = TestFeatureBuilder(sample) - val transformer: ScalarDivideTransformer[Real, Double] = new ScalarDivideTransformer[Real, Double](2.0).setInput(f1) + val transformer: ScalarDivideTransformer[Real, Double] = new ScalarDivideTransformer[Real, Double](2.0) + .setInput(f1) override val expectedResult: Seq[Real] = Seq(Real(0.5), Real(2.0), Real.empty, Real(-0.5), Real(1.0)) } From 392589be352c4c22e81a896d98c90644f95ab9ab Mon Sep 17 00:00:00 2001 From: leahmcguire Date: Mon, 1 Apr 2019 15:55:07 -0700 Subject: [PATCH 07/10] added tests --- .../op/dsl/RichNumericFeature.scala | 64 ++++++++++ .../impl/feature/MathTransformers.scala | 26 +++- .../AbsoluteValueTransformerTest.scala | 58 +++++++++ .../impl/feature/CeilTransformerTest.scala | 58 +++++++++ .../impl/feature/ExpTransformerTest.scala | 58 +++++++++ .../impl/feature/FloorTransformerTest.scala | 58 +++++++++ .../impl/feature/LogTransformerTest.scala | 58 +++++++++ .../impl/feature/MathTransformersTest.scala | 114 ------------------ .../impl/feature/PowerTransformerTest.scala | 59 +++++++++ .../feature/RoundDigitsTransformerTest.scala | 52 ++++++++ .../impl/feature/RoundTransformerTest.scala | 58 +++++++++ .../impl/feature/SqrtTransformerTest.scala | 58 +++++++++ 12 files changed, 603 insertions(+), 118 deletions(-) create mode 100644 core/src/test/scala/com/salesforce/op/stages/impl/feature/AbsoluteValueTransformerTest.scala create mode 100644 core/src/test/scala/com/salesforce/op/stages/impl/feature/CeilTransformerTest.scala create mode 100644 core/src/test/scala/com/salesforce/op/stages/impl/feature/ExpTransformerTest.scala create mode 100644 core/src/test/scala/com/salesforce/op/stages/impl/feature/FloorTransformerTest.scala create mode 100644 core/src/test/scala/com/salesforce/op/stages/impl/feature/LogTransformerTest.scala delete mode 100644 core/src/test/scala/com/salesforce/op/stages/impl/feature/MathTransformersTest.scala create mode 100644 core/src/test/scala/com/salesforce/op/stages/impl/feature/PowerTransformerTest.scala create mode 100644 core/src/test/scala/com/salesforce/op/stages/impl/feature/RoundDigitsTransformerTest.scala create mode 100644 core/src/test/scala/com/salesforce/op/stages/impl/feature/RoundTransformerTest.scala create mode 100644 core/src/test/scala/com/salesforce/op/stages/impl/feature/SqrtTransformerTest.scala diff --git a/core/src/main/scala/com/salesforce/op/dsl/RichNumericFeature.scala b/core/src/main/scala/com/salesforce/op/dsl/RichNumericFeature.scala index fc821553bc..afbdca2e0e 100644 --- a/core/src/main/scala/com/salesforce/op/dsl/RichNumericFeature.scala +++ b/core/src/main/scala/com/salesforce/op/dsl/RichNumericFeature.scala @@ -165,6 +165,70 @@ trait RichNumericFeature { def -[N](v: N)(implicit n: Numeric[N]): FeatureLike[Real] = f.transformWith(new ScalarSubtractTransformer[I, N](scalar = v)) + /** + * Take the absolute value of the feature + * @return transformed feature + */ + def abs(): FeatureLike[Real] = + f.transformWith(new AbsoluteValueTransformer[I]()) + + /** + * Take the ceil of the feature value + * @return transformed feature + */ + def ceil(): FeatureLike[Integral] = + f.transformWith(new CeilTransformer[I]()) + + /** + * Take the floor of the feature value + * @return transformed feature + */ + def floor(): FeatureLike[Integral] = + f.transformWith(new FloorTransformer[I]()) + + /** + * Round the feature value + * @return transformed feature + */ + def round(): FeatureLike[Integral] = + f.transformWith(new RoundTransformer[I]()) + + /** + * Round the feature value + * @return transformed feature + */ + def round(digits: Int): FeatureLike[Real] = + f.transformWith(new RoundDigitsTransformer[I](digits = digits)) + + /** + * Exp transformer: returns Euler's number `e` raised to the power of feature value + * @return transformed feature + */ + def exp(): FeatureLike[Real] = + f.transformWith(new ExpTransformer[I]()) + + /** + * Square root transformer + * @return transformed feature + */ + def sqrt(): FeatureLike[Real] = + f.transformWith(new SqrtTransformer[I]()) + + /** + * Square root transformer + * @return transformed feature + */ + def log[N](base: N)(implicit n: Numeric[N]): FeatureLike[Real] = + f.transformWith(new LogTransformer[I, N](base = base)) + + /** + * Square root transformer + * @return transformed feature + */ + def power[N](power: N)(implicit n: Numeric[N]): FeatureLike[Real] = + f.transformWith(new PowerTransformer[I, N](power = power)) + + } /** diff --git a/core/src/main/scala/com/salesforce/op/stages/impl/feature/MathTransformers.scala b/core/src/main/scala/com/salesforce/op/stages/impl/feature/MathTransformers.scala index 91a34e9c77..d1edd57952 100644 --- a/core/src/main/scala/com/salesforce/op/stages/impl/feature/MathTransformers.scala +++ b/core/src/main/scala/com/salesforce/op/stages/impl/feature/MathTransformers.scala @@ -272,6 +272,23 @@ class FloorTransformer[I <: OPNumeric[_]] } +/** + * Round transformer + * + * @param uid uid for instance + * @param tti type tag for input + * @tparam I input feature type + */ +class RoundTransformer[I <: OPNumeric[_]] +( + uid: String = UID[FloorTransformer[_]] +)( + implicit override val tti: TypeTag[I] +) extends UnaryTransformer[I, Integral](operationName = "floor", uid = uid){ + override def transformFn: I => Integral = (i: I) => i.toDouble.map(v => math.round(v)).toIntegral +} + + /** * Exp transformer: returns Euler's number `e` raised to the power of feature value * @@ -353,6 +370,7 @@ class PowerTransformer[I <: OPNumeric[_], N] i.toDouble.map(v => math.pow(v, n.toDouble(power))).filter(Number.isValid).toReal } + /** * Round transformer * @@ -361,16 +379,16 @@ class PowerTransformer[I <: OPNumeric[_], N] * @param tti type tag for input * @tparam I input feature type */ -class RoundTransformer[I <: OPNumeric[_]] +class RoundDigitsTransformer[I <: OPNumeric[_]] ( val digits: Int, uid: String = UID[PowerTransformer[_, _]] )( implicit override val tti: TypeTag[I] ) extends UnaryTransformer[I, Real](operationName = "round", uid = uid){ - override def transformFn: I => Real = (i: I) => { - val places = math.pow(10, digits) - i.toDouble.map(v => math.round(v * places) / places).filter(Number.isValid).toReal + override def transformFn: I => Real = (in: I) => { + val scaler = math.pow(10, digits) + in.toDouble.map{ i => math.round(i * scaler) / scaler }.filter(Number.isValid).toReal } } diff --git a/core/src/test/scala/com/salesforce/op/stages/impl/feature/AbsoluteValueTransformerTest.scala b/core/src/test/scala/com/salesforce/op/stages/impl/feature/AbsoluteValueTransformerTest.scala new file mode 100644 index 0000000000..0b487f21c1 --- /dev/null +++ b/core/src/test/scala/com/salesforce/op/stages/impl/feature/AbsoluteValueTransformerTest.scala @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2017, Salesforce.com, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.salesforce.op.stages.impl.feature + +import com.salesforce.op.features.types._ +import com.salesforce.op.test.{OpTransformerSpec, TestFeatureBuilder} +import org.junit.runner.RunWith +import org.scalatest.junit.JUnitRunner + +@RunWith(classOf[JUnitRunner]) +class AbsoluteValueTransformerTest extends OpTransformerSpec[Real, AbsoluteValueTransformer[Real]] { + val sample = Seq(Real(-1.0), Real(-4.0), Real.empty, Real(5.0), Real(-5.5), Real(0.1), Real(2.0), Real(0.0)) + val (inputData, f1) = TestFeatureBuilder(sample) + val transformer: AbsoluteValueTransformer[Real] = new AbsoluteValueTransformer[Real]().setInput(f1) + override val expectedResult: Seq[Real] = Seq(Real(1.0), Real(4.0), Real.empty, Real(5.0), + Real(5.5), Real(0.1), Real(2.0), Real(0.0)) + + it should "have a working shortcut" in { + val f2 = f1.abs() + f2.originStage.isInstanceOf[AbsoluteValueTransformer[_]] shouldBe true + } +} + + + + + + + + diff --git a/core/src/test/scala/com/salesforce/op/stages/impl/feature/CeilTransformerTest.scala b/core/src/test/scala/com/salesforce/op/stages/impl/feature/CeilTransformerTest.scala new file mode 100644 index 0000000000..54f5f8ee54 --- /dev/null +++ b/core/src/test/scala/com/salesforce/op/stages/impl/feature/CeilTransformerTest.scala @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2017, Salesforce.com, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.salesforce.op.stages.impl.feature + +import com.salesforce.op.features.types._ +import com.salesforce.op.test.{OpTransformerSpec, TestFeatureBuilder} +import org.junit.runner.RunWith +import org.scalatest.junit.JUnitRunner + +@RunWith(classOf[JUnitRunner]) +class CeilTransformerTest extends OpTransformerSpec[Integral, CeilTransformer[Real]] { + val sample = Seq(Real(-1.3), Real(-4.9), Real.empty, Real(5.1), Real(-5.1), Real(0.1), Real(2.5), Real(0.4)) + val (inputData, f1) = TestFeatureBuilder(sample) + val transformer: CeilTransformer[Real] = new CeilTransformer[Real]().setInput(f1) + override val expectedResult: Seq[Integral] = Seq(Integral(-1), Integral(-4), Integral.empty, Integral(6), + Integral(-5), Integral(1), Integral(3), Integral(1)) + + it should "have a working shortcut" in { + val f2 = f1.ceil() + f2.originStage.isInstanceOf[CeilTransformer[_]] shouldBe true + } +} + + + + + + + + diff --git a/core/src/test/scala/com/salesforce/op/stages/impl/feature/ExpTransformerTest.scala b/core/src/test/scala/com/salesforce/op/stages/impl/feature/ExpTransformerTest.scala new file mode 100644 index 0000000000..d87afdc7d8 --- /dev/null +++ b/core/src/test/scala/com/salesforce/op/stages/impl/feature/ExpTransformerTest.scala @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2017, Salesforce.com, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.salesforce.op.stages.impl.feature + +import com.salesforce.op.features.types._ +import com.salesforce.op.test.{OpTransformerSpec, TestFeatureBuilder} +import org.junit.runner.RunWith +import org.scalatest.junit.JUnitRunner + +@RunWith(classOf[JUnitRunner]) +class ExpTransformerTest extends OpTransformerSpec[Real, ExpTransformer[Real]] { + val sample = Seq(Real(-1.3), Real(-4.9), Real.empty, Real(5.1), Real(-5.1), Real(0.1), Real(2.5), Real(0.4)) + val (inputData, f1) = TestFeatureBuilder(sample) + val transformer: ExpTransformer[Real] = new ExpTransformer[Real]().setInput(f1) + override val expectedResult: Seq[Real] = Seq(Real(math.exp(-1.3)), Real(math.exp(-4.9)), Real.empty, + Real(math.exp(5.1)), Real(math.exp(-5.1)), Real(math.exp(0.1)), Real(math.exp(2.5)), Real(math.exp(0.4))) + + it should "have a working shortcut" in { + val f2 = f1.exp() + f2.originStage.isInstanceOf[ExpTransformer[_]] shouldBe true + } +} + + + + + + + + diff --git a/core/src/test/scala/com/salesforce/op/stages/impl/feature/FloorTransformerTest.scala b/core/src/test/scala/com/salesforce/op/stages/impl/feature/FloorTransformerTest.scala new file mode 100644 index 0000000000..a2712c7803 --- /dev/null +++ b/core/src/test/scala/com/salesforce/op/stages/impl/feature/FloorTransformerTest.scala @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2017, Salesforce.com, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.salesforce.op.stages.impl.feature + +import com.salesforce.op.features.types._ +import com.salesforce.op.test.{OpTransformerSpec, TestFeatureBuilder} +import org.junit.runner.RunWith +import org.scalatest.junit.JUnitRunner + +@RunWith(classOf[JUnitRunner]) +class FloorTransformerTest extends OpTransformerSpec[Integral, FloorTransformer[Real]] { + val sample = Seq(Real(-1.3), Real(-4.9), Real.empty, Real(5.1), Real(-5.1), Real(0.1), Real(2.5), Real(0.4)) + val (inputData, f1) = TestFeatureBuilder(sample) + val transformer: FloorTransformer[Real] = new FloorTransformer[Real]().setInput(f1) + override val expectedResult: Seq[Integral] = Seq(Integral(-2), Integral(-5), Integral.empty, Integral(5), + Integral(-6), Integral(0), Integral(2), Integral(0)) + + it should "have a working shortcut" in { + val f2 = f1.floor() + f2.originStage.isInstanceOf[FloorTransformer[_]] shouldBe true + } +} + + + + + + + + diff --git a/core/src/test/scala/com/salesforce/op/stages/impl/feature/LogTransformerTest.scala b/core/src/test/scala/com/salesforce/op/stages/impl/feature/LogTransformerTest.scala new file mode 100644 index 0000000000..0e7a8cc369 --- /dev/null +++ b/core/src/test/scala/com/salesforce/op/stages/impl/feature/LogTransformerTest.scala @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2017, Salesforce.com, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.salesforce.op.stages.impl.feature + +import com.salesforce.op.features.types._ +import com.salesforce.op.test.{OpTransformerSpec, TestFeatureBuilder} +import org.junit.runner.RunWith +import org.scalatest.junit.JUnitRunner + +@RunWith(classOf[JUnitRunner]) +class LogTransformerTest extends OpTransformerSpec[Real, LogTransformer[Real, Double]] { + val sample = Seq(Real(-1.3), Real(-4.9), Real.empty, Real(5.1), Real(-5.1), Real(0.1), Real(2.5), Real(0.4)) + val (inputData, f1) = TestFeatureBuilder(sample) + val transformer: LogTransformer[Real, Double] = new LogTransformer[Real, Double](10).setInput(f1) + override val expectedResult: Seq[Real] = Seq(Real.empty, Real.empty, Real.empty, + Real(math.log10(5.1)), Real.empty, Real(math.log10(0.1)), Real(math.log10(2.5)), Real(math.log10(0.4))) + + it should "have a working shortcut" in { + val f2 = f1.log(2) + f2.originStage.isInstanceOf[LogTransformer[_, _]] shouldBe true + } +} + + + + + + + + diff --git a/core/src/test/scala/com/salesforce/op/stages/impl/feature/MathTransformersTest.scala b/core/src/test/scala/com/salesforce/op/stages/impl/feature/MathTransformersTest.scala deleted file mode 100644 index 78a4df17ef..0000000000 --- a/core/src/test/scala/com/salesforce/op/stages/impl/feature/MathTransformersTest.scala +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (c) 2017, Salesforce.com, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * * Neither the name of the copyright holder nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package com.salesforce.op.stages.impl.feature - -import com.salesforce.op.features.types._ -import com.salesforce.op.test.{OpTransformerSpec, TestFeatureBuilder} -import org.junit.runner.RunWith -import org.scalatest.junit.JUnitRunner - -@RunWith(classOf[JUnitRunner]) -class AddTransformerTest extends OpTransformerSpec[Real, AddTransformer[Real, Real]] { - val sample = Seq((Real(1.0), Real(2.0)), (Real(4.0), Real(4.0)), (Real.empty, Real(5.0)), - (Real(5.0), Real.empty), (Real(2.0), Real(0.0))) - val (inputData, f1, f2) = TestFeatureBuilder(sample) - val transformer: AddTransformer[Real, Real] = new AddTransformer[Real, Real]().setInput(f1, f2) - override val expectedResult: Seq[Real] = Seq(Real(3.0), Real(8.0), Real(5.0), Real(5.0), Real(2.0)) -} - -@RunWith(classOf[JUnitRunner]) -class ScalarAddTransformerTest extends OpTransformerSpec[Real, ScalarAddTransformer[Real, Double]] { - val sample = Seq(Real(1.0), Real(4.0), Real.empty, Real(-1.0), Real(2.0)) - val (inputData, f1) = TestFeatureBuilder(sample) - val transformer: ScalarAddTransformer[Real, Double] = new ScalarAddTransformer[Real, Double](5.0) - .setInput(f1) - override val expectedResult: Seq[Real] = Seq(Real(6.0), Real(9.0), Real.empty, Real(4.0), Real(7.0)) -} - -@RunWith(classOf[JUnitRunner]) -class SubtractTransformerTest extends OpTransformerSpec[Real, SubtractTransformer[Real, Real]] { - val sample = Seq((Real(1.0), Real(2.0)), (Real(4.0), Real(4.0)), (Real.empty, Real(5.0)), - (Real(5.0), Real.empty), (Real(2.0), Real(0.0))) - val (inputData, f1, f2) = TestFeatureBuilder(sample) - val transformer: SubtractTransformer[Real, Real] = new SubtractTransformer[Real, Real]().setInput(f1, f2) - override val expectedResult: Seq[Real] = Seq(Real(-1.0), Real(0.0), Real(-5.0), Real(5.0), Real(2.0)) -} - -@RunWith(classOf[JUnitRunner]) -class ScalarSubtractTransformerTest extends OpTransformerSpec[Real, ScalarSubtractTransformer[Real, Double]] { - val sample = Seq(Real(1.0), Real(4.0), Real.empty, Real(-1.0), Real(2.0)) - val (inputData, f1) = TestFeatureBuilder(sample) - val transformer: ScalarSubtractTransformer[Real, Double] = new ScalarSubtractTransformer[Real, Double](5.0) - .setInput(f1) - override val expectedResult: Seq[Real] = Seq(Real(-4.0), Real(-1.0), Real.empty, Real(-6.0), Real(-3.0)) -} - - -@RunWith(classOf[JUnitRunner]) -class MultiplyTransformerTest extends OpTransformerSpec[Real, MultiplyTransformer[Real, Real]] { - val sample = Seq((Real(1.0), Real(2.0)), (Real(4.0), Real(4.0)), (Real.empty, Real(5.0)), - (Real(5.0), Real.empty), (Real(2.0), Real(0.0))) - val (inputData, f1, f2) = TestFeatureBuilder(sample) - val transformer: MultiplyTransformer[Real, Real] = new MultiplyTransformer[Real, Real]().setInput(f1, f2) - override val expectedResult: Seq[Real] = Seq(Real(2.0), Real(16.0), Real.empty, Real.empty, Real(0.0)) -} - -@RunWith(classOf[JUnitRunner]) -class ScalarMultiplyTransformerTest extends OpTransformerSpec[Real, ScalarMultiplyTransformer[Real, Double]] { - val sample = Seq(Real(1.0), Real(4.0), Real.empty, Real(-1.0), Real(2.0)) - val (inputData, f1) = TestFeatureBuilder(sample) - val transformer: ScalarMultiplyTransformer[Real, Double] = new ScalarMultiplyTransformer[Real, Double](5.0) - .setInput(f1) - override val expectedResult: Seq[Real] = Seq(Real(5.0), Real(20.0), Real.empty, Real(-5.0), Real(10.0)) -} - -@RunWith(classOf[JUnitRunner]) -class DivideTransformerTest extends OpTransformerSpec[Real, DivideTransformer[Real, Real]] { - val sample = Seq((Real(1.0), Real(2.0)), (Real(4.0), Real(4.0)), (Real.empty, Real(5.0)), - (Real(5.0), Real.empty), (Real(2.0), Real(0.0))) - val (inputData, f1, f2) = TestFeatureBuilder(sample) - val transformer: DivideTransformer[Real, Real] = new DivideTransformer[Real, Real]().setInput(f1, f2) - override val expectedResult: Seq[Real] = Seq(Real(0.5), Real(1.0), Real.empty, Real.empty, Real.empty) -} - -@RunWith(classOf[JUnitRunner]) -class ScalarDivideTransformerTest extends OpTransformerSpec[Real, ScalarDivideTransformer[Real, Double]] { - val sample = Seq(Real(1.0), Real(4.0), Real.empty, Real(-1.0), Real(2.0)) - val (inputData, f1) = TestFeatureBuilder(sample) - val transformer: ScalarDivideTransformer[Real, Double] = new ScalarDivideTransformer[Real, Double](2.0) - .setInput(f1) - override val expectedResult: Seq[Real] = Seq(Real(0.5), Real(2.0), Real.empty, Real(-0.5), Real(1.0)) -} - - - - - diff --git a/core/src/test/scala/com/salesforce/op/stages/impl/feature/PowerTransformerTest.scala b/core/src/test/scala/com/salesforce/op/stages/impl/feature/PowerTransformerTest.scala new file mode 100644 index 0000000000..ffb6eeabb4 --- /dev/null +++ b/core/src/test/scala/com/salesforce/op/stages/impl/feature/PowerTransformerTest.scala @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2017, Salesforce.com, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.salesforce.op.stages.impl.feature + +import com.salesforce.op.features.types._ +import com.salesforce.op.test.{OpTransformerSpec, TestFeatureBuilder} +import org.junit.runner.RunWith +import org.scalatest.junit.JUnitRunner + +@RunWith(classOf[JUnitRunner]) +class PowerTransformerTest extends OpTransformerSpec[Real, PowerTransformer[Real, Double]] { + val sample = Seq(Real(-1.3), Real(-4.9), Real.empty, Real(5.1), Real(-5.1), Real(0.1), Real(2.5), Real(0.4)) + val (inputData, f1) = TestFeatureBuilder(sample) + val transformer: PowerTransformer[Real, Double] = new PowerTransformer[Real, Double](3.0).setInput(f1) + override val expectedResult: Seq[Real] = Seq(Real(math.pow(-1.3, 3)), Real(math.pow(-4.9, 3)), Real.empty, + Real(math.pow(5.1, 3)), Real(math.pow(-5.1, 3)), Real(math.pow(0.1, 3)), Real(math.pow(2.5, 3)), + Real(math.pow(0.4, 3))) + + it should "have a working shortcut" in { + val f2 = f1.power(4) + f2.originStage.isInstanceOf[PowerTransformer[_, _]] shouldBe true + } +} + + + + + + + + diff --git a/core/src/test/scala/com/salesforce/op/stages/impl/feature/RoundDigitsTransformerTest.scala b/core/src/test/scala/com/salesforce/op/stages/impl/feature/RoundDigitsTransformerTest.scala new file mode 100644 index 0000000000..68bc0196bf --- /dev/null +++ b/core/src/test/scala/com/salesforce/op/stages/impl/feature/RoundDigitsTransformerTest.scala @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2017, Salesforce.com, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.salesforce.op.stages.impl.feature + +import com.salesforce.op.features.types._ +import com.salesforce.op.test.{OpTransformerSpec, TestFeatureBuilder} +import org.junit.runner.RunWith +import org.scalatest.junit.JUnitRunner + + +@RunWith(classOf[JUnitRunner]) +class RoundDigitsTransformerTest extends OpTransformerSpec[Real, RoundDigitsTransformer[Real]] { + val sample = Seq(Real(1.4231092), Real(4.3231), Real.empty, Real(-1.0), Real(2.03728181)) + val (inputData, f1) = TestFeatureBuilder(sample) + val transformer: RoundDigitsTransformer[Real] = new RoundDigitsTransformer[Real](2) + .setInput(f1) + override val expectedResult: Seq[Real] = Seq(Real(1.42), Real(4.32), Real.empty, Real(-1.0), Real(2.04)) + + it should "have a working shortcut" in { + val f2 = f1.round(4) + f2.originStage.isInstanceOf[RoundDigitsTransformer[_]] shouldBe true + } +} + diff --git a/core/src/test/scala/com/salesforce/op/stages/impl/feature/RoundTransformerTest.scala b/core/src/test/scala/com/salesforce/op/stages/impl/feature/RoundTransformerTest.scala new file mode 100644 index 0000000000..508bca7016 --- /dev/null +++ b/core/src/test/scala/com/salesforce/op/stages/impl/feature/RoundTransformerTest.scala @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2017, Salesforce.com, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.salesforce.op.stages.impl.feature + +import com.salesforce.op.features.types._ +import com.salesforce.op.test.{OpTransformerSpec, TestFeatureBuilder} +import org.junit.runner.RunWith +import org.scalatest.junit.JUnitRunner + +@RunWith(classOf[JUnitRunner]) +class RoundTransformerTest extends OpTransformerSpec[Integral, RoundTransformer[Real]] { + val sample = Seq(Real(-1.3), Real(-4.9), Real.empty, Real(5.1), Real(-5.1), Real(0.1), Real(2.5), Real(0.4)) + val (inputData, f1) = TestFeatureBuilder(sample) + val transformer: RoundTransformer[Real] = new RoundTransformer[Real]().setInput(f1) + override val expectedResult: Seq[Integral] = Seq(Integral(-1), Integral(-5), Integral.empty, Integral(5), + Integral(-5), Integral(0), Integral(3), Integral(0)) + + it should "have a working shortcut" in { + val f2 = f1.round() + f2.originStage.isInstanceOf[RoundTransformer[_]] shouldBe true + } +} + + + + + + + + diff --git a/core/src/test/scala/com/salesforce/op/stages/impl/feature/SqrtTransformerTest.scala b/core/src/test/scala/com/salesforce/op/stages/impl/feature/SqrtTransformerTest.scala new file mode 100644 index 0000000000..7c5a0ef468 --- /dev/null +++ b/core/src/test/scala/com/salesforce/op/stages/impl/feature/SqrtTransformerTest.scala @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2017, Salesforce.com, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.salesforce.op.stages.impl.feature + +import com.salesforce.op.features.types._ +import com.salesforce.op.test.{OpTransformerSpec, TestFeatureBuilder} +import org.junit.runner.RunWith +import org.scalatest.junit.JUnitRunner + +@RunWith(classOf[JUnitRunner]) +class SqrtTransformerTest extends OpTransformerSpec[Real, SqrtTransformer[Real]] { + val sample = Seq(Real(-1.3), Real(-4.9), Real.empty, Real(5.1), Real(-5.1), Real(0.1), Real(2.5), Real(0.4)) + val (inputData, f1) = TestFeatureBuilder(sample) + val transformer: SqrtTransformer[Real] = new SqrtTransformer[Real]().setInput(f1) + override val expectedResult: Seq[Real] = Seq(Real.empty, Real.empty, Real.empty, + Real(math.sqrt(5.1)), Real.empty, Real(math.sqrt(0.1)), Real(math.sqrt(2.5)), Real(math.sqrt(0.4))) + + it should "have a working shortcut" in { + val f2 = f1.sqrt() + f2.originStage.isInstanceOf[SqrtTransformer[_]] shouldBe true + } +} + + + + + + + + From cb2c20c763e5be4df4d30d019e512092ae5fd853 Mon Sep 17 00:00:00 2001 From: leahmcguire Date: Tue, 2 Apr 2019 10:22:00 -0700 Subject: [PATCH 08/10] cleanup --- .../impl/feature/MathTransformers.scala | 37 +++++++++---------- .../AbsoluteValueTransformerTest.scala | 9 +---- .../impl/feature/AddTransformerTest.scala | 9 +---- .../impl/feature/DivideTransformerTest.scala | 2 +- .../impl/feature/ExpTransformerTest.scala | 12 +----- .../impl/feature/FloorTransformerTest.scala | 9 +---- .../impl/feature/LogTransformerTest.scala | 17 +++------ .../feature/MultiplyTransformerTest.scala | 2 +- .../impl/feature/PowerTransformerTest.scala | 19 +++------- .../feature/RoundDigitsTransformerTest.scala | 2 +- .../impl/feature/RoundTransformerTest.scala | 2 +- .../feature/ScalarAddTransformerTest.scala | 2 +- .../feature/ScalarDivideTransformerTest.scala | 2 +- .../ScalarMultiplyTransformerTest.scala | 2 +- .../ScalarSubtractTransformerTest.scala | 2 +- .../impl/feature/SqrtTransformerTest.scala | 11 +----- .../feature/SubtractTransformerTest.scala | 2 +- 17 files changed, 45 insertions(+), 96 deletions(-) diff --git a/core/src/main/scala/com/salesforce/op/stages/impl/feature/MathTransformers.scala b/core/src/main/scala/com/salesforce/op/stages/impl/feature/MathTransformers.scala index d1edd57952..78a6ba8eff 100644 --- a/core/src/main/scala/com/salesforce/op/stages/impl/feature/MathTransformers.scala +++ b/core/src/main/scala/com/salesforce/op/stages/impl/feature/MathTransformers.scala @@ -281,10 +281,10 @@ class FloorTransformer[I <: OPNumeric[_]] */ class RoundTransformer[I <: OPNumeric[_]] ( - uid: String = UID[FloorTransformer[_]] + uid: String = UID[RoundTransformer[_]] )( implicit override val tti: TypeTag[I] -) extends UnaryTransformer[I, Integral](operationName = "floor", uid = uid){ +) extends UnaryTransformer[I, Integral](operationName = "round", uid = uid){ override def transformFn: I => Integral = (i: I) => i.toDouble.map(v => math.round(v)).toIntegral } @@ -315,7 +315,7 @@ class ExpTransformer[I <: OPNumeric[_]] */ class SqrtTransformer[I <: OPNumeric[_]] ( - uid: String = UID[ExpTransformer[_]] + uid: String = UID[SqrtTransformer[_]] )( implicit override val tti: TypeTag[I] ) extends UnaryTransformer[I, Real](operationName = "sqrt", uid = uid){ @@ -332,16 +332,16 @@ class SqrtTransformer[I <: OPNumeric[_]] * @tparam I input feature type * @tparam N value type */ -class LogTransformer[I <: OPNumeric[_], N] +class LogTransformer[I <: OPNumeric[_]] ( - val base: N, - uid: String = UID[LogTransformer[_, _]] + val base: Double, + uid: String = UID[LogTransformer[_]] )( - implicit override val tti: TypeTag[I], - val n: Numeric[N] + implicit override val tti: TypeTag[I] ) extends UnaryTransformer[I, Real](operationName = "log", uid = uid){ + require(base > 0, "log base must be greater than 0") override def transformFn: I => Real = (i: I) => { - def logN(v: Double): Double = math.log10(v) / math.log10(n.toDouble(base)) + def logN(v: Double): Double = math.log10(v) / math.log10(base) i.toDouble.map(logN).filter(Number.isValid).toReal } } @@ -351,28 +351,27 @@ class LogTransformer[I <: OPNumeric[_], N] /** * Power transformer * - * @param base base for log value + * @param power base for log value * @param uid uid for instance * @param tti type tag for input * @param n value converter * @tparam I input feature type * @tparam N value type */ -class PowerTransformer[I <: OPNumeric[_], N] +class PowerTransformer[I <: OPNumeric[_]] ( - val power: N, - uid: String = UID[PowerTransformer[_, _]] + val power: Double, + uid: String = UID[PowerTransformer[_]] )( - implicit override val tti: TypeTag[I], - val n: Numeric[N] + implicit override val tti: TypeTag[I] ) extends UnaryTransformer[I, Real](operationName = "power", uid = uid){ override def transformFn: I => Real = (i: I) => - i.toDouble.map(v => math.pow(v, n.toDouble(power))).filter(Number.isValid).toReal + i.toDouble.map(v => math.pow(v, power)).filter(Number.isValid).toReal } /** - * Round transformer + * Round digits transformer * * @param digits digits to round to * @param uid uid for instance @@ -382,10 +381,10 @@ class PowerTransformer[I <: OPNumeric[_], N] class RoundDigitsTransformer[I <: OPNumeric[_]] ( val digits: Int, - uid: String = UID[PowerTransformer[_, _]] + uid: String = UID[RoundDigitsTransformer[_]] )( implicit override val tti: TypeTag[I] -) extends UnaryTransformer[I, Real](operationName = "round", uid = uid){ +) extends UnaryTransformer[I, Real](operationName = "roundDigits", uid = uid){ override def transformFn: I => Real = (in: I) => { val scaler = math.pow(10, digits) in.toDouble.map{ i => math.round(i * scaler) / scaler }.filter(Number.isValid).toReal diff --git a/core/src/test/scala/com/salesforce/op/stages/impl/feature/AbsoluteValueTransformerTest.scala b/core/src/test/scala/com/salesforce/op/stages/impl/feature/AbsoluteValueTransformerTest.scala index 0b487f21c1..ee35d3ca48 100644 --- a/core/src/test/scala/com/salesforce/op/stages/impl/feature/AbsoluteValueTransformerTest.scala +++ b/core/src/test/scala/com/salesforce/op/stages/impl/feature/AbsoluteValueTransformerTest.scala @@ -40,7 +40,7 @@ class AbsoluteValueTransformerTest extends OpTransformerSpec[Real, AbsoluteValue val sample = Seq(Real(-1.0), Real(-4.0), Real.empty, Real(5.0), Real(-5.5), Real(0.1), Real(2.0), Real(0.0)) val (inputData, f1) = TestFeatureBuilder(sample) val transformer: AbsoluteValueTransformer[Real] = new AbsoluteValueTransformer[Real]().setInput(f1) - override val expectedResult: Seq[Real] = Seq(Real(1.0), Real(4.0), Real.empty, Real(5.0), + val expectedResult: Seq[Real] = Seq(Real(1.0), Real(4.0), Real.empty, Real(5.0), Real(5.5), Real(0.1), Real(2.0), Real(0.0)) it should "have a working shortcut" in { @@ -49,10 +49,3 @@ class AbsoluteValueTransformerTest extends OpTransformerSpec[Real, AbsoluteValue } } - - - - - - - diff --git a/core/src/test/scala/com/salesforce/op/stages/impl/feature/AddTransformerTest.scala b/core/src/test/scala/com/salesforce/op/stages/impl/feature/AddTransformerTest.scala index 67ea7c87cd..77b8832571 100644 --- a/core/src/test/scala/com/salesforce/op/stages/impl/feature/AddTransformerTest.scala +++ b/core/src/test/scala/com/salesforce/op/stages/impl/feature/AddTransformerTest.scala @@ -41,13 +41,6 @@ class AddTransformerTest extends OpTransformerSpec[Real, AddTransformer[Real, Re (Real(5.0), Real.empty), (Real(2.0), Real(0.0))) val (inputData, f1, f2) = TestFeatureBuilder(sample) val transformer: AddTransformer[Real, Real] = new AddTransformer[Real, Real]().setInput(f1, f2) - override val expectedResult: Seq[Real] = Seq(Real(3.0), Real(8.0), Real(5.0), Real(5.0), Real(2.0)) + val expectedResult: Seq[Real] = Seq(Real(3.0), Real(8.0), Real(5.0), Real(5.0), Real(2.0)) } - - - - - - - diff --git a/core/src/test/scala/com/salesforce/op/stages/impl/feature/DivideTransformerTest.scala b/core/src/test/scala/com/salesforce/op/stages/impl/feature/DivideTransformerTest.scala index 00da5d5a55..a2af96dbb6 100644 --- a/core/src/test/scala/com/salesforce/op/stages/impl/feature/DivideTransformerTest.scala +++ b/core/src/test/scala/com/salesforce/op/stages/impl/feature/DivideTransformerTest.scala @@ -42,6 +42,6 @@ class DivideTransformerTest extends OpTransformerSpec[Real, DivideTransformer[Re (Real(5.0), Real.empty), (Real(2.0), Real(0.0))) val (inputData, f1, f2) = TestFeatureBuilder(sample) val transformer: DivideTransformer[Real, Real] = new DivideTransformer[Real, Real]().setInput(f1, f2) - override val expectedResult: Seq[Real] = Seq(Real(0.5), Real(1.0), Real.empty, Real.empty, Real.empty) + val expectedResult: Seq[Real] = Seq(Real(0.5), Real(1.0), Real.empty, Real.empty, Real.empty) } diff --git a/core/src/test/scala/com/salesforce/op/stages/impl/feature/ExpTransformerTest.scala b/core/src/test/scala/com/salesforce/op/stages/impl/feature/ExpTransformerTest.scala index d87afdc7d8..320485caca 100644 --- a/core/src/test/scala/com/salesforce/op/stages/impl/feature/ExpTransformerTest.scala +++ b/core/src/test/scala/com/salesforce/op/stages/impl/feature/ExpTransformerTest.scala @@ -40,19 +40,11 @@ class ExpTransformerTest extends OpTransformerSpec[Real, ExpTransformer[Real]] { val sample = Seq(Real(-1.3), Real(-4.9), Real.empty, Real(5.1), Real(-5.1), Real(0.1), Real(2.5), Real(0.4)) val (inputData, f1) = TestFeatureBuilder(sample) val transformer: ExpTransformer[Real] = new ExpTransformer[Real]().setInput(f1) - override val expectedResult: Seq[Real] = Seq(Real(math.exp(-1.3)), Real(math.exp(-4.9)), Real.empty, - Real(math.exp(5.1)), Real(math.exp(-5.1)), Real(math.exp(0.1)), Real(math.exp(2.5)), Real(math.exp(0.4))) + override val expectedResult: Seq[Real] = Seq(Some(-1.3), Some(-4.9), None, + Some(5.1), Some(-5.1), Some(0.1), Some(2.5), Some(0.4)).map(_.map(math.exp).toReal) it should "have a working shortcut" in { val f2 = f1.exp() f2.originStage.isInstanceOf[ExpTransformer[_]] shouldBe true } } - - - - - - - - diff --git a/core/src/test/scala/com/salesforce/op/stages/impl/feature/FloorTransformerTest.scala b/core/src/test/scala/com/salesforce/op/stages/impl/feature/FloorTransformerTest.scala index a2712c7803..a5075bf85d 100644 --- a/core/src/test/scala/com/salesforce/op/stages/impl/feature/FloorTransformerTest.scala +++ b/core/src/test/scala/com/salesforce/op/stages/impl/feature/FloorTransformerTest.scala @@ -40,7 +40,7 @@ class FloorTransformerTest extends OpTransformerSpec[Integral, FloorTransformer[ val sample = Seq(Real(-1.3), Real(-4.9), Real.empty, Real(5.1), Real(-5.1), Real(0.1), Real(2.5), Real(0.4)) val (inputData, f1) = TestFeatureBuilder(sample) val transformer: FloorTransformer[Real] = new FloorTransformer[Real]().setInput(f1) - override val expectedResult: Seq[Integral] = Seq(Integral(-2), Integral(-5), Integral.empty, Integral(5), + val expectedResult: Seq[Integral] = Seq(Integral(-2), Integral(-5), Integral.empty, Integral(5), Integral(-6), Integral(0), Integral(2), Integral(0)) it should "have a working shortcut" in { @@ -49,10 +49,3 @@ class FloorTransformerTest extends OpTransformerSpec[Integral, FloorTransformer[ } } - - - - - - - diff --git a/core/src/test/scala/com/salesforce/op/stages/impl/feature/LogTransformerTest.scala b/core/src/test/scala/com/salesforce/op/stages/impl/feature/LogTransformerTest.scala index 0e7a8cc369..d684e985c1 100644 --- a/core/src/test/scala/com/salesforce/op/stages/impl/feature/LogTransformerTest.scala +++ b/core/src/test/scala/com/salesforce/op/stages/impl/feature/LogTransformerTest.scala @@ -36,23 +36,16 @@ import org.junit.runner.RunWith import org.scalatest.junit.JUnitRunner @RunWith(classOf[JUnitRunner]) -class LogTransformerTest extends OpTransformerSpec[Real, LogTransformer[Real, Double]] { +class LogTransformerTest extends OpTransformerSpec[Real, LogTransformer[Real]] { val sample = Seq(Real(-1.3), Real(-4.9), Real.empty, Real(5.1), Real(-5.1), Real(0.1), Real(2.5), Real(0.4)) val (inputData, f1) = TestFeatureBuilder(sample) - val transformer: LogTransformer[Real, Double] = new LogTransformer[Real, Double](10).setInput(f1) - override val expectedResult: Seq[Real] = Seq(Real.empty, Real.empty, Real.empty, - Real(math.log10(5.1)), Real.empty, Real(math.log10(0.1)), Real(math.log10(2.5)), Real(math.log10(0.4))) + val transformer: LogTransformer[Real] = new LogTransformer[Real](10).setInput(f1) + val expectedResult: Seq[Real] = Seq(None, None, None, + Some(5.1), None, Some(0.1), Some(2.5), Some(0.4)).map(_.map(math.log10).toReal) it should "have a working shortcut" in { val f2 = f1.log(2) - f2.originStage.isInstanceOf[LogTransformer[_, _]] shouldBe true + f2.originStage.isInstanceOf[LogTransformer[_]] shouldBe true } } - - - - - - - diff --git a/core/src/test/scala/com/salesforce/op/stages/impl/feature/MultiplyTransformerTest.scala b/core/src/test/scala/com/salesforce/op/stages/impl/feature/MultiplyTransformerTest.scala index 540cd2115a..c1b98ec606 100644 --- a/core/src/test/scala/com/salesforce/op/stages/impl/feature/MultiplyTransformerTest.scala +++ b/core/src/test/scala/com/salesforce/op/stages/impl/feature/MultiplyTransformerTest.scala @@ -41,6 +41,6 @@ class MultiplyTransformerTest extends OpTransformerSpec[Real, MultiplyTransforme (Real(5.0), Real.empty), (Real(2.0), Real(0.0))) val (inputData, f1, f2) = TestFeatureBuilder(sample) val transformer: MultiplyTransformer[Real, Real] = new MultiplyTransformer[Real, Real]().setInput(f1, f2) - override val expectedResult: Seq[Real] = Seq(Real(2.0), Real(16.0), Real.empty, Real.empty, Real(0.0)) + val expectedResult: Seq[Real] = Seq(Real(2.0), Real(16.0), Real.empty, Real.empty, Real(0.0)) } diff --git a/core/src/test/scala/com/salesforce/op/stages/impl/feature/PowerTransformerTest.scala b/core/src/test/scala/com/salesforce/op/stages/impl/feature/PowerTransformerTest.scala index ffb6eeabb4..9472762055 100644 --- a/core/src/test/scala/com/salesforce/op/stages/impl/feature/PowerTransformerTest.scala +++ b/core/src/test/scala/com/salesforce/op/stages/impl/feature/PowerTransformerTest.scala @@ -36,24 +36,17 @@ import org.junit.runner.RunWith import org.scalatest.junit.JUnitRunner @RunWith(classOf[JUnitRunner]) -class PowerTransformerTest extends OpTransformerSpec[Real, PowerTransformer[Real, Double]] { +class PowerTransformerTest extends OpTransformerSpec[Real, PowerTransformer[Real]] { val sample = Seq(Real(-1.3), Real(-4.9), Real.empty, Real(5.1), Real(-5.1), Real(0.1), Real(2.5), Real(0.4)) val (inputData, f1) = TestFeatureBuilder(sample) - val transformer: PowerTransformer[Real, Double] = new PowerTransformer[Real, Double](3.0).setInput(f1) - override val expectedResult: Seq[Real] = Seq(Real(math.pow(-1.3, 3)), Real(math.pow(-4.9, 3)), Real.empty, - Real(math.pow(5.1, 3)), Real(math.pow(-5.1, 3)), Real(math.pow(0.1, 3)), Real(math.pow(2.5, 3)), - Real(math.pow(0.4, 3))) + val transformer: PowerTransformer[Real] = new PowerTransformer[Real](3.0).setInput(f1) + override val expectedResult: Seq[Real] = Seq(Some(-1.3), Some(-4.9), None, + Some(5.1), Some(-5.1), None(0.1), Some(2.5), + Some(0.4)).map(_.map(v => math.pow(v, 3)).toReal) it should "have a working shortcut" in { val f2 = f1.power(4) - f2.originStage.isInstanceOf[PowerTransformer[_, _]] shouldBe true + f2.originStage.isInstanceOf[PowerTransformer[_]] shouldBe true } } - - - - - - - diff --git a/core/src/test/scala/com/salesforce/op/stages/impl/feature/RoundDigitsTransformerTest.scala b/core/src/test/scala/com/salesforce/op/stages/impl/feature/RoundDigitsTransformerTest.scala index 68bc0196bf..4c7b9dfacd 100644 --- a/core/src/test/scala/com/salesforce/op/stages/impl/feature/RoundDigitsTransformerTest.scala +++ b/core/src/test/scala/com/salesforce/op/stages/impl/feature/RoundDigitsTransformerTest.scala @@ -42,7 +42,7 @@ class RoundDigitsTransformerTest extends OpTransformerSpec[Real, RoundDigitsTran val (inputData, f1) = TestFeatureBuilder(sample) val transformer: RoundDigitsTransformer[Real] = new RoundDigitsTransformer[Real](2) .setInput(f1) - override val expectedResult: Seq[Real] = Seq(Real(1.42), Real(4.32), Real.empty, Real(-1.0), Real(2.04)) + val expectedResult: Seq[Real] = Seq(Real(1.42), Real(4.32), Real.empty, Real(-1.0), Real(2.04)) it should "have a working shortcut" in { val f2 = f1.round(4) diff --git a/core/src/test/scala/com/salesforce/op/stages/impl/feature/RoundTransformerTest.scala b/core/src/test/scala/com/salesforce/op/stages/impl/feature/RoundTransformerTest.scala index 508bca7016..12c155c230 100644 --- a/core/src/test/scala/com/salesforce/op/stages/impl/feature/RoundTransformerTest.scala +++ b/core/src/test/scala/com/salesforce/op/stages/impl/feature/RoundTransformerTest.scala @@ -40,7 +40,7 @@ class RoundTransformerTest extends OpTransformerSpec[Integral, RoundTransformer[ val sample = Seq(Real(-1.3), Real(-4.9), Real.empty, Real(5.1), Real(-5.1), Real(0.1), Real(2.5), Real(0.4)) val (inputData, f1) = TestFeatureBuilder(sample) val transformer: RoundTransformer[Real] = new RoundTransformer[Real]().setInput(f1) - override val expectedResult: Seq[Integral] = Seq(Integral(-1), Integral(-5), Integral.empty, Integral(5), + val expectedResult: Seq[Integral] = Seq(Integral(-1), Integral(-5), Integral.empty, Integral(5), Integral(-5), Integral(0), Integral(3), Integral(0)) it should "have a working shortcut" in { diff --git a/core/src/test/scala/com/salesforce/op/stages/impl/feature/ScalarAddTransformerTest.scala b/core/src/test/scala/com/salesforce/op/stages/impl/feature/ScalarAddTransformerTest.scala index e89bd714d6..ec11494994 100644 --- a/core/src/test/scala/com/salesforce/op/stages/impl/feature/ScalarAddTransformerTest.scala +++ b/core/src/test/scala/com/salesforce/op/stages/impl/feature/ScalarAddTransformerTest.scala @@ -42,6 +42,6 @@ class ScalarAddTransformerTest extends OpTransformerSpec[Real, ScalarAddTransfor val (inputData, f1) = TestFeatureBuilder(sample) val transformer: ScalarAddTransformer[Real, Double] = new ScalarAddTransformer[Real, Double](5.0) .setInput(f1) - override val expectedResult: Seq[Real] = Seq(Real(6.0), Real(9.0), Real.empty, Real(4.0), Real(7.0)) + val expectedResult: Seq[Real] = Seq(Real(6.0), Real(9.0), Real.empty, Real(4.0), Real(7.0)) } diff --git a/core/src/test/scala/com/salesforce/op/stages/impl/feature/ScalarDivideTransformerTest.scala b/core/src/test/scala/com/salesforce/op/stages/impl/feature/ScalarDivideTransformerTest.scala index 0c81bf4618..18bff6969d 100644 --- a/core/src/test/scala/com/salesforce/op/stages/impl/feature/ScalarDivideTransformerTest.scala +++ b/core/src/test/scala/com/salesforce/op/stages/impl/feature/ScalarDivideTransformerTest.scala @@ -40,7 +40,7 @@ class ScalarDivideTransformerTest extends OpTransformerSpec[Real, ScalarDivideTr val (inputData, f1) = TestFeatureBuilder(sample) val transformer: ScalarDivideTransformer[Real, Double] = new ScalarDivideTransformer[Real, Double](2.0) .setInput(f1) - override val expectedResult: Seq[Real] = Seq(Real(0.5), Real(2.0), Real.empty, Real(-0.5), Real(1.0)) + val expectedResult: Seq[Real] = Seq(Real(0.5), Real(2.0), Real.empty, Real(-0.5), Real(1.0)) } diff --git a/core/src/test/scala/com/salesforce/op/stages/impl/feature/ScalarMultiplyTransformerTest.scala b/core/src/test/scala/com/salesforce/op/stages/impl/feature/ScalarMultiplyTransformerTest.scala index 3dc951faf2..2b00b2ac08 100644 --- a/core/src/test/scala/com/salesforce/op/stages/impl/feature/ScalarMultiplyTransformerTest.scala +++ b/core/src/test/scala/com/salesforce/op/stages/impl/feature/ScalarMultiplyTransformerTest.scala @@ -41,5 +41,5 @@ class ScalarMultiplyTransformerTest extends OpTransformerSpec[Real, ScalarMultip val (inputData, f1) = TestFeatureBuilder(sample) val transformer: ScalarMultiplyTransformer[Real, Double] = new ScalarMultiplyTransformer[Real, Double](5.0) .setInput(f1) - override val expectedResult: Seq[Real] = Seq(Real(5.0), Real(20.0), Real.empty, Real(-5.0), Real(10.0)) + val expectedResult: Seq[Real] = Seq(Real(5.0), Real(20.0), Real.empty, Real(-5.0), Real(10.0)) } diff --git a/core/src/test/scala/com/salesforce/op/stages/impl/feature/ScalarSubtractTransformerTest.scala b/core/src/test/scala/com/salesforce/op/stages/impl/feature/ScalarSubtractTransformerTest.scala index faf3ed6f26..74f83dcfdf 100644 --- a/core/src/test/scala/com/salesforce/op/stages/impl/feature/ScalarSubtractTransformerTest.scala +++ b/core/src/test/scala/com/salesforce/op/stages/impl/feature/ScalarSubtractTransformerTest.scala @@ -40,5 +40,5 @@ class ScalarSubtractTransformerTest extends OpTransformerSpec[Real, ScalarSubtra val (inputData, f1) = TestFeatureBuilder(sample) val transformer: ScalarSubtractTransformer[Real, Double] = new ScalarSubtractTransformer[Real, Double](5.0) .setInput(f1) - override val expectedResult: Seq[Real] = Seq(Real(-4.0), Real(-1.0), Real.empty, Real(-6.0), Real(-3.0)) + val expectedResult: Seq[Real] = Seq(Real(-4.0), Real(-1.0), Real.empty, Real(-6.0), Real(-3.0)) } diff --git a/core/src/test/scala/com/salesforce/op/stages/impl/feature/SqrtTransformerTest.scala b/core/src/test/scala/com/salesforce/op/stages/impl/feature/SqrtTransformerTest.scala index 7c5a0ef468..27c2ff5ba6 100644 --- a/core/src/test/scala/com/salesforce/op/stages/impl/feature/SqrtTransformerTest.scala +++ b/core/src/test/scala/com/salesforce/op/stages/impl/feature/SqrtTransformerTest.scala @@ -40,8 +40,8 @@ class SqrtTransformerTest extends OpTransformerSpec[Real, SqrtTransformer[Real]] val sample = Seq(Real(-1.3), Real(-4.9), Real.empty, Real(5.1), Real(-5.1), Real(0.1), Real(2.5), Real(0.4)) val (inputData, f1) = TestFeatureBuilder(sample) val transformer: SqrtTransformer[Real] = new SqrtTransformer[Real]().setInput(f1) - override val expectedResult: Seq[Real] = Seq(Real.empty, Real.empty, Real.empty, - Real(math.sqrt(5.1)), Real.empty, Real(math.sqrt(0.1)), Real(math.sqrt(2.5)), Real(math.sqrt(0.4))) + val expectedResult: Seq[Real] = Seq(None, None, None, + Some(5.1), None, Some(0.1), Some(2.5), Some(0.4)).map(_.map(math.sqrt).toReal) it should "have a working shortcut" in { val f2 = f1.sqrt() @@ -49,10 +49,3 @@ class SqrtTransformerTest extends OpTransformerSpec[Real, SqrtTransformer[Real]] } } - - - - - - - diff --git a/core/src/test/scala/com/salesforce/op/stages/impl/feature/SubtractTransformerTest.scala b/core/src/test/scala/com/salesforce/op/stages/impl/feature/SubtractTransformerTest.scala index 11b85074f3..d07d0bee05 100644 --- a/core/src/test/scala/com/salesforce/op/stages/impl/feature/SubtractTransformerTest.scala +++ b/core/src/test/scala/com/salesforce/op/stages/impl/feature/SubtractTransformerTest.scala @@ -42,7 +42,7 @@ class SubtractTransformerTest extends OpTransformerSpec[Real, SubtractTransforme (Real(5.0), Real.empty), (Real(2.0), Real(0.0))) val (inputData, f1, f2) = TestFeatureBuilder(sample) val transformer: SubtractTransformer[Real, Real] = new SubtractTransformer[Real, Real]().setInput(f1, f2) - override val expectedResult: Seq[Real] = Seq(Real(-1.0), Real(0.0), Real(-5.0), Real(5.0), Real(2.0)) + val expectedResult: Seq[Real] = Seq(Real(-1.0), Real(0.0), Real(-5.0), Real(5.0), Real(2.0)) } From 1af456366af44df3b9a33b5a94b5fc5cf6d5c03c Mon Sep 17 00:00:00 2001 From: leahmcguire Date: Tue, 2 Apr 2019 11:13:37 -0700 Subject: [PATCH 09/10] more cleanup --- .../scala/com/salesforce/op/dsl/RichNumericFeature.scala | 8 ++++---- .../op/stages/impl/feature/PowerTransformerTest.scala | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/core/src/main/scala/com/salesforce/op/dsl/RichNumericFeature.scala b/core/src/main/scala/com/salesforce/op/dsl/RichNumericFeature.scala index afbdca2e0e..62bd04644c 100644 --- a/core/src/main/scala/com/salesforce/op/dsl/RichNumericFeature.scala +++ b/core/src/main/scala/com/salesforce/op/dsl/RichNumericFeature.scala @@ -218,15 +218,15 @@ trait RichNumericFeature { * Square root transformer * @return transformed feature */ - def log[N](base: N)(implicit n: Numeric[N]): FeatureLike[Real] = - f.transformWith(new LogTransformer[I, N](base = base)) + def log(base: Double): FeatureLike[Real] = + f.transformWith(new LogTransformer[I](base = base)) /** * Square root transformer * @return transformed feature */ - def power[N](power: N)(implicit n: Numeric[N]): FeatureLike[Real] = - f.transformWith(new PowerTransformer[I, N](power = power)) + def power(power: Double): FeatureLike[Real] = + f.transformWith(new PowerTransformer[I](power = power)) } diff --git a/core/src/test/scala/com/salesforce/op/stages/impl/feature/PowerTransformerTest.scala b/core/src/test/scala/com/salesforce/op/stages/impl/feature/PowerTransformerTest.scala index 9472762055..4d9ad4814f 100644 --- a/core/src/test/scala/com/salesforce/op/stages/impl/feature/PowerTransformerTest.scala +++ b/core/src/test/scala/com/salesforce/op/stages/impl/feature/PowerTransformerTest.scala @@ -41,7 +41,7 @@ class PowerTransformerTest extends OpTransformerSpec[Real, PowerTransformer[Real val (inputData, f1) = TestFeatureBuilder(sample) val transformer: PowerTransformer[Real] = new PowerTransformer[Real](3.0).setInput(f1) override val expectedResult: Seq[Real] = Seq(Some(-1.3), Some(-4.9), None, - Some(5.1), Some(-5.1), None(0.1), Some(2.5), + Some(5.1), Some(-5.1), Some(0.1), Some(2.5), Some(0.4)).map(_.map(v => math.pow(v, 3)).toReal) it should "have a working shortcut" in { From 3fa7f8e2d9923dad89a3cc678874930688b6837c Mon Sep 17 00:00:00 2001 From: leahmcguire Date: Wed, 3 Apr 2019 14:37:11 -0700 Subject: [PATCH 10/10] fixed doc --- .../salesforce/op/stages/impl/feature/MathTransformers.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/scala/com/salesforce/op/stages/impl/feature/MathTransformers.scala b/core/src/main/scala/com/salesforce/op/stages/impl/feature/MathTransformers.scala index 78a6ba8eff..6fea160751 100644 --- a/core/src/main/scala/com/salesforce/op/stages/impl/feature/MathTransformers.scala +++ b/core/src/main/scala/com/salesforce/op/stages/impl/feature/MathTransformers.scala @@ -351,7 +351,7 @@ class LogTransformer[I <: OPNumeric[_]] /** * Power transformer * - * @param power base for log value + * @param power power to multiply feature to * @param uid uid for instance * @param tti type tag for input * @param n value converter