Skip to content

Commit

Permalink
Refactored min and max methods to a family of clamp extension methods.
Browse files Browse the repository at this point in the history
Optimized copy extension method
  • Loading branch information
c committed Oct 4, 2023
1 parent 26f1abb commit 6b4bcee
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 43 deletions.
Binary file added elementRanksVerification.ods
Binary file not shown.
47 changes: 18 additions & 29 deletions slash/shared/src/main/scala/ai/dragonfly/math/vector/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -25,34 +25,11 @@ import scala.language.implicitConversions

import scala.compiletime.ops.any.==
import scala.compiletime.ops.int.*
import ai.dragonfly.math.vector.Vec.copy

package object vector {

opaque type Vec[N <: Int] = NArray[Double]


inline def min[N <: Int](inline v: Vec[N], lt: Double) : Vec[N] = {
import Vec.dimension
val vOut = v.copy
var i = 0
while (i < v.dimension) {
if (v(i) > lt) vOut(i) = lt
i = i + 1
}
vOut
}

inline def max[N <: Int](v: Vec[N], gt: Double) : Vec[N] = {
import Vec.dimension
val vOut = v.copy
var i = 0
while (i < v.dimension) {
if (v(i) < gt) vOut(i) = gt
i = i + 1
}
vOut
}
object Vec {

export narr.Extensions.given
Expand Down Expand Up @@ -186,16 +163,28 @@ package object vector {

inline def dimension: Int = thisVector.length

def copy:Vec[N] = {
val copyOfThisVector:Vec[N] = new NArray[Double](dimension)
var i = 0
while (i < dimension) {
copyOfThisVector(i) = thisVector(i)
inline def copy:Vec[N] = thisVector.asInstanceOf[NArr[Double]].slice(0, dimension).asInstanceOf[Vec[N]]

// clamp methods

def clamp(lt: Double, gt: Double): Vec[N] = {
var i = 0; while (i < thisVector.dimension) {
if (thisVector(i) < lt) thisVector(i) = lt
else if (thisVector(i) > gt) thisVector(i) = gt
i = i + 1
}
copyOfThisVector
thisVector
}

inline def clampMin(lt: Double): Vec[N] = clamp(lt, Double.MaxValue)
inline def clampMAX(gt: Double): Vec[N] = clamp(Double.MinValue, gt)

inline def clamped(lt: Double, gt: Double):Vec[N] = copy.clamp(lt, gt)

inline def clampedMin(lt: Double): Vec[N] = copy.clamp(lt, Double.MaxValue)
inline def clampedMAX(gt: Double): Vec[N] = copy.clamp(Double.MinValue, gt)


def sum = {
var sum = 0.0
var i = 0
Expand Down
16 changes: 16 additions & 0 deletions tests/shared/src/test/scala/helpers.forTests.scala
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
/*
* Copyright 2023 dragonfly.ai
*
* 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.
*/

import ai.dragonfly.math.vector.Vec


Expand Down
21 changes: 7 additions & 14 deletions tests/shared/src/test/scala/simple.vec.ops.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,51 +14,44 @@ class SimpleOps extends munit.FunSuite:
test("vector subtraction") {
val v1 = Vec[2](1.5, 2.5)
val v2 = Vec[2](2.5, 3.5)

val vResult = Vec[2](-1.0, -1.0)
assertVecEquals(v1 - v2, vResult )
}


test("scalar addition") {
val v1 = Vec[3](1.5, 2.5, 3.5)
val vResult = Vec[3](2.5, 3.5, 4.5)

assertVecEquals( v1 + 1, vResult )
}

test("scalar negation") {
val v1 = Vec[3](1.5, 2.5, 3.5)
val vResult = Vec[3](0.5, 1.5, 2.5)

assertVecEquals( v1 - 1.0, vResult )
}

test("scalar multiplication") {
val v1 = Vec[3](1.5, 2.5, 3.5)
val vResult = Vec[3](3.0, 5.0, 7.0)

assertVecEquals( v1 * 2.0, vResult )
}

test("scalar division") {
val v1 = Vec[3](1.5, 2.5, 3.5)
val vResult = Vec[3](0.75, 1.25, 1.75 )

assertVecEquals( v1 / 2.0, vResult )
}

test("scalar min") {
test("clampedMin") {
val v1 = Vec[3](1.5, 2.5, 3.5)
val vResult = Vec[3](1.5, 2.0, 2.0 )
println( min(v1 , 2.0).csv() )
assertVecEquals( min(v1 , 2.0), vResult )
}
val vResult = Vec[3](2.0, 2.5, 3.5)
assertVecEquals(v1.clampedMin(2.0), vResult)
}

test("scalar max") {
test("clampedMAX") {
val v1 = Vec[3](1.5, 2.5, 3.5)
val vResult = Vec[3](2.0, 2.5, 3.5 )
assertVecEquals( max(v1 , 2.0), vResult )
val vResult = Vec[3](1.5, 2.0, 2.0 )
assertVecEquals( v1.clampedMAX(2.0), vResult )
}

end SimpleOps
Expand Down

0 comments on commit 6b4bcee

Please sign in to comment.