Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
722b012
setup domain specific module
Quafadas Jan 19, 2026
34cd2bb
.
Quafadas Jan 19, 2026
f758c3d
.
Quafadas Jan 19, 2026
87724b5
.
Quafadas Jan 19, 2026
d031b48
fix boolean suite
Quafadas Jan 19, 2026
188ad73
int array mean and var
Quafadas Jan 19, 2026
16abc28
update variance to accept different modes
Quafadas Jan 19, 2026
8cf8fae
.
Quafadas Jan 19, 2026
9dfce4a
DRY a little
Quafadas Jan 19, 2026
9d827ee
scenarios
Quafadas Jan 19, 2026
5225bfe
fmt
Quafadas Jan 19, 2026
f4cab70
.
Quafadas Jan 19, 2026
e76140f
.
Quafadas Jan 19, 2026
a013054
.
Quafadas Jan 19, 2026
08a606d
.
Quafadas Jan 21, 2026
a194ac3
start reporting
Quafadas Jan 21, 2026
c75e5fe
.
Quafadas Jan 21, 2026
75f41ca
fixy
Quafadas Jan 22, 2026
913d4ac
.
Quafadas Jan 22, 2026
8c57791
.
Quafadas Jan 22, 2026
fd397b4
.
Quafadas Jan 23, 2026
8dbb5b6
.
Quafadas Jan 23, 2026
6276052
.
Quafadas Jan 23, 2026
f05eb13
.
Quafadas Jan 23, 2026
202c187
welfords algorithm
Quafadas Jan 23, 2026
1b98111
.
Quafadas Jan 23, 2026
777ebfa
.
Quafadas Jan 23, 2026
f23672c
.
Quafadas Jan 23, 2026
581da5c
.
Quafadas Jan 23, 2026
bbf5c5e
.
Quafadas Jan 23, 2026
19fa7d0
Add BegBin
Quafadas Jan 25, 2026
678c60b
.
Quafadas Jan 25, 2026
b924f8b
.
Quafadas Jan 26, 2026
42e1795
pareto plot
Quafadas Jan 26, 2026
d38bf05
.
Quafadas Jan 26, 2026
76b8706
.
Quafadas Jan 26, 2026
75eece2
.
Quafadas Jan 26, 2026
6ad8d69
[autofix.ci] apply automated fixes
autofix-ci[bot] Jan 26, 2026
6087d34
.
Quafadas Jan 26, 2026
802ba9f
Merge branch 're' of https://github.com/Quafadas/vecxt into re
Quafadas Jan 26, 2026
10b4e94
.
Quafadas Jan 26, 2026
e493409
.
Quafadas Jan 26, 2026
c4f7328
[autofix.ci] apply automated fixes
autofix-ci[bot] Jan 26, 2026
76f99b8
.
Quafadas Jan 26, 2026
b7dc52a
.
Quafadas Jan 26, 2026
c3c2a03
scenarr is now a monoid
Quafadas Jan 26, 2026
4957d32
[autofix.ci] apply automated fixes
autofix-ci[bot] Jan 26, 2026
40aa490
oep
Quafadas Jan 26, 2026
16000eb
.
Quafadas Jan 26, 2026
7f0f05d
.
Quafadas Jan 26, 2026
78b5408
[autofix.ci] apply automated fixes
autofix-ci[bot] Jan 26, 2026
7570450
fix
Quafadas Jan 27, 2026
668941d
.
Quafadas Jan 27, 2026
9b45a5b
.
Quafadas Jan 27, 2026
6a0f372
.
Quafadas Jan 28, 2026
4444a29
.
Quafadas Jan 28, 2026
f786575
.
Quafadas Jan 28, 2026
3c849e5
.
Quafadas Jan 28, 2026
bde22f1
poisson
Quafadas Jan 29, 2026
aac13fb
.
Quafadas Jan 29, 2026
4b873f5
.
Quafadas Jan 29, 2026
731d737
.
Quafadas Jan 29, 2026
0c5bdd6
.
Quafadas Jan 29, 2026
0fb4ed7
stats
Quafadas Jan 29, 2026
e76b10e
.
Quafadas Jan 29, 2026
018cb64
.
Quafadas Jan 29, 2026
997dead
[autofix.ci] apply automated fixes
autofix-ci[bot] Jan 29, 2026
884e0bb
.
Quafadas Jan 29, 2026
1a9ca44
.
Quafadas Jan 29, 2026
98696e2
.
Quafadas Jan 29, 2026
02bd306
.
Quafadas Jan 29, 2026
29698c1
[autofix.ci] apply automated fixes
autofix-ci[bot] Jan 29, 2026
a5a8284
.
Quafadas Jan 29, 2026
cef4c87
.
Quafadas Jan 29, 2026
02bbaef
[autofix.ci] apply automated fixes
autofix-ci[bot] Jan 29, 2026
88c8ad1
.
Quafadas Jan 29, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,17 @@ vecxt/
│ ├── src-jvm/ # JVM-specific tests
│ ├── src-js/ # Js-specific tests
│ └── src-native/ # Scala Native-specific tests
├── vecxt_re/ # Domain specific library for reinsurance calculations
│ ├── src/ # Cross-platform shared source code
│ ├── src-jvm/ # JVM-specific implementations (SIMD Vector API)
│ ├── src-js/ # JavaScript-specific implementations
│ ├── src-js-native/ # JavaScript / native shared (DRY) implementations
│ ├── src-native/ # Scala Native-specific implementations
│ └── test/ # Cross-platform test suite (munit)
│ ├── src/ # Shared test source files
│ ├── src-jvm/ # JVM-specific tests
│ ├── src-js/ # Js-specific tests
│ └── src-native/ # Scala Native-specific tests
├── vecxt/ # Main source directory and core published module
│ ├── src/ # Cross-platform shared source code
│ ├── src-jvm/ # JVM-specific implementations (SIMD Vector API)
Expand Down Expand Up @@ -81,4 +92,8 @@ Follow styleguide.md for coding conventions
Use inline methods where possible to avoid dispatch overhead where possible.

