-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
What if we just have a seperate set of JS methods?
- Loading branch information
Showing
13 changed files
with
738 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,318 @@ | ||
/* | ||
* Copyright 2023 quafadas | ||
* | ||
* 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 vecxt | ||
import vecxt.Limits.Limit | ||
import vecxt.Retentions.Retention | ||
|
||
import scala.util.chaining.* | ||
import vecxt.BoundsCheck | ||
import scala.scalajs.js.typedarray.Float64Array | ||
import scala.scalajs.js | ||
import scala.scalajs.js.annotation.JSBracketAccess | ||
|
||
|
||
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() | ||
|
||
@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 | ||
|
||
extension [A](v: js.Array[A]) | ||
inline def fill(a: A): Unit = v.asInstanceOf[JsArrayFacade].fill(a) | ||
|
||
@js.native | ||
trait JsArrayFacade extends js.Object : | ||
def fill[A](a: A): Unit = js.native | ||
|
||
|
||
extension (vec: js.Array[Boolean]) | ||
inline def countTrue: Int = | ||
var sum = 0 | ||
for i <- 0 until vec.length do if vec(i) then sum = sum + 1 | ||
sum | ||
end countTrue | ||
|
||
inline def &&(thatIdx: js.Array[Boolean]): js.Array[Boolean] = | ||
val result = new js.Array[Boolean](vec.length) | ||
for i <- 0 until vec.length do result(i) = vec(i) && thatIdx(i) | ||
result | ||
end && | ||
|
||
inline def ||(thatIdx: js.Array[Boolean]): js.Array[Boolean] = | ||
val result = new js.Array[Boolean](vec.length) | ||
for i <- 0 until vec.length do result(i) = vec(i) || thatIdx(i) | ||
result | ||
end || | ||
|
||
// def copy: Array[Boolean] = | ||
// val copyOfThisVector: Array[Boolean] = new Array[Boolean](vec.length) | ||
// var i = 0 | ||
// while i < vec.length do | ||
// copyOfThisVector(i) = vec(i) | ||
// i = i + 1 | ||
// end while | ||
// copyOfThisVector | ||
// end copy | ||
end extension | ||
|
||
extension (vec: Float64Array) | ||
|
||
def idxBoolean(index: js.Array[Boolean]) = | ||
val trues = index.countTrue | ||
val newVec = Float64Array(trues) | ||
var j = 0 | ||
for i <- 0 to trues do | ||
// println(s"i: $i || j: $j || ${index(i)} ${vec(i)} ") | ||
if index(i) then | ||
newVec(j) = vec(i) | ||
j += 1 | ||
end for | ||
newVec | ||
end idxBoolean | ||
|
||
def increments: Float64Array = | ||
val out = Float64Array(vec.length) | ||
out(0) = vec(0) | ||
var i = 1 | ||
while i < vec.length do | ||
out(i) = vec(i) - vec(i - 1) | ||
i = i + 1 | ||
end while | ||
out | ||
end increments | ||
|
||
inline def stdDev: Double = | ||
// https://www.cuemath.com/data/standard-deviation/ | ||
val mu = vec.mean | ||
val diffs_2 = vec.map(num => Math.pow(num - mu, 2)) | ||
Math.sqrt(diffs_2.sum / (vec.length - 1)) | ||
end stdDev | ||
|
||
inline def mean: Double = vec.sum / vec.length | ||
|
||
inline def sum: Double = | ||
var sum = 0.0 | ||
var i = 0; | ||
while i < vec.length do | ||
sum = sum + vec(i) | ||
i = i + 1 | ||
end while | ||
sum | ||
end sum | ||
|
||
inline def cumsum = | ||
var i = 1 | ||
while i < vec.length do | ||
vec(i) = vec(i - 1) + vec(i) | ||
i = i + 1 | ||
end while | ||
end cumsum | ||
|
||
inline def -(vec2: Float64Array)(using inline boundsCheck : BoundsCheck) = | ||
dimCheck(vec, vec2) | ||
val out = Float64Array(vec.length) | ||
var i = 0 | ||
while i < vec.length do | ||
out(i) = vec(i) - vec2(i) | ||
i = i + 1 | ||
end while | ||
out | ||
end - | ||
|
||
inline def -=(vec2: Float64Array): Unit = | ||
var i = 0 | ||
while i < vec.length do | ||
vec(i) = vec(i) - vec2(i) | ||
i = i + 1 | ||
end while | ||
end -= | ||
|
||
inline def +(vec2: Float64Array) = | ||
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 | ||
end + | ||
|
||
inline def +=(vec2: Float64Array): Unit = | ||
var i = 0 | ||
while i < vec.length do | ||
vec(i) = vec(i) + vec2(i) | ||
i = i + 1 | ||
end while | ||
end += | ||
|
||
inline def *=(d: Double) = | ||
var i = 0 | ||
while i < vec.length do | ||
vec(i) = vec(i) * d | ||
i = i + 1 | ||
end while | ||
vec | ||
end *= | ||
|
||
inline def *(d: Double) = | ||
val out = Float64Array(vec.length) | ||
var i = 0 | ||
while i < vec.length do | ||
out(i) = vec(i) * d | ||
i = i + 1 | ||
end while | ||
out | ||
end * | ||
|
||
inline def <(num: Double): js.Array[Boolean] = | ||
logicalIdx((a, b) => a < b, num) | ||
|
||
inline def <=(num: Double): js.Array[Boolean] = | ||
logicalIdx((a, b) => a <= b, num) | ||
|
||
inline def >(num: Double): js.Array[Boolean] = | ||
logicalIdx((a, b) => a > b, num) | ||
|
||
inline def >=(num: Double): js.Array[Boolean] = | ||
logicalIdx((a, b) => a >= b, num) | ||
|
||
inline def logicalIdx( | ||
inline op: (Double, Double) => Boolean, | ||
inline num: Double | ||
): js.Array[Boolean] = | ||
val n = vec.length | ||
val idx = new js.Array[Boolean](n).tap(_.fill(false)) | ||
|
||
var i = 0 | ||
while i < n do | ||
if op(vec(i), num) then idx(i) = true | ||
i = i + 1 | ||
end while | ||
idx | ||
end logicalIdx | ||
|
||
/* | ||
Retention and limit are known constants | ||
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 | ||
case (Some(limit), Some(retention)) => | ||
var i = 0; | ||
while i < vec.length do | ||
val tmp = vec(i) - retention | ||
if tmp < 0.0 then vec(i) = 0.0 | ||
else if tmp > limit then vec(i) = limit.toDouble | ||
else vec(i) = tmp | ||
end if | ||
i = i + 1 | ||
end while | ||
|
||
case (None, Some(retention)) => | ||
var i = 0; | ||
while i < vec.length do | ||
val tmp = vec(i) - retention | ||
if tmp < 0.0 then vec(i) = 0.0 | ||
else vec(i) = tmp | ||
i = i + 1 | ||
end while | ||
|
||
case (Some(limit), None) => | ||
var i = 0; | ||
while i < vec.length do | ||
val tmp = vec(i) | ||
if tmp > limit then vec(i) = limit.toDouble | ||
else vec(i) = tmp | ||
i = i + 1 | ||
end while | ||
|
||
case (None, None) => () | ||
|
||
end reinsuranceFunction | ||
|
||
/* | ||
Retention and limit are known constants | ||
In excel f(x) = if(x < retention, 0, if(x > limit, limit, x) | ||
*/ | ||
inline def franchiseFunction(inline limitOpt: Option[Limit], inline retentionOpt: Option[Retention]): Unit = | ||
(limitOpt, retentionOpt) match | ||
case (None, None) => () | ||
|
||
case (Some(limit), Some(retention)) => | ||
var i = 0; | ||
val maxLim = limit.toDouble + retention.toDouble | ||
while i < vec.length do | ||
val tmp = vec(i) | ||
if tmp < retention then vec(i) = 0.0 | ||
else if tmp > maxLim then vec(i) = maxLim | ||
else vec(i) = tmp | ||
end if | ||
i = i + 1 | ||
end while | ||
|
||
case (Some(limit), None) => | ||
var i = 0; | ||
while i < vec.length do | ||
val tmp = vec(i) | ||
if tmp > limit.toDouble then vec(i) = limit.toDouble | ||
else vec(i) = tmp | ||
end if | ||
i = i + 1 | ||
end while | ||
case (None, Some(retention)) => | ||
var i = 0; | ||
while i < vec.length do | ||
val tmp = vec(i) | ||
if tmp > retention.toDouble then vec(i) = tmp | ||
else vec(i) = 0.0 | ||
end if | ||
i = i + 1 | ||
end while | ||
end franchiseFunction | ||
|
||
end extension | ||
|
||
extension (vec: js.Array[Float64Array]) | ||
inline def horizontalSum: Float64Array = | ||
val out = new Float64Array(vec.head.length) | ||
var i = 0 | ||
while i < vec.head.length do | ||
var sum = 0.0 | ||
var j = 0 | ||
while j < vec.length do | ||
sum += vec(j)(i) | ||
// pprint.pprintln(s"j : $j i : $i vecij : ${vec(j)(i)} out : ${out(i)} sum : $sum") | ||
j = j + 1 | ||
end while | ||
out(i) = sum | ||
i = i + 1 | ||
end while | ||
out | ||
end extension |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
/* | ||
* Copyright 2023 quafadas | ||
* | ||
* 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 vecxt | ||
|
||
import scala.scalajs.js.typedarray.Float64Array | ||
|
||
object dimCheck: | ||
inline def apply(a: Float64Array, b : Float64Array) (using inline doCheck: BoundsCheck)= | ||
inline if doCheck then | ||
if a.length != b.length then throw VectorDimensionMismatch(a.length, b.length) | ||
|
||
case class VectorDimensionMismatch(givenDimension:Int, requiredDimension:Int) extends Exception( | ||
s"Expected Vector dimensions to match. First dimension was : $requiredDimension, second was : $givenDimension ." | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import scala.scalajs.js.typedarray.Float64Array | ||
|
||
import scala.util.chaining.* | ||
import vecxt.* | ||
|
||
@main def checkBytecode = | ||
val a = Float64Array(3).tap(_.fill(1.0)) | ||
val a1 = Float64Array(3).tap(_.fill(2.0)) | ||
// val b = Array[Boolean](true, false, true) | ||
// val c = Array[Boolean](false, true, true) | ||
|
||
import vecxt.BoundsCheck.yes | ||
|
||
a - a1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
2 changes: 1 addition & 1 deletion
2
core/shared/src/main/scala/vecxt/main.scala → ...vm-native/src/main/scala/vecxt/main.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
package vecxt | ||
|
||
import vecxt.* | ||
|
||
@main def checkBytecode = | ||
val a = Array[Double](1,2,3) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
package vecxt | ||
|
||
enum LossCalc: | ||
case Agg, Occ | ||
end LossCalc |
Oops, something went wrong.