Skip to content

Commit

Permalink
Additional arithmetic traits.
Browse files Browse the repository at this point in the history
  • Loading branch information
neuralagent committed Jan 2, 2017
1 parent e5d6bee commit 346386b
Show file tree
Hide file tree
Showing 5 changed files with 119 additions and 11 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Skylark
* http://skylark.io
*
* Copyright 2012-2017 Quantarray, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.quantarray.skylark.measure

/**
* Can divide quantity type class.
*
* @author Araik Grigoryan
*/
trait CanDivideQuantity[N, M1, Q1, M2, Q2, RM] extends CanDivide[M1, M2, RM]
{
type QR

def divide(numerator: Q1, denominator: Q2): QR
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Skylark
* http://skylark.io
*
* Copyright 2012-2017 Quantarray, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.quantarray.skylark.measure

/**
* Can exponentiate quantity type class.
*
* @author Araik Grigoryan
*/
trait CanExponentiateQuantity[N, M, Q, RM] extends CanExponentiate[M, RM]
{
type QR

def pow(base: Q, exponent: Double): QR
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Skylark
* http://skylark.io
*
* Copyright 2012-2017 Quantarray, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.quantarray.skylark.measure

/**
* Can multiply quantity type class.
*
* @author Araik Grigoryan
*/
trait CanMultiplyQuantity[N, M1, Q1, M2, Q2, RM] extends CanMultiply[M1, M2, RM]
{
type QR

def times(multiplicand: Q1, multiplier: Q2): QR
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,35 +26,38 @@ import scala.language.implicitConversions
*
* @author Araik Grigoryan
*/
case class Quantity[N, M <: Measure[M]](override val value: N, override val measure: M)(implicit qn: QuasiNumeric[N]) extends AnyQuantity[N](value, measure)
case class Quantity[N, M](value: N, measure: M)(implicit qn: QuasiNumeric[N])
{
override def unary_-() = Quantity(qn.negate(value), measure)
def unary_-() = Quantity(qn.negate(value), measure)

override def *(constant: Double) = Quantity(qn.timesConstant(value, constant), measure)
def *(constant: Double) = Quantity(qn.timesConstant(value, constant), measure)

override def /(constant: Double) = Quantity(qn.divideByConstant(value, constant), measure)
def /(constant: Double) = Quantity(qn.divideByConstant(value, constant), measure)

/**
* Adds another quantity. CanAdd instance allows addition of apples and oranges to obtain bananas.
* Adds another quantity. CanAddQuantity instance allows addition of apples and oranges to obtain bananas.
*/
def +[M2 <: Measure[M2]](quantity: Quantity[N, M2])
(implicit caq: CanAddQuantity[N, M, Quantity[N, M], M2, Quantity[N, M2], M],
cc1: CanConvert[M, M], cc2: CanConvert[M2, M]): caq.QR = caq.plus(this, quantity)

/**
* Subtracts another quantity. CanAdd instance allows addition of apples and oranges to obtain bananas.
* Subtracts another quantity. CanAddQuantity instance allows addition of apples and oranges to obtain bananas.
*/
def -[M2 <: Measure[M2]](quantity: Quantity[N, M2])
(implicit caq: CanAddQuantity[N, M, Quantity[N, M], M2, Quantity[N, M2], M],
cc1: CanConvert[M, M], cc2: CanConvert[M2, M]): caq.QR = caq.plus(this, -quantity)

def /[M2 <: Measure[M2], R <: Measure[R]](quantity: Quantity[N, M2])(implicit cd: CanDivide[M, M2, R]): Quantity[N, R] =
Quantity(qn.divide(value, quantity.value), measure / quantity.measure)
/**
* Divides by another quantity.
*/
def /[M2 <: Measure[M2], R <: Measure[R]](quantity: Quantity[N, M2])(implicit cdq: CanDivideQuantity[N, M, Quantity[N, M], M2, Quantity[N, M2], R]): cdq.QR =
cdq.divide(this, quantity)

def *[M2 <: Measure[M2], R <: Measure[R]](quantity: Quantity[N, M2])(implicit cm: CanMultiply[M, M2, R]): Quantity[N, R] =
Quantity(qn.times(value, quantity.value), measure * quantity.measure)
def *[M2 <: Measure[M2], R <: Measure[R]](quantity: Quantity[N, M2])(implicit cmq: CanMultiplyQuantity[N, M, Quantity[N, M], M2, Quantity[N, M2], R]): cmq.QR =
cmq.times(this, quantity)

def ^[R <: Measure[R]](exponent: Double)(implicit ce: CanExponentiate[M, R]): Quantity[N, R] =
def ^[R <: Measure[R]](exponent: Double)(implicit ce: CanExponentiateQuantity[N, M, Quantity[N, M], R]): Quantity[N, R] =
Quantity(qn.pow(value, exponent), measure ^ exponent)

def to[M2 <: Measure[M2]](target: M2)(implicit cc: CanConvert[M, M2]): Option[Quantity[N, M2]] =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,15 @@ package object arithmetic
a1.flatMap(aa1 => a2.map(_ + aa1)).map(v => Quantity(v, targetMeasure))
}
}

implicit def canDivideQuantity[N, M1 <: Measure[M1], Q1 <: Quantity[N, M1], M2 <: Measure[M2], Q2 <: Quantity[N, M2]](implicit qn: QuasiNumeric[N]) = new CanDivideQuantity[Double, M1, Q1, M2, Q2, RatioMeasure[M1, M2]]
{
type QR = Quantity[N, RatioMeasure[M1, M2]]

override def divide(numerator: M1, denominator: M2): RatioMeasure[M1, M2] = RatioMeasure(numerator, denominator)

override def divide(numerator: Q1, denominator: Q2): QR = Quantity(qn.divide(numerator.value, denominator.value), divide(numerator.measure, denominator.measure))
}
}

object safe extends SafeArithmeticImplicits
Expand Down

0 comments on commit 346386b

Please sign in to comment.