## GitHub Actions CI
The project uses GitHub Actions for CI/CD
The project uses GitHub Actions for CI/CD

## Vecxt Re

Contains a bunch of domain specific code for reinsurance calculations, structures, and various reinsurance contract types. It will often rely on Vecxt. You should view the principles as the same - correctness above all else - performance matters. It also aims to eexpose a consistent cross platform API.
19 changes: 19 additions & 0 deletions .github/workflows/autofix.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name: 'autofix.ci'
on:
pull_request:
jobs:
autofix:
if: github.event.pull_request.draft == false
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: 25

- name: Run autoformat
run: ./mill mill.scalalib.scalafmt.ScalafmtModule/reformatAll __.sources

- uses: autofix-ci/action@ff86a557419858bb967097bfc916833f5647fa8c
3 changes: 3 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ jobs:
- name: Test
run: ./mill vecxtensions.${{ matrix.project }}.test

- name: Test
run: ./mill vecxt_re.${{ matrix.project }}.test

- name: Laws Test
if: matrix.project == 'jvm'
run: ./mill laws.${{ matrix.project }}.test
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,6 @@ weights2.csv
biases1.csv
biases2.csv
.DS_Store

.venv/
experiments/src/bhd.scala
52 changes: 19 additions & 33 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -1,49 +1,35 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "scala",
"request": "launch",
"name": "test Suite",
"buildTarget": "vecxt.jvm.test",
"testClass": "vecxt.LongArraysSuite",
"jvmOptions": [
"--add-modules=jdk.incubator.vector"
],
"args": [
"-oD"
]
"name": "plotIndex",
"mainClass": "experiments.plotIndex",
"buildTarget": "file:///Users/simon/Code/vecxt/experiments",
"args": [],
"jvmOptions": [],
"env": {}
},
{
"type": "scala",
"request": "launch",
"name": "debug test",
"buildTarget": "vecxt.jvm.test",
"testClass": "vecxt.MatrixAdditionTest",
"jvmOptions": [
"--add-modules=jdk.incubator.vector"
],
"args": [
"-oD"
],
"env": {},
"internalConsoleOptions": "openOnSessionStart",
"preLaunchTask": "",
"postDebugTask": ""
"name": "readXl",
"mainClass": "experiments.readXl",
"buildTarget": "file:///Users/simon/Code/vecxt/experiments",
"args": [],
"jvmOptions": [],
"env": {}
},
{
"type": "scala",
"request": "attach",
"name": "Attach debugger",
// name of the module that is being debugging
"buildTarget": "vecxt.jvm.test",
// Host of the jvm to connect to
"hostName": "localhost",
// Port to connect to
"port": 5005
"request": "launch",
"name": "pricingFun",
"mainClass": "experiments.pricingFun",
"buildTarget": "file:///Users/simon/Code/vecxt/experiments",
"args": [],
"jvmOptions": [],
"env": {}
}
]
}
4 changes: 2 additions & 2 deletions .vscode/mcp.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"servers": {
"vecxt-metals": {
"url": "http://localhost:51891/sse",
"type": "sse"
"url": "http://localhost:51891/mcp",
"type": "http"
}
}
}
2 changes: 1 addition & 1 deletion .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
{
"label": "compiledClassesAndSemanticDbFiles",
"type": "shell",
"command": "./mill __.compiledClassesAndSemanticDbFiles",
"command": "./mill __.jvm.compiledClassesAndSemanticDbFiles",
"runOptions": {
"runOn": "folderOpen"
},
Expand Down
2 changes: 1 addition & 1 deletion benchmark/package.mill
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ object `package` extends JmhModule with ScalaModule:
def scalaVersion = build.vecxt.jvm.scalaVersion
def jmhCoreVersion = "1.37"
override def forkArgs: T[Seq[String]] = super.forkArgs() ++ build.vecIncubatorFlag
override def moduleDeps: Seq[JavaModule] = Seq(build.vecxt.jvm, build.vecxtensions.jvm)
override def moduleDeps: Seq[JavaModule] = Seq(build.vecxt.jvm, build.vecxtensions.jvm, build.vecxt_re.jvm)
def enableBsp = false

// override def generateBenchmarkSources = T{
Expand Down
94 changes: 94 additions & 0 deletions benchmark/src/LossReportBenchmark.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package vecxt.benchmark

import org.openjdk.jmh.annotations.*
import org.openjdk.jmh.infra.Blackhole
import scala.compiletime.uninitialized
import scala.util.Random
import vecxt_re.*
import vecxt_re.ReReporting.*
import vecxt.all.*

// ./mill benchmark.runJmh "vecxt.benchmark.LossReportBenchmark" -jvmArgs --add-modules=jdk.incubator.vector -rf json -wi 1 -i 3 -f 1

/** 231] Benchmark (numEventsStr) (numIterationsStr) Mode Cnt Score Error Units 231] LossReportBenchmark.lossReport_fast
* 10000 100 thrpt 3 177346.981 ± 24137.324 ops/s 231] LossReportBenchmark.lossReport_fast 10000 1000 thrpt 3
* 180400.504 ± 8719.687 ops/s 231] LossReportBenchmark.lossReport_fast 100000 100 thrpt 3 11731.510 ± 1945.957 ops/s
* 231] LossReportBenchmark.lossReport_fast 100000 1000 thrpt 3 17443.246 ± 425.030 ops/s 231]
* LossReportBenchmark.lossReport_separate 10000 100 thrpt 3 46850.187 ± 7232.734 ops/s 231]
* LossReportBenchmark.lossReport_separate 10000 1000 thrpt 3 49876.719 ± 5238.487 ops/s 231]
* LossReportBenchmark.lossReport_separate 100000 100 thrpt 3 3360.234 ± 326.993 ops/s 231]
* LossReportBenchmark.lossReport_separate 100000 1000 thrpt 3 4706.819 ± 615.832 ops/s
*/

@State(Scope.Thread)
class LossReportBenchmark extends BLASBenchmark:

@Param(Array("10000", "100000"))
var numEventsStr: String = uninitialized

@Param(Array("100", "1000"))
var numIterationsStr: String = uninitialized

var years: Array[Int] = uninitialized
var ceded: Array[Double] = uninitialized
var layerObj: Layer = uninitialized

@Setup(Level.Trial)
def setup: Unit =
val rng = new Random(0)
val numEvents = numEventsStr.toInt
val numIterations = numIterationsStr.toInt

val yrs = Array.ofDim[Int](numEvents)
var i = 0
while i < numEvents do
yrs(i) = rng.nextInt(numIterations) + 1 // 1-based group indices
i += 1
end while

java.util.Arrays.sort(yrs)

years = yrs

ceded = Array.ofDim[Double](numEvents)
i = 0
while i < numEvents do
// random loss values between 0 and 100
ceded(i) = rng.nextDouble() * 100.0
i += 1
end while

// Choose a layer with a moderate aggLimit to cause some exhaustion hits
layerObj = Layer(occLimit = Some(100.0), aggLimit = Some(50.0))
()
end setup

@Benchmark
def lossReport_fast(bh: Blackhole) =
val calcd = (layerObj, ceded)
val r = calcd.lossReport(numIterationsStr.toInt, years, ReportDenominator.FirstLimit)
// consume fields so JMH doesn't optimize away
bh.consume(r.el)
bh.consume(r.stdDev)
bh.consume(r.attachProb)
bh.consume(r.exhaustProb)
end lossReport_fast

@Benchmark
def lossReport_separate(bh: Blackhole) =
val calcd = (layerObj, ceded)
val n = numIterationsStr.toInt
val reportLimit = ReportDenominator.FirstLimit.fromlayer(layerObj)

val el = calcd.expectedLoss(n) / reportLimit
val std = calcd.std(n, years) / reportLimit
val attach = calcd.attachmentProbability(n, years)
val exhaust = calcd.exhaustionProbability(n, years)

bh.consume(el)
bh.consume(std)
bh.consume(attach)
bh.consume(exhaust)
end lossReport_separate

end LossReportBenchmark
25 changes: 19 additions & 6 deletions benchmark/src/groupOpsBenchmark.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,12 @@ import org.openjdk.jmh.annotations.*
import org.openjdk.jmh.infra.Blackhole
import scala.compiletime.uninitialized
import vecxtensions.*
import vecxt_re.*
import java.util.Random
import java.util.concurrent.TimeUnit

// ./mill benchmark.runJmh "vecxt.benchmark.LossReportBenchmark" -jvmArgs --add-modules=jdk.incubator.vector -rf json -wi 1 -i 3 -f 1

@State(Scope.Thread)
@BenchmarkMode(Array(Mode.AverageTime))
@OutputTimeUnit(TimeUnit.NANOSECONDS)
Expand Down Expand Up @@ -91,11 +94,21 @@ class GroupOpsBenchmark:
bh.consume(valuesCopy2)
end benchGroupDiffInPlace

@Benchmark
def benchGroupSum(bh: Blackhole): Unit =
val (uniqueGroups, sums) = groupSum(groups, values)
bh.consume(uniqueGroups)
bh.consume(sums)
end benchGroupSum
// @Benchmark
// def benchGroupSum(bh: Blackhole): Unit =
// // groupSum in vecxt_re takes nitr; compute number of groups then call it
// var maxGroup = 0
// var i = 0
// while i < groups.length do
// if groups(i) > maxGroup then maxGroup = groups(i)
// end if
// i += 1
// end while
// val numGroups = maxGroup + 1
// val sums = groupSum(groups, values, numGroups)
// val uniqueGroups = Array.tabulate(numGroups)(identity)
// bh.consume(uniqueGroups)
// bh.consume(sums)
// end benchGroupSum

end GroupOpsBenchmark
4 changes: 2 additions & 2 deletions benchmark/src/splitAmnt.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ import org.openjdk.jmh.infra.Blackhole
import scala.compiletime.uninitialized
import vecxt.all.*
import vecxt.all.given
import vecxt.reinsurance.*
import vecxt_re.*
import jdk.incubator.vector.VectorSpecies
import jdk.incubator.vector.VectorOperators
import jdk.incubator.vector.DoubleVector
import java.util.Random
import vecxt.reinsurance.SplitLosses.splitAmntFast
import vecxt_re.SplitLosses.splitAmntFast

// mill benchmark.runJmh vecxt.benchmark.SplitAmntBenchmark -jvmArgs --add-modules=jdk.incubator.vector -rf json
@State(Scope.Thread)
Expand Down
37 changes: 27 additions & 10 deletions benchmark/src/variance.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,18 @@ import jdk.incubator.vector.VectorSpecies
import jdk.incubator.vector.VectorOperators
import jdk.incubator.vector.DoubleVector

// ./mill benchmark.runJmh "vecxt.benchmark.VarianceBenchmark" -jvmArgs --add-modules=jdk.incubator.vector -rf json -wi 2 -i 3 -f 1

/** 231] Benchmark (len) Mode Cnt Score Error Units 231] VarianceBenchmark.var_simd_twopass 1000 thrpt 3 1087302.435 ±
* 16013.286 ops/s 231] VarianceBenchmark.var_simd_twopass 100000 thrpt 3 9578.869 ± 334.606 ops/s 231]
* VarianceBenchmark.var_simd_welford 1000 thrpt 3 436244.559 ± 6158.585 ops/s 231] VarianceBenchmark.var_simd_welford
* 100000 thrpt 3 4187.715 ± 203.266 ops/s
*/

@State(Scope.Thread)
class VarianceBenchmark extends BLASBenchmark:

@Param(Array("3", "128", "100000"))
@Param(Array("1000", "100000"))
var len: String = uninitialized;

var arr: Array[Double] = uninitialized
Expand All @@ -32,20 +40,29 @@ class VarianceBenchmark extends BLASBenchmark:
vec.map(i => (i - μ) * (i - μ)).sumSIMD / (vec.length - 1)
end extension


// @Benchmark
// def var_naive_twopass(bh: Blackhole) =
// val r = arr.variance2
// bh.consume(r);
// end var_naive_twopass

@Benchmark
def var_loop(bh: Blackhole) =
val r = arr.variance2
def var_simd_twopass(bh: Blackhole) =
val r = arr.meanAndVarianceTwoPass(VarianceMode.Sample).variance
bh.consume(r);
end var_loop
end var_simd_twopass

// @Benchmark
// def var_simd_welford(bh: Blackhole) =
// val r = arr.meanAndVarianceWelfordSIMD(VarianceMode.Sample).variance
// bh.consume(r);
// end var_simd_welford

@Benchmark
def var_vec(bh: Blackhole) =
val r = arr.variance
bh.consume(r);
end var_vec
// @Benchmark
// def var_default(bh: Blackhole) =
// val r = arr.variance(VarianceMode.Sample)
// bh.consume(r);
// end var_default
end VarianceBenchmark


Loading