From 8e374d79a9ab94ef0576a692f7680220f0220f3a Mon Sep 17 00:00:00 2001 From: Simon Parten Date: Sat, 11 Nov 2023 19:28:35 +0100 Subject: [PATCH] . --- .../main/scala/vecxt/array.extensions.scala | 65 +++++++------------ ...dlibt.facade.scala => stdlib.facade.scala} | 5 +- .../main/scala/vecxt/array.extensions.scala | 2 + .../main/scala/vecxt/array.extensions.scala | 38 +++-------- .../src/test/scala/arrayExtensions.test.scala | 4 ++ 5 files changed, 43 insertions(+), 71 deletions(-) rename core/js/src/main/scala/vecxt/{stdlibt.facade.scala => stdlib.facade.scala} (82%) diff --git a/core/js/src/main/scala/vecxt/array.extensions.scala b/core/js/src/main/scala/vecxt/array.extensions.scala index bcb27fe..f03d5fd 100644 --- a/core/js/src/main/scala/vecxt/array.extensions.scala +++ b/core/js/src/main/scala/vecxt/array.extensions.scala @@ -1,3 +1,4 @@ +import vecxt.blas /* * Copyright 2023 quafadas * @@ -22,21 +23,22 @@ import scala.scalajs.js import scala.scalajs.js.typedarray.Float64Array import scala.util.chaining.* -// extension (v: Float64Array) -// inline def sort(): Unit = v.asInstanceOf[TypedArrayFacade].sort() -// inline def reverse(): Unit = v.asInstanceOf[TypedArrayFacade].reverse() -// inline def slice(): Float64Array = v.asInstanceOf[TypedArrayFacade].slice() -// end extension +package object vecxt: -// @js.native -// trait TypedArrayFacade extends js.Object: + extension (v: Float64Array) + inline def nativeSort(): Unit = v.asInstanceOf[TypedArrayFacade].sort() + inline def nativeReverse(): Unit = v.asInstanceOf[TypedArrayFacade].reverse() + inline def nativeSlice(): Float64Array = v.asInstanceOf[TypedArrayFacade].slice() + end extension -// def sort(): Unit = js.native -// def reverse(): Unit = -// js.native // mutable https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/reverse -// def slice(): Float64Array = js.native -// end TypedArrayFacade -package object vecxt: + @js.native + trait TypedArrayFacade extends js.Object: + + def sort(): Unit = js.native + def reverse(): Unit = + js.native // mutable https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/reverse + def slice(): Float64Array = js.native + end TypedArrayFacade @js.native trait JsArrayFacade extends js.Object: @@ -199,51 +201,34 @@ package object vecxt: end while end cumsum + inline def norm: Double = blas.dnrm2(vec.length, vec, 1) + inline def -(vec2: Float64Array)(using inline boundsCheck: BoundsCheck): Float64Array = dimCheck(vec, vec2) - blas.daxpy(vec.length, -1.0, vec2, 1, vec, 1) + vec.nativeSlice().tap(_ -= vec2) end - inline def -=(vec2: Float64Array)(using inline boundsCheck: BoundsCheck): Unit = dimCheck(vec, vec2) - var i = 0 - while i < vec.length do - vec(i) = vec(i) - vec2(i) - i = i + 1 - end while + blas.daxpy(vec.length, -1.0, vec2, 1, vec, 1) end -= inline def +(vec2: Float64Array)(using inline boundsCheck: BoundsCheck): Float64Array = dimCheck(vec, vec2) - blas.daxpy(vec.length, 1.0, vec, 1, vec2, 1) + vec.nativeSlice().tap(_ += vec2) end + inline def +=(vec2: Float64Array)(using inline boundsCheck: BoundsCheck): Unit = dimCheck(vec, vec2) - var i = 0 - while i < vec.length do - vec(i) = vec(i) + vec2(i) - i = i + 1 - end while + blas.daxpy(vec.length, 1.0, vec2, 1, vec, 1) end += - inline def *=(d: Double): Float64Array = - var i = 0 - while i < vec.length do - vec(i) = vec(i) * d - i = i + 1 - end while - vec + inline def *=(d: Double): Unit = + blas.dscal(vec.length, d, vec, 1) end *= inline def *(d: Double): Float64Array = - val out = Float64Array(vec.length) - var i = 0 - while i < vec.length do - out(i) = vec(i) * d - i = i + 1 - end while - out + vec.nativeSlice().tap(_ *= d) end * inline def <(num: Double): js.Array[Boolean] = @@ -291,8 +276,6 @@ package object vecxt: In excel f(x) = min(max(x - retention, 0), limit)) - The implementation takes advantage of their existence or not, to optimise the number of operations required. - */ inline def reinsuranceFunction(limitOpt: Option[Limit], retentionOpt: Option[Retention]): Unit = (limitOpt, retentionOpt) match diff --git a/core/js/src/main/scala/vecxt/stdlibt.facade.scala b/core/js/src/main/scala/vecxt/stdlib.facade.scala similarity index 82% rename from core/js/src/main/scala/vecxt/stdlibt.facade.scala rename to core/js/src/main/scala/vecxt/stdlib.facade.scala index 3595637..7e02901 100644 --- a/core/js/src/main/scala/vecxt/stdlibt.facade.scala +++ b/core/js/src/main/scala/vecxt/stdlib.facade.scala @@ -26,6 +26,9 @@ object blas extends ArrayOps @js.native trait ArrayOps extends js.Object: - def daxpy(N: Int, alpha: Double, x: Float64Array, strideX: Int, y: Float64Array, strideY: Int): Float64Array = + def daxpy(N: Int, alpha: Double, x: Float64Array, strideX: Int, y: Float64Array, strideY: Int): Unit = js.native + + def dscal(N: Int, alpha: Double, x: Float64Array, strideX: Int): Unit = js.native + def dnrm2(N: Int, x: Float64Array, strideX: Int): Double = js.native end ArrayOps diff --git a/core/jvm/src/main/scala/vecxt/array.extensions.scala b/core/jvm/src/main/scala/vecxt/array.extensions.scala index 82cd00d..6915ee9 100644 --- a/core/jvm/src/main/scala/vecxt/array.extensions.scala +++ b/core/jvm/src/main/scala/vecxt/array.extensions.scala @@ -167,6 +167,8 @@ package object vecxt: end while end cumsum + inline def norm: Double = blas().dnrm2(vec.length, vec, 1) + inline def -(vec2: Array[Double])(using inline boundsCheck: BoundsCheck): Array[Double] = dimCheck(vec, vec2) vec.clone.tap(_ -= vec2) diff --git a/core/native/src/main/scala/vecxt/array.extensions.scala b/core/native/src/main/scala/vecxt/array.extensions.scala index 821a55b..3ebfd8d 100644 --- a/core/native/src/main/scala/vecxt/array.extensions.scala +++ b/core/native/src/main/scala/vecxt/array.extensions.scala @@ -18,7 +18,7 @@ import org.ekrich.blas.unsafe.* import vecxt.BoundsChecks.BoundsCheck import vecxt.Limits.Limit import vecxt.Retentions.Retention - +import scala.util.chaining.* import scala.scalanative.unsafe.* package object vecxt: @@ -176,15 +176,11 @@ package object vecxt: end while end cumsum + inline def norm: Double = blas.cblas_dnrm2(vec.length, vec.at(0), 1) + inline def -(vec2: Array[Double])(using inline boundsCheck: BoundsCheck) = dimCheck(vec, vec2) - val out = new Array[Double](vec.length) - var i = 0 - while i < vec.length do - out(i) = vec(i) - vec2(i) - i = i + 1 - end while - out + vec.clone.tap(_ -= vec2) end - inline def -=(vec2: Array[Double])(using inline boundsCheck: BoundsCheck): Unit = @@ -192,14 +188,9 @@ package object vecxt: blas.cblas_daxpy(vec.length, -1.0, vec2.at(0), 1, vec.at(0), 1) end -= - inline def +(vec2: Array[Double]) = - val out = new Array[Double](vec.length) - var i = 0 - while i < vec.length do - out(i) = vec(i) + vec2(i) - i = i + 1 - end while - out + inline def +(vec2: Array[Double])(using inline boundsCheck: BoundsCheck) = + dimCheck(vec, vec2) + vec.clone.tap(_ += vec2) end + inline def +=(vec2: Array[Double])(using inline boundsCheck: BoundsCheck): Unit = @@ -208,22 +199,11 @@ package object vecxt: end += inline def *=(d: Double) = - var i = 0 - while i < vec.length do - vec(i) = vec(i) * d - i = i + 1 - end while - vec + blas.cblas_dscal(vec.length, d, vec.at(0), 1) end *= inline def *(d: Double) = - val out = new Array[Double](vec.length) - var i = 0 - while i < vec.length do - out(i) = vec(i) * d - i = i + 1 - end while - out + vec.clone.tap(_ *= d) end * inline def <(num: Double): Array[Boolean] = diff --git a/tests/shared/src/test/scala/arrayExtensions.test.scala b/tests/shared/src/test/scala/arrayExtensions.test.scala index 4694bdb..d43ac1c 100644 --- a/tests/shared/src/test/scala/arrayExtensions.test.scala +++ b/tests/shared/src/test/scala/arrayExtensions.test.scala @@ -143,6 +143,10 @@ class ArrayExtensionSuite extends munit.FunSuite: assertEquals(v_idx3.countTrue, 1) } + test("norm") { + assertEqualsDouble(v_fill.norm, Math.sqrt(1 + 4 + 9 + 16), 0.00001) + } + test("Array indexing") { val v1 = NArray[Double](1.0, 2.0, 3.0) val vIdx = NArray[Boolean](true, false, true)