Skip to content

Commit

Permalink
factor conversion classes to own files
Browse files Browse the repository at this point in the history
  • Loading branch information
erikerlandson committed Apr 7, 2024
1 parent c584bc8 commit db6f0f8
Show file tree
Hide file tree
Showing 5 changed files with 340 additions and 285 deletions.
285 changes: 0 additions & 285 deletions core/src/main/scala/coulomb/conversion/conversion.scala

This file was deleted.

89 changes: 89 additions & 0 deletions core/src/main/scala/coulomb/conversion/deltaunit.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/*
* Copyright 2022 Erik Erlandson
*
* 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 coulomb.conversion

import scala.annotation.implicitNotFound

/** Convert a value of type V from implied delta units UF to UT */
@implicitNotFound(
"No unit conversion in scope for value type ${V}, unit types ${UF} => ${UT}"
)
abstract class DeltaUnitConversion[V, B, UF, UT] extends (V => V)

object DeltaUnitConversion:
import scala.compiletime.*
import algebra.ring.*
import spire.math.*
import coulomb.infra.typeexpr
import coulomb.conversion.coefficients.*

inline def offset[V, U, B]: V =
inline erasedValue[V] match
case _: Float => deltaOffsetFloat[U, B].asInstanceOf[V]
case _: Double => deltaOffsetDouble[U, B].asInstanceOf[V]
case _: BigDecimal => deltaOffsetBigDecimal[U, B].asInstanceOf[V]
case _: Rational => deltaOffsetRational[U, B].asInstanceOf[V]
case _ =>
summonFrom {
case _: Fractional[V] =>
ValueConversion[Rational, V](
deltaOffsetRational[U, B]
)
case _ =>
error(
"Cannot instantiate the offset of a non-fractional type"
)
}

private inline def applyShim[V, B, UF, UT](v: V)(using
alg: Rng[V]
): V =
// Rng ("rung") has additive group and mult semigroup
// (c * (v + df)) - dt
alg.minus(
alg.times(
UnitConversion.coefficient[V, UF, UT],
alg.plus(
v,
offset[V, UF, B]
)
),
offset[V, UT, B]
)

inline def apply[V, B, UF, UT](v: V): V =
if (typeexpr.teq[UF, UT]) v
else
applyShim[V, B, UF, UT](v)(using
summonInline[Rng[V]]
)

inline given g_DeltaUnitConversion[V, B, UF, UT](using
Rng[V]
): DeltaUnitConversion[V, B, UF, UT] =
new G_DeltaUnitConversion[V, B, UF, UT](
UnitConversion.coefficient[V, UF, UT],
offset[V, UF, B],
offset[V, UT, B]
)

class G_DeltaUnitConversion[V, B, UF, UT](coef: V, df: V, dt: V)(using
alg: Rng[V]
) extends DeltaUnitConversion[V, B, UF, UT]:
def apply(v: V): V =
// (c * (v + df)) - dt
alg.minus(alg.times(coef, alg.plus(v, df)), dt)
Loading

0 comments on commit db6f0f8

Please sign in to comment.