Compare commits

...

643 Commits

Author SHA1 Message Date
ab16bd16ac Fix benchmark results script 2024-08-26 13:37:49 +03:00
222cdc2c14 Add unstable marker to eigenvalue decomposition 2024-08-21 12:06:00 +03:00
6c1a5e62bf Remove buildSrc 2024-08-21 11:56:05 +03:00
1619a49017 Add proper test for symmetric matrices eigenValueDecomposition 2024-08-18 22:45:33 +03:00
b818a8981f Eigenvalue decomposition API
Cosmetic change Double -> Float64
2024-08-17 21:11:13 +03:00
91513a1629 Reimplement random-forking chain 2024-08-14 19:20:05 +03:00
2becee7f59 Reimplement random-forking chain 2024-08-09 22:14:24 +03:00
6619db3f45 Reimplement random-forging chain 2024-08-09 10:22:37 +03:00
48d0ee8126 Add Metropolis-Hastings sampler.
Minor fixes.
2024-08-04 21:26:51 +03:00
57d1cd8c87 Add Metropolis-Hastings sampler.
Minor fixes.
2024-08-04 15:01:47 +03:00
SPC-code
e0997ccf9c
Merge pull request #533 from Vasilev-Ilya/STUD-7_metropolis_hastings_sampler
Draft: STUD-7: Metropolis-Hastings sampler implementation
2024-08-03 21:35:29 +03:00
3e8f44166c add Attributes minus 2024-07-07 11:14:11 +03:00
6e24b563b2 optimize attributes plus 2024-07-07 11:06:20 +03:00
2d309e050b Merge branch 'refs/heads/beta/kotlin2.0.0' into dev 2024-07-07 11:03:48 +03:00
c585c59552 2.0.0 2024-06-04 10:31:42 +03:00
vasilev.ilya
3417d8cdc1 Minor edits. Tests added. | STUD-7 2024-05-20 01:12:27 +03:00
1881feb5e2 Merge pull request 'Fix #532 by making ShapeND a non-value class' (!522) from bug/defaultStridesCache into dev
Reviewed-on: #522
Reviewed-by: Alexander Nozik <altavir@gmail.com>
2024-05-09 09:16:52 +03:00
Gleb Minaev
201887187d Make ShapeND a usual non-value class. Implement its equals and hashCode methods. Deprecate contentEquals and contentHashCode. 2024-05-08 21:59:49 +03:00
c418607bf6 2.0.0-RC2 2024-04-30 19:41:34 +03:00
dbc5488eb2 Minor edits. Tests added. | STUD-7 2024-04-24 23:29:14 +03:00
d0d250c67f MHS first implementation | STUD-7 2024-04-22 22:01:15 +03:00
9518f16348 Merge branch 'refs/heads/dev' into beta/kotlin2.0.0
# Conflicts:
#	gradle.properties
2024-04-20 09:22:19 +03:00
fc0393436f Document ShapeND.asArray() 2024-04-15 18:01:58 +03:00
9228e6019c Update Attributes version 2024-04-15 17:57:00 +03:00
edbf8c05be cleanup Minuit 2024-04-15 17:52:15 +03:00
SPC-code
f335d63659
Update docs/buffers.md
Co-authored-by: Gleb Minaev <43728100+lounres@users.noreply.github.com>
2024-04-15 17:42:52 +03:00
SPC-code
c696a22f62
Update kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/GaussIntegrator.kt
Co-authored-by: Gleb Minaev <43728100+lounres@users.noreply.github.com>
2024-04-15 17:41:52 +03:00
2fe04040c6 Fix AttributeBuilder inlining 2024-03-27 09:58:28 +03:00
255d4ba6b7 Dump API. Update readme 2024-03-27 09:51:23 +03:00
48b334a2b6 Singleton implementation for Attributes.EMPTY 2024-03-27 09:45:56 +03:00
ac851bea62 Change logic of AttributesBuilder. It no longer exposes the constructor 2024-03-27 09:18:46 +03:00
3b74968f9a Change logic of AttributesBuilder. It no longer exposes the constructor 2024-03-27 09:11:35 +03:00
214467d21c Reformat code 2024-03-27 09:11:12 +03:00
ecb5d28110 Attributes modify->modified 2024-03-27 08:51:56 +03:00
ec88d6be9e Remove unnecessary reification 2024-03-27 08:19:22 +03:00
461e5a7c54 Refactor names for AttributesBuilder behavior 2024-03-27 08:12:39 +03:00
1be6a5ca0e LinearSpace.compute -> LinearSpace.withComputedAttribute 2024-03-27 07:45:57 +03:00
a67bda8a33 Adjust build 2024-03-27 07:44:53 +03:00
efef5996e1 Remove contracts 2024-03-27 07:44:33 +03:00
69b59b43f4 Mark polymorphic attribute getters and setters as unstable 2024-03-27 07:43:54 +03:00
0af8147be6 Remove unnecessary internal dependencies 2024-03-26 09:58:50 +03:00
bd9430bab4 Merge branch 'dev' into beta/kotlin2.0.0
# Conflicts:
#	gradle.properties
#	kmath-histograms/build.gradle.kts
#	kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/Histogram.kt
2024-03-19 09:15:55 +03:00
82196250f6 Remove unnecessary internal dependencies 2024-03-17 09:42:50 +03:00
86324a9219 Add RingBuffer reset and capacity 2024-03-17 09:29:15 +03:00
203a350650 Merge remote-tracking branch 'github/dev' into dev 2024-03-08 10:19:20 +03:00
b076a6573a Update versions 2024-03-08 10:18:32 +03:00
SPC-code
e7d8b94889
Update attributes-kt/src/commonMain/kotlin/space/kscience/attributes/SafeType.kt
Co-authored-by: Gleb Minaev <43728100+lounres@users.noreply.github.com>
2024-03-08 10:07:54 +03:00
5dea38eef8 Merge remote-tracking branch 'github/dev' into dev 2024-03-08 10:07:28 +03:00
SPC-code
dcf5b19d80
Update attributes-kt/src/commonMain/kotlin/space/kscience/attributes/Attributes.kt
Co-authored-by: Gleb Minaev <43728100+lounres@users.noreply.github.com>
2024-03-08 10:06:30 +03:00
11722db3c8 Add Attributes container equality 2024-03-08 10:04:37 +03:00
fcb7e2fa7d Reverse types for buffers and typealiases for geometry. 2024-02-22 21:03:58 +03:00
dba001eff3 Fix types in geometry algebras 2024-02-20 20:39:57 +03:00
49f0d1fe7d Fix types in geometry algebras 2024-02-20 19:35:00 +03:00
ad66a63ac2 Merge remote-tracking branch 'github/dev' into dev 2024-02-20 19:05:58 +03:00
32c5b3c10d Add publishing to attributes-kt 2024-02-20 18:38:21 +03:00
SPC-code
bc1b75f79e
Merge branch 'master' into dev 2024-02-18 15:10:51 +03:00
fd9da63ef9 Prepare for 0.4.0 release 2024-02-18 15:05:56 +03:00
024e2a1a4f Add .kotlin to gitignore 2024-02-18 14:26:47 +03:00
41a325d428 fix dot bug introduced in the last refactor. Add test for parallel linear algebra. 2024-02-18 14:22:20 +03:00
79642a869d LUP cleanup 2024-02-18 14:00:38 +03:00
fbee95ab8b LUP cleanup 2024-02-18 13:32:22 +03:00
10739e0d04 Performance fixes 2024-02-18 12:27:46 +03:00
f8e91c2402 Finishing fixes 2024-02-17 21:32:26 +03:00
7d88fb0166 Merge branch 'dev' into dev-0.4
# Conflicts:
#	kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/_generated.kt
2024-02-16 18:57:57 +03:00
ca9df8a167 Add more corner cases for complex power 2024-02-08 18:06:06 +03:00
9e3fd240b8 Update versions 2024-02-08 17:39:19 +03:00
a526dcc16b Merge branch 'dev' into dev-0.4
# Conflicts:
#	kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/MatrixFeatures.kt
#	kmath-core/src/commonMain/kotlin/space/kscience/kmath/misc/Featured.kt
#	kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/_generated.kt
#	kmath-memory/src/commonMain/kotlin/space/kscience/kmath/memory/MemoryBuffer.kt
#	kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/OptimizationBuilder.kt
2024-02-07 21:53:49 +03:00
83d9e1f0af Merge remote-tracking branch 'github/dev' into dev 2024-02-07 21:42:49 +03:00
8a754ace19 Fixed GitHub #524 (Complex power of real-valued number 2024-02-07 21:18:47 +03:00
9f9c4a347b Fix all issues for 2.0.0 2024-01-28 18:35:47 +03:00
c6f6191ef1 Deprecate direct angle conversion 2024-01-28 18:15:33 +03:00
SPC-code
960a334b8e
Merge pull request #522 from SciProgCentre/copyright-upgrade
Update/Add copyright comments. Regenerate code for kmath-ejml.
2024-01-05 09:56:22 +03:00
Gleb Minaev
cc4159be67 Update/Add copyright comments. Regenerate code for kmath-ejml. 2024-01-05 01:50:27 +03:00
24b934eab7 Add Buffer.asList() 2023-11-22 14:32:56 +03:00
9e88bff668 Kotlin 2.0.0-Beta1 2023-11-22 09:22:28 +03:00
5c82a5e1fa 0.4 WIP 2023-11-18 22:29:59 +03:00
2f2f552648 0.4 WIP 2023-11-11 10:19:09 +03:00
2386ecba41 0.4 WIP 2023-11-04 11:49:31 +03:00
46eacbb750 0.4 WIP 2023-11-03 09:56:19 +03:00
ea887b8c72 0.4 WIP 2023-11-01 08:55:47 +03:00
544b8610e1 Merge branch 'dev' into dev-0.4
# Conflicts:
#	buildSrc/settings.gradle.kts
#	gradle.properties
#	gradle/wrapper/gradle-wrapper.properties
#	kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Circle2D.kt
#	kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Float32Space2D.kt
#	kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Float64Space2D.kt
#	kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/quaternionOperations.kt
2023-10-31 14:18:50 +03:00
a84f1e1500 Merge branch 'kotlin/1.9.20' into dev 2023-10-31 14:05:37 +03:00
328d45444c 1.9.20 finalization 2023-10-31 14:05:17 +03:00
1765f8cf8c Remove asPolynomial 2023-10-25 10:28:39 +03:00
bfb556b013 remove webpack and node version fixture 2023-10-03 19:33:39 +03:00
5129f29084 update geometry 2023-09-22 09:53:44 +03:00
56933ecff3 1.9.20-Beta2 2023-09-22 09:04:39 +03:00
12a02320ec Merge branch 'dev' into kotlin/1.9.20
# Conflicts:
#	build.gradle.kts
2023-09-22 08:33:40 +03:00
7a4e9e70f9 add some quaternion operations 2023-09-22 08:21:14 +03:00
23c0758ba6 Kotlin 1.9.20 2023-09-13 13:25:54 +03:00
dd3d38490a [WIP] refactor features to attributes 2023-09-13 09:00:56 +03:00
9da14089e0 Update integration to use Attributes 2023-08-14 10:06:23 +03:00
5196322b7a Update integration to use Attributes 2023-08-13 19:13:39 +03:00
eff70eb690 Refactor rotations. Add Rotation matrix to Euler conversion 2023-08-13 14:51:50 +03:00
67994d35d9 Merge branch 'dev' into dev-0.4
# Conflicts:
#	CHANGELOG.md
#	build.gradle.kts
#	examples/src/main/kotlin/space/kscience/kmath/operations/mixedNDOperations.kt
#	kmath-commons/src/main/kotlin/space/kscience/kmath/commons/linear/CMMatrix.kt
#	kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/Float64LinearSpace.kt
#	kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LupDecomposition.kt
#	kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Float64FieldND.kt
#	kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Circle2D.kt
#	kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Float64Space2D.kt
#	kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean3d/Float64Space3D.kt
#	kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/vectorPrecision.kt
#	kmath-nd4j/src/main/kotlin/space/kscience/kmath/nd4j/Nd4jTensorAlgebra.kt
#	kmath-tensorflow/src/main/kotlin/space/kscience/kmath/tensorflow/DoubleTensorFlowAlgebra.kt
#	kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensorAlgebra.kt
#	kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/IntTensorAlgebra.kt
#	kmath-viktor/src/main/kotlin/space/kscience/kmath/viktor/ViktorFieldOpsND.kt
2023-08-12 21:38:43 +03:00
efb853c1bc Refactor geometry 2023-08-12 13:16:18 +03:00
19bebfd1ed Finish naming change 2023-08-12 11:21:59 +03:00
62f1c59d73 Fix Median statistics. Update algebra naming. Add integer fields 2023-08-12 10:46:43 +03:00
976714475e levenbergMarquardt cleanup 2023-07-28 20:56:31 +03:00
1e2a8a40e5 levenbergMarquardt cleanup 2023-07-28 20:39:05 +03:00
cfac7ecffc Merge branch 'dev' into dev-0.4 2023-07-28 12:02:17 +03:00
14f0fa1a6f Merge remote-tracking branch 'space/dev' into dev 2023-07-18 11:15:27 +03:00
a3c65e5b17 [WIP] Features to Attributes refactoring 2023-07-18 11:14:23 +03:00
4abe25c188 [WIP] Features to Attributes refactoring 2023-07-18 10:13:36 +03:00
6da51b7794 [WIP] Features to Attributes refactoring 2023-07-09 15:51:50 +03:00
a001c74025 1.9.0-RC 2023-06-22 08:49:51 +03:00
d3893ab7e6 [WIP] moving from features to attributes 2023-06-20 19:45:21 +03:00
SPC-code
7e46c7de4e
Merge pull request #513 from margarita0303/dev
Added Levenberg-Marquardt algorithm and svd Golub-Kahan
2023-06-19 16:11:56 +03:00
Gleb Minaev
e00c2a4e2b Fix version of matheclipse-core. 2023-06-16 16:00:48 +03:00
Margarita Lashina
5f2690309b fix mistake in streaming version 2023-06-13 03:06:55 +03:00
c0a7cff1d8 Merge branch 'dev' into dev-0.3.2
# Conflicts:
#	build.gradle.kts
#	gradle/wrapper/gradle-wrapper.properties
#	kmath-core/build.gradle.kts
#	kmath-tensors/build.gradle.kts
2023-06-11 09:10:31 +03:00
009f93adbb Add rotation coversion test for XYZ 2023-06-08 09:28:26 +03:00
Margarita Lashina
ef4335bc41 use function types for input func 2023-06-07 15:24:01 +03:00
1f6b7abf46 wasm test version 2023-06-07 15:16:58 +03:00
Margarita Lashina
f91b018d4f add assertEquals to middle and difficult test 2023-06-07 07:24:47 +03:00
Margarita Lashina
346e2e97f2 add minor fixes 2023-06-07 06:14:05 +03:00
Margarita Lashina
0655642933 add documentation to the main function levenbergMarquardt 2023-06-07 06:00:58 +03:00
Margarita Lashina
e8dafad6c5 the input data is placed in a separate class, to which the documentation is written 2023-06-07 05:25:32 +03:00
Margarita Lashina
162e37cb2f removed extra comments, unnecessary variables, renaming variables and secondary functions 2023-06-07 02:52:00 +03:00
Margarita Lashina
cac5b513f3 made class for settings private and removed settings as input from a custom function 2023-06-07 01:55:38 +03:00
Margarita Lashina
0c7f5697da add documentation for enum TypeOfConvergence 2023-06-07 00:50:27 +03:00
Margarita Lashina
1ed40cd8ce fix problem with imports 2023-06-06 20:43:59 +03:00
Margarita Lashina
29d392a8a0 fix problem with imports 2023-06-06 20:31:15 +03:00
Margarita Lashina
963e14b00a move enums 2023-06-06 20:07:42 +03:00
c940645e2e fix simja version 2023-06-06 17:43:38 +03:00
Margarita Lashina
c017d58265 Merge remote-tracking branch 'origin/dev' into dev 2023-06-06 01:42:57 +03:00
Margarita Lashina
8d81d2d8d5 move lm-algorithm from DoubleTensorAlgebra as extension 2023-06-06 01:41:08 +03:00
Margarita
f65a463773
Merge branch 'dev' into dev 2023-06-06 00:56:12 +03:00
Margarita
2ead722620
Merge pull request #4 from margarita0303/streaming_lm_algorithm
tests changed
2023-06-06 00:40:14 +03:00
Margarita Lashina
47600dff23 tests changed 2023-06-06 00:39:19 +03:00
Margarita
3a1817586f
Merge pull request #3 from margarita0303/streaming_lm_algorithm
Streaming lm algorithm, tests and examples
2023-05-29 15:15:02 +03:00
Margarita Lashina
1afb0d0a4c fixed time for js tests for lm 2023-05-29 15:13:13 +03:00
Margarita Lashina
33cb317cee added examples and tests 2023-05-28 23:07:01 +03:00
Margarita Lashina
20c20a30e8 y_dat added generation 2023-05-27 16:07:13 +03:00
Margarita Lashina
e738fbc86d typo fixed 2023-05-27 01:24:37 +03:00
Margarita Lashina
ce16946105 added streaming version of LM 2023-05-27 01:16:43 +03:00
Margarita Lashina
a18fa01100 added parameter check in tests 2023-05-26 21:53:50 +03:00
65c6962544 Update build tools 2023-05-26 16:46:18 +03:00
3e9d28be31 Update build tools 2023-05-26 11:38:50 +03:00
SPC-code
b5f85a6d86
Merge pull request #514 from SciProgCentre/dev
0.3.1
2023-05-12 22:19:48 +03:00
13d6ea2a16 Merge remote-tracking branch 'space/dev' into dev 2023-05-12 20:58:53 +03:00
378180ba09 Pre-release fixes 2023-05-12 20:57:55 +03:00
SPC-code
1c337789a5
Merge branch 'master' into dev 2023-05-10 16:06:34 +03:00
SPC-code
debcef4c9a
Update README.md
change space shield address
2023-05-09 20:34:29 +03:00
SPC-code
acff855c93
Merge branch 'dev' into dev 2023-05-09 20:32:46 +03:00
1222fd4617 Merge remote-tracking branch 'space/master' into dev 2023-05-09 20:14:28 +03:00
8cdbc8dbbe Add opt-ins 2023-05-09 20:12:18 +03:00
4ab2244ac9 update space automation 2023-05-09 19:44:39 +03:00
4ab1b7d0d4 update space automation 2023-05-09 19:28:38 +03:00
8eb25596a0 Variance test post-merge cleanup 2023-05-09 19:22:39 +03:00
4dbcaca87c Merge remote-tracking branch 'space/dev' into dev 2023-05-09 19:01:56 +03:00
1316e6548e Remove vector type from polygon 2023-05-09 19:01:37 +03:00
SPC-code
46b3773419
Merge pull request #511 from mrFendel/mrfendel
VarianceRatioTest implementation for Series
2023-05-09 19:00:21 +03:00
Margarita Lashina
cfe8e9bfee done TODOs, deleted prints and added type of convergence to output of lm 2023-05-07 21:34:20 +03:00
Margarita Lashina
64e563340a fixed error for chi_sq and added more complete output for lm 2023-05-07 17:26:59 +03:00
mrFendel
f44039e309 -- refactoring 2023-05-05 18:50:10 +03:00
mrFendel
16385b5f4e -- refactoring 2023-05-05 18:45:54 +03:00
Margarita Lashina
b526f9a476 added Levenberg-Marquardt algorithm + test 2023-05-04 20:05:32 +03:00
Margarita Lashina
89a5522144 added new svd algorithm (Golub Kahan) and used by default for svd 2023-05-04 00:44:18 +03:00
Margarita Lashina
19c1af1874 added helper functions for levenberg-marquardt algorithm 2023-05-03 21:25:30 +03:00
Margarita Lashina
10f84bd630 added function solve 2023-05-03 21:14:29 +03:00
40b3fa782c Merge remote-tracking branch 'space/master' into dev-0.3.2 2023-05-03 10:12:01 +03:00
Margarita Lashina
a02085918a Merge remote-tracking branch 'origin/dev' into dev 2023-05-02 23:16:31 +03:00
Margarita
a9627071ff
Merge branch 'SciProgCentre:dev' into dev 2023-05-02 23:16:01 +03:00
Margarita Lashina
a74a7808a2 Merge remote-tracking branch 'origin/dev' into dev 2023-05-02 23:14:37 +03:00
SPC-code
a7c54d3ffb
Merge pull request #512 from SciProgCentre/dependabot/github_actions/dot-github/workflows/gradle/gradle-build-action-2.4.2
Bump gradle/gradle-build-action from 2.1.5 to 2.4.2 in /.github/workflows
2023-05-01 16:54:09 +03:00
dependabot[bot]
0c565c6056
Bump gradle/gradle-build-action in /.github/workflows
Bumps [gradle/gradle-build-action](https://github.com/gradle/gradle-build-action) from 2.1.5 to 2.4.2.
- [Release notes](https://github.com/gradle/gradle-build-action/releases)
- [Commits](https://github.com/gradle/gradle-build-action/compare/v2.1.5...v2.4.2)

---
updated-dependencies:
- dependency-name: gradle/gradle-build-action
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-01 13:50:29 +00:00
f09371a3f9 Explicit mutability for StructureND builders 2023-04-22 09:13:06 +03:00
cdfddb7551 Explicit mutability for StructureND builders 2023-04-21 12:41:46 +03:00
8e281e8b0f Merge remote-tracking branch 'space/dev' into dev 2023-04-21 10:38:01 +03:00
mrFendel
1e27af9cf5 - Zelen-Severo CDF aproximation
- p-value for varianceRatioTest
2023-04-19 17:13:47 +03:00
mrFendel
0193349f94 requirements, default parameters, new Test for varianceRatioTest 2023-04-19 01:36:54 +03:00
mrFendel
98781c83ad fixed bug with heteroscedastic z-score in Variance Ratio Test 2023-04-18 19:16:10 +03:00
mrFendel
e6da61c52a refactoring 2023-04-18 01:53:07 +03:00
mrFendel
dababe3075 Merge remote-tracking branch 'kmath/dev' into mrfendel 2023-04-18 01:02:40 +03:00
Gleb Minaev
85395ff82e Add autodiff example 2023-04-14 21:17:44 +03:00
mrFendel
5b95923bb9 fixed zip in SereiesAlgebra + tests for VarianceRatio 2023-04-14 06:36:20 +03:00
mrFendel
a91b43a52d tests for varianceRatio 2023-04-13 17:52:14 +03:00
mrFendel
0ce1861ab4 refactoring 2023-04-13 03:47:36 +03:00
mrFendel
a68ebef26d zScore for variance Ratio Test 2023-04-13 03:38:10 +03:00
mrFendel
2b83560da8 Variance Ratio function 2023-04-12 22:24:48 +03:00
e76d8e0774 fix zipWithNextCircular on single element 2023-04-12 11:40:27 +03:00
875e32679b [WIP] geometry refactor 2023-04-12 11:39:28 +03:00
mrFendel
31d1cc774a added shiftOperartion and diff 2023-04-11 20:31:04 +03:00
mrFendel
a4ca6e3d58 Merge remote-tracking branch 'kmath/dev' into mrfendel 2023-04-10 19:13:38 +03:00
5965ca940b Merge remote-tracking branch 'space/master' into dev 2023-04-09 14:02:00 +03:00
e1d5409c0d Patch changelog 2023-04-09 11:12:04 +03:00
8ac7567afd Patch changelog 2023-04-09 11:08:39 +03:00
b2746e5c0e Wasm support 2023-04-09 10:55:58 +03:00
ce388fed44 Move annotations to base package. Fix series 2023-04-07 19:55:34 +03:00
mrFendel
4db091d898 deleted TimeSeriesAlgebra 2023-04-07 12:39:30 +03:00
mrFendel
165dfd6c5d Merge branch 'dev-local' into mrfendel
# Conflicts:
#	kmath-stat/src/commonMain/kotlin/space/kscience/kmath/series/SeriesAlgebra.kt
2023-04-07 10:55:25 +03:00
mrFendel
ba26c7020e started TimeSeriesAlgebra 2023-04-06 17:58:29 +03:00
mrFendel
1d7f4ed538 shiftOp and diff in SeriesAlgebra 2023-04-06 03:17:01 +03:00
SPC-code
115736e98a
Merge pull request #510 from SciProgCentre/dev
0.3.1-dev-11
2023-04-05 18:46:35 +03:00
SPC-code
96554d2b0c
Merge branch 'master' into dev 2023-04-05 18:46:20 +03:00
7cc6a4be40 remove trajectory 2023-04-05 15:26:09 +03:00
00ce7d5a48 Obstacle avoidance finished 2023-04-05 13:30:13 +03:00
a0e2ef1afc refactor lines and segments 2023-04-04 19:33:43 +03:00
025cb58060 refactoring directions 2023-04-04 19:02:24 +03:00
639a255aaf refactoring directions 2023-04-04 18:50:17 +03:00
f5201b6be0 refactoring directions 2023-04-04 17:42:40 +03:00
1e46ffbd98 refactoring directions 2023-04-04 16:50:30 +03:00
fd35d7c614 [WIP] refactoring directions 2023-04-04 15:28:02 +03:00
109e050f03 Hieraechy for trajectory types 2023-04-04 15:16:33 +03:00
f809e40791 Disentangle obstacle code phase 1 2023-04-04 11:42:58 +03:00
d08424428e Merge remote-tracking branch 'space/dev' into artdegt 2023-04-04 11:42:22 +03:00
93bc15f346 Merge remote-tracking branch 'space/artdegt' into artdegt 2023-03-28 08:37:26 +03:00
Artyom Degtyarev
11dd4088d9 search for shortest path algorithm 2023-03-24 10:39:51 +03:00
Artyom Degtyarev
24c39c97cd search for shortest path algorithm 2023-03-24 10:30:13 +03:00
Artyom Degtyarev
ea5305c8d8 search for shortest path algorithm 2023-03-24 10:28:02 +03:00
SPC-code
d87eefcaa3
Add macOsArm64 to publish.yml 2023-03-22 18:04:16 +03:00
6d219341f9 Merge branch 'dev' into artdegt 2023-03-22 12:30:28 +03:00
56bba749c0 Update publishing 2023-03-22 10:54:24 +03:00
Artyom Degtyarev
81213eb943 search for shortest path algorithm 2023-03-21 12:04:27 +03:00
c442eb7e94 Fix publish task names 2023-03-19 19:41:31 +03:00
62c8610a9e Update publishing CD 2023-03-19 19:16:46 +03:00
c36af3515e Update trajectory description 2023-03-19 18:39:27 +03:00
ef336af87d Fix vector product 2023-03-16 09:37:03 +03:00
cd2ade881a Revert "Remove the choice of left-handed product. Refactor vectorProduct. Remove leviChivita function."
This reverts commit 28b85b0f53.
2023-03-16 09:33:17 +03:00
5625800fc9
Merge SCI-MR-180: feature/vector-product 2023-03-14 17:16:34 +00:00
Gleb Minaev
28b85b0f53 Remove the choice of left-handed product. Refactor vectorProduct. Remove leviChivita function. 2023-03-14 20:13:34 +03:00
Artyom Degtyarev
4c1ffdb6d9 search for shortest path algorithm 2023-03-14 13:50:42 +03:00
72c7030297 Add time series example stub 2023-03-10 22:50:41 +03:00
a3963ac4f5 Refactor series naming and docs 2023-03-10 21:40:14 +03:00
4871baf0e5 Add vector product to Euclidean3DSpace 2023-03-10 12:01:08 +03:00
Artyom Degtyarev
2bce369c5d search for shortest path algorithm 2023-03-09 16:03:48 +03:00
Artyom Degtyarev
1b6a41c728 search for shortest path algorithm 2023-03-09 08:39:20 +03:00
Artyom Degtyarev
61d43ae5fa search for shortest path algorithm 2023-03-04 21:31:06 +03:00
Artyom Degtyarev
6288eb9d97 Merge branch 'dev' of https://git.jetbrains.space/spc/sci/kmath into artdegt
# Conflicts:
#	kmath-trajectory/src/commonMain/kotlin/space/kscience/kmath/trajectory/tangent.kt
2023-03-04 20:58:35 +03:00
Artyom Degtyarev
2c13386646 search for shortest path algorithm 2023-03-01 10:40:54 +03:00
db61f71440 update build tools 2023-02-18 19:04:07 +03:00
04127fc3f2 Fix tests 2023-02-18 18:53:03 +03:00
Artyom Degtyarev
cc0fb2a718 non-existence of tangents throws exception 2023-02-16 18:47:42 +03:00
ed4aa47913 Minor refactoring of tangents 2023-02-16 10:57:24 +03:00
67316c4a70 Add documentation after circle tangent changes 2023-02-16 10:39:25 +03:00
7d897ad8cb Cleanup after circle tangent changes 2023-02-16 10:29:12 +03:00
Artyom Degtyarev
8998a394b3 tangentsToCircle fixed 2023-02-15 17:55:39 +03:00
Artyom Degtyarev
c342c5cd78 tangentsToCircle fixed 2023-02-15 17:53:32 +03:00
Artyom Degtyarev
d535a2155f tangentsToCircle fixed 2023-02-15 15:06:47 +03:00
Artyom Degtyarev
bef317677c tangentsToCircle fixed 2023-02-15 14:36:58 +03:00
Artyom Degtyarev
50579f4712 added tangent between two circles 2023-02-13 23:17:13 +03:00
784d397ab1 Fix serial names for trajectory serializers 2023-02-12 10:40:53 +03:00
6deeaf057e Add angle serializer 2023-02-11 21:51:19 +03:00
2c6d1e89c5 Update type-safe angles 2023-02-05 20:05:53 +03:00
0366a69123 Refactor trajectory 2023-02-03 19:33:22 +03:00
db30913542 Move to build tools 0.14 2023-02-03 19:32:53 +03:00
d97888f135 Fix test 2023-01-24 21:22:25 +03:00
7f4f4c7703 Update of symbolic operations 2023-01-24 21:01:26 +03:00
2e4be2aa3a A minor change to XYfit arguments 2023-01-24 11:36:53 +03:00
3f4fe9e43b Migrate to 1.8. Use universal autodiffs 2022-12-31 15:02:52 +03:00
6d47c0ccec
Ordered segments in trajectory 2022-12-10 12:30:15 +03:00
29977650f1
Naive classifier notebook 2022-12-10 12:21:56 +03:00
991ab907d8
Encapsulate internal constants in Expression 2022-12-10 11:09:55 +03:00
Margarita
9e141db871
Merge pull request #2 from SciProgCentre/dev
Dev
2022-12-10 04:01:45 +03:00
b14e2fdd08
Moved polynomials to https://github.com/SciProgCentre/kmath-polynomial 2022-11-05 21:44:41 +03:00
cff563c321
Major tensor refactoring 2022-11-05 16:14:23 +03:00
8286db30af
Optimize tensor shape computation 2022-10-16 20:15:37 +03:00
94489b28e2
Fix visibility in Trajectory2D 2022-10-16 14:41:48 +03:00
fb0d016aa8
Perform merge build only on JVM 2022-10-15 18:58:30 +03:00
e24463c58b
Refactor Dubins path 2022-10-15 18:45:06 +03:00
ee569b85f8
Safe shapes 2022-10-14 13:05:39 +03:00
b0abcf2d0c
Safe shapes 2022-10-14 12:47:57 +03:00
c653052d8c
Merge remote-tracking branch 'space/dev' into dev 2022-10-04 09:20:18 +03:00
SPC-code
2376d278c3
Merge pull request #504 from SciProgCentre/dev
Merge to update docs and contributions
2022-10-03 20:58:00 +03:00
89d0cbc7ea
Refactoring and optimization of tensorAlgebra 2022-09-30 11:34:44 +03:00
b602066f48
Change the default strides and unify strides processing 2022-09-27 16:57:06 +03:00
d70389d2e6
Fix after series merge 2022-09-26 16:47:38 +03:00
4d1137659b
Merge branch 'feature/series' into dev
# Conflicts:
#	build.gradle.kts
#	kmath-commons/src/main/kotlin/space/kscience/kmath/commons/transform/Transformations.kt
#	kmath-core/build.gradle.kts
#	kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/AlgebraND.kt
#	kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/BufferAlgebraND.kt
#	kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/BufferND.kt
#	kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/ShapeIndices.kt
#	kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/BufferAlgebra.kt
#	kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/DoubleBufferOps.kt
#	kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/bufferExtensions.kt
#	kmath-histograms/src/jvmMain/kotlin/space/kscience/kmath/histogram/UnivariateHistogram.kt
#	kmath-stat/src/commonMain/kotlin/space/kscience/kmath/distributions/UniformDistribution.kt
#	kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/Sampler.kt
#	kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/BroadcastDoubleTensorAlgebra.kt
#	kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/BufferedTensor.kt
#	kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensorAlgebra.kt
#	kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/broadcastUtils.kt
#	kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/linUtils.kt
#	kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/tensorCastsUtils.kt
#	kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/utils.kt
#	settings.gradle.kts
2022-09-26 13:10:59 +03:00
6bf8d9d325
Naming refactoring 2022-09-26 13:08:49 +03:00
2358f53cf7 Make Circle2D data class 2022-09-15 17:42:37 +03:00
20886d6f6b
Global refactor of tensors 2022-09-11 17:10:26 +03:00
b5d04ba02c
Global refactor of tensors 2022-09-11 15:27:38 +03:00
3729faf49b
Rename Tensor::get to Tensor::getTensor to avoid name clash. 2022-09-05 23:24:01 +03:00
a9821772db
Move power to ExtendedFieldOps 2022-09-05 22:08:35 +03:00
5042fda751
Int Tensor Algebra implementation 2022-09-05 16:30:39 +03:00
ad97751327
Refactor for build tools 0.13.0 2022-09-04 20:59:30 +03:00
0c1d0aa64e
Merge remote-tracking branch 'origin/dev' into dev 2022-08-21 19:18:05 +03:00
ec77cd1fc3
Geometry overhaul 2022-08-21 19:17:38 +03:00
Gleb Minaev
26662b5114
Merge pull request #502 from lounres/fix/#472
Fix #455: Update copyrights
2022-08-21 15:06:41 +03:00
98e21f3c3a
Merge remote-tracking branch 'origin/dev' into dev 2022-08-21 11:40:20 +03:00
978de59b7a
Add rotations converter to Quaternions 2022-08-21 11:40:02 +03:00
5af0c91f0a
Misc 2022-08-21 11:39:41 +03:00
6111c673ee
Type-safe angles 2022-08-21 11:39:17 +03:00
Alexander Nozik
7f77c1e710
Merge pull request #501 from lounres/fix/old-domain-appearances
Replace main `mipt-npm` appearances with `SciProgCentre`.
2022-08-20 09:50:55 +03:00
Gleb Minaev
efe14f50bf #472: Update copyright. 2022-08-19 15:59:13 +03:00
Gleb Minaev
b6d2eb3b1b Replace main mipt-npm appearances with SciProgCentre.
Now link in "Documentation site (WIP)" works.
2022-08-19 15:19:01 +03:00
a8182fad23
Multik went MPP 2022-08-04 09:54:59 +03:00
ee0d44e12e
rename bdot to matmul 2022-08-03 18:20:46 +03:00
e636ed27bd
Merge remote-tracking branch 'origin/dev' into dev 2022-08-03 18:13:08 +03:00
5402ba47c9
Restrict tensor dot ot vectors and matrices only. Introduce bdot to Double TensorAlgebra for broadcasting operations. 2022-08-03 18:10:44 +03:00
9456217935
Update multik algebra 2022-08-03 17:29:01 +03:00
Alexander Nozik
c5516e5581
Merge pull request #498 from mipt-npm/refactor/dubins
Refactor/dubins
2022-07-30 09:53:46 +03:00
0e9072710f
Kotlin 1.7.20-Beta 2022-07-29 15:58:02 +03:00
137ddb3ade
Code simplification for Dubins path 2022-07-29 14:12:44 +03:00
Alexander Nozik
99fee476bc
Merge pull request #469 from lounres/feature/polynomials
Feature: Polynomials and rational functions
2022-07-28 18:04:06 +03:00
Gleb Minaev
a2fb14a221 Merge remote-tracking branch 'origin/feature/polynomials' into feature/polynomials 2022-07-28 12:03:12 +03:00
Gleb Minaev
c2025ee1c9 Remove Polynomial interface, fix consequent platform clashes. Add invariance. 2022-07-27 14:36:20 +03:00
Alexander Nozik
b5406e460e
Merge branch 'dev' into feature/polynomials 2022-07-27 08:26:08 +03:00
323e8b6872
Code simplification for Dubins path 2022-07-26 09:19:04 +03:00
1e8a8cac7e
Fix readme 2022-07-24 12:01:02 +03:00
TatianaMy
ad30c68eba
Merge pull request #495 from ESchouten/trajectory
Trajectory: Dubins path
2022-07-24 11:29:24 +03:00
Gleb Minaev
0c6ad35c13 Simplify the version catalog usage. 2022-07-23 10:24:52 +03:00
Gleb Minaev
e1b8fcdbbf Two consecutive dots... 2022-07-20 19:10:35 +03:00
Gleb Minaev
fe4eb96dae Add docs. 2022-07-20 19:09:20 +03:00
Gleb Minaev
163a7c717a Fix description. 2022-07-20 08:28:47 +03:00
Gleb Minaev
9d4df5d8e0 Add and regenerate READMEs. Fix files' directory. 2022-07-20 08:22:41 +03:00
Erik Schouten
f2cbbeba20 Author details 2022-07-17 15:56:24 +02:00
Erik Schouten
429eefa3f7 Arc direction as computed property 2022-07-17 15:48:08 +02:00
Erik Schouten
86fce7ec68 Arc contains circle, circle direction is computed from poses, factory function can create Arc based on Vector points and provided direction 2022-07-17 15:47:05 +02:00
Erik Schouten
8faa312424 Dubins factory functions 2022-07-17 14:56:21 +02:00
Erik Schouten
3260c3d171 Pose2D facrtory function 2022-07-17 14:39:43 +02:00
Erik Schouten
7de157ce24 Re-introduce line/straight segment, rename components to start/end 2022-07-17 14:21:12 +02:00
Gleb Minaev
f48e4483cc Last cosmetic changes. 2022-07-16 22:21:13 +03:00
Gleb Minaev
2d86cf1cc7 Remove power overriding and algebraic stub. 2022-07-16 21:55:35 +03:00
Gleb Minaev
99c7174802 Turn Polynomial data class back. 2022-07-16 20:55:10 +03:00
Gleb Minaev
58d7015782 Remove utils modules. Revive suddenly lost tests. 2022-07-16 20:15:30 +03:00
Gleb Minaev
3a91cb2579 Draft another DSL for labeled polynomials. Add variance. 2022-07-16 18:46:40 +03:00
Gleb Minaev
db19df4329 Merge branch 'dev' into feature/polynomials 2022-07-16 17:23:39 +03:00
Gleb Minaev
a1a2c41846 Add a bit more utilities for maps and refactor polynomials' code. 2022-07-16 17:13:05 +03:00
3eef778f60
Add mandatory MutableBufferFactory to Algebra #477 2022-07-16 16:27:11 +03:00
Gleb Minaev
579511a5ee Add utilities for maps. Fix some tests. 2022-07-16 16:07:03 +03:00
68add4cb5f
Refactor test naming 2022-07-16 11:35:50 +03:00
b522e5919e
Merge remote-tracking branch 'origin/dev' into dev 2022-07-16 10:19:55 +03:00
Alexander Nozik
fc036215a5
Merge pull request #402 from mipt-npm/commandertvis/diff
Copy `DerivativeStructure` from Commons Math to multiplatform
2022-07-16 10:05:59 +03:00
Alexander Nozik
debff5357b
Merge pull request #494 from mipt-npm/altavir/diff
altavir/diff
2022-07-16 09:58:43 +03:00
Erik Schouten
4f88982734 Formatting 2022-07-15 22:13:50 +02:00
Erik Schouten
fa6d741869 Small improvement in test classes, theta function 2022-07-15 22:12:36 +02:00
Erik Schouten
ada1141738 Use Line distancTo function 2022-07-15 18:57:10 +02:00
Erik Schouten
cdb116fa20 Cleanup 2022-07-15 18:55:37 +02:00
Erik Schouten
32769d6906 Dubins path 2022-07-15 18:13:50 +02:00
18ae964e57
Name refactor 2022-07-15 17:35:13 +03:00
bfadf5b33d
Name refactor 2022-07-15 17:31:28 +03:00
846a6d2620
Grand derivative refactoring. Phase 3 2022-07-15 17:20:00 +03:00
f5fe53a9f2
Grand derivative refactoring. Phase 2 2022-07-15 16:20:28 +03:00
5846f42141
Grand derivative refactoring. Phase 1 2022-07-15 15:21:49 +03:00
Gleb Minaev
4ea29c82c5 Small fix of DSL1. 2022-07-13 12:05:53 +03:00
56f3c05907
Merge remote-tracking branch 'origin/dev' into altavir/diff 2022-07-13 10:13:47 +03:00
Gleb Minaev
87aeda84d9 Added MathJax to docs. 2022-07-12 23:10:38 +03:00
0eb9bd810c
Kotlin 1.7.10 2022-07-12 22:56:08 +03:00
Gleb Minaev
f7d159bc03 Made IntModulo implement ScaleOperations. 2022-07-12 02:05:29 +03:00
Gleb Minaev
5bc627f1d4 Rollback all breaking changes. The only breaking change now is value class. 2022-07-12 01:56:34 +03:00
Gleb Minaev
6ff79e28ac Fix names, references, etc. 2022-07-12 00:57:44 +03:00
Gleb Minaev
f726e6d0f1 Minimise appearance of new feature, leave only upgrades. 2022-07-11 23:32:15 +03:00
Gleb Minaev
51dd72e48f Finish move. 2022-07-11 22:39:13 +03:00
Gleb Minaev
1c719b9e70 Fix examples. 2022-07-11 17:52:46 +03:00
Gleb Minaev
d44a48bdb1 Moving to new modules. 2022-07-11 17:27:59 +03:00
Gleb Minaev
d3be07987c Simplify usages of LabeledPolynomial constructing fabrics. Fix bugs. Add tests for variable's interoperability. 2022-07-06 23:16:25 +03:00
Gleb Minaev
923c52737d Adapt NumberedPolynomial tests to LabeledPolynomial tests. 2022-07-06 17:13:50 +03:00
Gleb Minaev
5834fad938 Renamed constructing DSLs components. Fixed rejected NumberedPolynomial tests. 2022-07-06 00:37:46 +03:00
Gleb Minaev
45ed45bd13 Finish tests generation for numbered utilities. Also:
- Optimize a bit labeled and numbered differentiation.
- Fixed bugs in numbered anti-differentiation.
2022-07-05 03:41:52 +03:00
Gleb Minaev
e40977647d Added suppresses. 2022-07-05 03:35:56 +03:00
Gleb Minaev
e89e4e19d3 Return suppresses. 2022-07-04 03:54:28 +03:00
Gleb Minaev
39088ec36b Replaced assertFailsWith with assertFailsWithTypeAndMessage. 2022-07-04 02:36:46 +03:00
Gleb Minaev
102e83b478 Tests generation for numbered utilities in progress: finish substitutions. 2022-07-04 02:24:46 +03:00
Gleb Minaev
672a3c1552 Tests generation for numbered utilities in progress: finish map-wise substitutions. Also:
- Upgrade operations on Rational.
- Add new assertions.
- Changed a bit FIXME comments.
2022-07-03 15:47:12 +03:00
Gleb Minaev
f147636e9d Tests generation for numbered utilities in progress. 2022-07-01 14:46:05 +03:00
Gleb Minaev
c8b9951f46 Added for list utilities for rational functions. 2022-06-29 14:54:49 +03:00
Gleb Minaev
64b33aed18 Remove extra suppresses. 2022-06-29 14:53:12 +03:00
Gleb Minaev
da46ea923c Extended test for NumberedPolynomial 2022-06-28 15:07:09 +03:00
Gleb Minaev
043d292eca Added test. Fixed bug in NumberedPolynomial's DSL. 2022-06-27 17:14:03 +03:00
Gleb Minaev
0ef2258665 Removed extra suppresses. 2022-06-27 17:11:39 +03:00
Gleb Minaev
ed634013f6 Removed extra suppresses. 2022-06-27 17:07:33 +03:00
Gleb Minaev
cb7291ccb0 Little addition to polynomials design note. 2022-06-26 12:58:30 +03:00
Gleb Minaev
630d16bbee Added design notes. Also:
- Changed `xxxPolynomialSpace()` and `xxxPolynomialSpace()` functions to `xxxPolynomialSpace` value properties.
- Changed inconsistency of names `XxxRationalFunctionalSpaceYyy` and `XxxRationalFunctionSpaceYyy` in favor of second one.
2022-06-26 12:16:51 +03:00
Gleb Minaev
fc2455fe34 Merge branch 'dev' into feature/polynomials 2022-06-25 23:29:34 +03:00
Gleb Minaev
3e917baaaf Added examples for polynomials. Also:
- Fixed bug in differentiation of NumberedPolynomials.
- Fixed bug in addition and subtraction of LabeledPolynomials.
- Added references to NumberedPolynomialWithoutCheck and LabeledPolynomialWithoutCheck.
- Made NumberedRationalFunction and LabeledRationalFunction classes data. Made their constructor public.
2022-06-25 21:23:32 +03:00
Gleb Minaev
403ff93f4a Moved optimizations to branch refactor/polynomials 2022-06-25 16:01:18 +03:00
Gleb Minaev
9fc99a4c72 Removed extra copyright comment. 2022-06-25 15:45:10 +03:00
Gleb Minaev
6c8fa29304 Merge branch 'feature/polynomials-sift' into feature/polynomials 2022-06-18 01:26:33 +03:00
Gleb Minaev
d416f8cf34 Merge branch 'dev' into feature/polynomials 2022-06-18 01:25:46 +03:00
Gleb Minaev
680d23ddcb Last sift. Cleaned up labeled structures. 2022-06-18 01:25:14 +03:00
Gleb Minaev
1ea336b70e Added some test of NumberedPolynomial utilities. 2022-06-17 22:07:54 +03:00
Gleb Minaev
b5a94923b5 Fixed problems with JVM names. Exposed internal NumberedPolynomial constructor with opt-in condition. Added and upgraded tests. Fixed small bugs (mistakes). Upgraded arithmetic operations a bit. 2022-06-17 01:53:40 +03:00
a1267d84ac
Fix quaternion rotation tests 2022-06-14 20:58:13 +03:00
Gleb Minaev
eadd521e35 Merge branch 'dev' into feature/polynomials-sift 2022-06-14 19:46:50 +03:00
b5031121ce
up build tools 2022-06-14 19:31:13 +03:00
Gleb Minaev
d0134bdbe9 Sift 4. Cleaned up "numbered" case. Tests are in progress. 2022-06-14 19:15:36 +03:00
a810790d8d Merge SCI-MR-158: Fix name clash in strict mode; replace eval with new Function 2022-06-14 15:59:58 +00:00
Iaroslav Postovalov
b09127f090
Fix name clash in strict mode; replace eval with new Function 2022-06-14 22:52:47 +07:00
Alexander Nozik
f0053daf77
Merge pull request #489 from lounres/docs-latex-update
Inlined LaTeX formula
2022-06-14 18:09:29 +03:00
85a1e8b33f
New common test infrastructure 2022-06-14 16:27:32 +03:00
Gleb Minaev
58e0715714 Removed duplicates of copyright comments. 2022-06-13 12:15:14 +03:00
Gleb Minaev
5928adfe45 Fixed merging accidents. 2022-06-13 12:08:58 +03:00
Gleb Minaev
4e08d6d877 Merge branch 'feature/polynomials-listPolynomials-applications' into feature/polynomials-sift 2022-06-13 12:04:57 +03:00
1fd8dfd7b8
refactor Quaternions 2022-06-13 11:17:41 +03:00
Gleb Minaev
37ad48e820 Sift # 3. Filtered last sift and usages of [ListPolynomial]s. 2022-06-13 02:06:15 +03:00
Gleb Minaev
dbb48a2a9f Added docstrings to ListPolynomial and ListRationalFunction fabric functions. 2022-06-13 01:41:04 +03:00
Gleb Minaev
ab9bba2202 Put suddenly disappeared files back. 2022-06-13 00:16:22 +03:00
Gleb Minaev
b50d8dcd23 Merge branch 'feature/polynomials-ListPolynomials' into feature/polynomials-sift
# Conflicts:
#	kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/ListPolynomial.kt
#	kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/ListRationalFunction.kt
#	kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/Polynomial.kt
#	kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/RationalFunction.kt
#	kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/listUtilOptimized.kt
#	kmath-functions/src/commonTest/kotlin/space/kscience/kmath/functions/ListPolynomialTest.kt
#	kmath-functions/src/commonTest/kotlin/space/kscience/kmath/functions/ListPolynomialUtilTest.kt
#	kmath-functions/src/commonTest/kotlin/space/kscience/kmath/test/misc/IntModulo.kt
#	kmath-functions/src/commonTest/kotlin/space/kscience/kmath/test/misc/misc.kt
2022-06-12 23:54:30 +03:00
Gleb Minaev
94fd24d852 Fixed some tests and docstrings. Removed zero and one overridings because overrided fields are already lazily initialized. 2022-06-12 23:49:44 +03:00
Gleb Minaev
e710013800 Fixed tests. 2022-06-12 23:02:26 +03:00
Gleb Minaev
3a6aa14320 Cleaned up ListPolynomials and ListRationalFunctions:
- Added/updated docs.
- Fully (but in a simple way) implemented invocation, substitution, functional representation, derivatives and antiderivatives. Optimized reimplementation is in progress.
- Upgraded `PolynomialSpaceOfFractions` by adding a bit of laziness.
- Other little things...
2022-06-12 22:52:08 +03:00
fabad733f4
Fix binaryen module creation 2022-06-12 15:30:10 +03:00
e1276b684f
Update better-parse 2022-06-12 15:19:59 +03:00
569e01fce1
Migration to kotlin 1.7 2022-06-12 15:16:40 +03:00
Gleb Minaev
17703e407d Applied changes from previous sift. 2022-06-12 00:24:23 +03:00
Gleb Minaev
a6b86eeee1 Cleaned out useless code. 2022-06-11 19:31:01 +03:00
Gleb Minaev
03b92de6e0 Sifted ListPolynomial's basics. 2022-06-11 19:29:14 +03:00
Gleb Minaev
8af183a969 Fixed typos. Added docstrings. Added variable convertional methods. 2022-06-11 19:22:57 +03:00
Gleb Minaev
a2b02ef09e Sifted rest usage of non-basic polynomial things. 2022-06-11 16:15:59 +03:00
Gleb Minaev
9b51062bf7 Sift. 2022-06-11 16:09:24 +03:00
Gleb Minaev
89cdbf4d71 Changed names of algebraic stub. Added FIXMEs about KT-31420. Changed JVM/JS names style. 2022-06-11 15:58:25 +03:00
Gleb Minaev
b92ef23f5d
Some fixes 2022-06-11 00:06:45 +03:00
Gleb Minaev
de9f3cc8df Inlined LaTeX formula. Now GitHub supports MathJax! 2022-06-10 23:37:50 +03:00
c28be83226
LazyStructire::deferred -> async 2022-06-08 09:00:37 +03:00
Gleb Minaev
af2e437a48 Merge branch 'master' into feature/polynomials
# Conflicts:
#	README.md
#	kmath-ast/README.md
#	kmath-complex/README.md
#	kmath-core/README.md
#	kmath-ejml/README.md
#	kmath-for-real/README.md
#	kmath-functions/README.md
#	kmath-jafama/README.md
#	kmath-kotlingrad/README.md
#	kmath-nd4j/README.md
#	kmath-tensors/README.md
2022-06-03 21:58:37 +03:00
5a36c3e03c
Remove metaspace memory allocation key 2022-04-13 11:20:11 +03:00
Alexander Nozik
2144c6382c
Update pages.yml 2022-04-12 12:02:11 +03:00
Alexander Nozik
7e4ece8dbc
Update publish.yml 2022-04-12 11:56:12 +03:00
Alexander Nozik
b698f2d613
Update pages.yml 2022-04-12 11:10:14 +03:00
Alexander Nozik
19cd74013b
Update pages.yml 2022-04-12 11:06:18 +03:00
Alexander Nozik
5bb895a653
Merge pull request #480 from mipt-npm/dev
0.3.0
2022-04-12 10:59:28 +03:00
358d750226
Add missing @CommanderTvis contributions to changelog 2022-04-12 09:49:35 +03:00
d862a0a896
0.3.0 release 2022-04-11 20:08:13 +03:00
74e6bc65a3
0.3.0 release 2022-04-11 20:07:40 +03:00
916bc69e4b
Revert changes in tensor algebra to remove name conflicts 2022-04-11 17:32:16 +03:00
7e4d223044
Fixed missing TF basic operations 2022-04-11 14:56:48 +03:00
b509dc917d
ValueAndErrorField 2022-04-10 23:00:55 +03:00
Iaroslav Postovalov
ff58985d78
Merge pull request #476 from mipt-npm/refactor/histogram
Complete refactor of histograms API
2022-04-11 00:59:04 +07:00
1295a407c3
Refactor tree histogram 2022-04-10 15:29:46 +03:00
6247e79884
Refactor multivariate histograms 2022-04-10 13:41:41 +03:00
27a252b637
Accept changes, Update documentation 2022-04-10 11:31:52 +03:00
229c36b661
Accept changes 2022-04-10 10:32:36 +03:00
Alexander Nozik
40b088149b
Update kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/IndexedHistogramGroup.kt
Co-authored-by: Iaroslav Postovalov <38042667+CommanderTvis@users.noreply.github.com>
2022-04-10 10:29:59 +03:00
Alexander Nozik
86d89f89f9
Update kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/IndexedHistogramGroup.kt
Co-authored-by: Iaroslav Postovalov <38042667+CommanderTvis@users.noreply.github.com>
2022-04-10 10:29:44 +03:00
eba3a2526e
[final] Generalize UniformHistogram1D 2022-04-10 09:48:55 +03:00
3de8976ea5
Merge remote-tracking branch 'origin/dev' into refactor/histogram
# Conflicts:
#	buildSrc/gradle.properties
#	gradle/wrapper/gradle-wrapper.properties
2022-04-10 09:41:38 +03:00
Alexander Nozik
c24cf90262
Merge pull request #471 from mipt-npm/commandertvis/gradle
Upgrade gradle tools
2022-04-10 09:40:16 +03:00
3a2faa7da4
Generalize UniformHistogram1D 2022-04-09 10:18:18 +03:00
a2c0bc8a10
Another histogram refactor 2022-04-08 19:41:41 +03:00
73f72f12bc
[WIP] Another histogram refactor 2022-04-05 23:23:29 +03:00
Gleb Minaev
7f7b550674 Simplified polynomial builders. 2022-04-03 11:44:42 +03:00
Iaroslav Postovalov
5988b9ad30
Merge branch 'master' into commandertvis/gradle 2022-04-01 21:56:53 +07:00
Iaroslav Postovalov
97a320c9ef
Use gradle-build-action 2022-04-01 14:02:03 +07:00
Iaroslav Postovalov
bae465fe86
Update GitHub actions 2022-04-01 03:06:07 +07:00
Iaroslav Postovalov
3277a99ed3
Never use GitHub Packages to publish project with 2022-04-01 02:58:12 +07:00
Iaroslav Postovalov
38fd3e24c8
Use correct class name for kotlin JVM compilation 2022-04-01 02:37:14 +07:00
Iaroslav Postovalov
13fb49e48c
Rename version catalog 2022-04-01 02:27:50 +07:00
Iaroslav Postovalov
92cffd78d9
Upgrade gradle tools 2022-04-01 02:23:34 +07:00
Gleb Minaev
b3087c245f Fixed tests. 2022-03-25 17:46:13 +03:00
Gleb Minaev
f7286d33d2 Moved constructors to separate files. Replaced some TODOs with FIXMEs. 2022-03-25 17:18:56 +03:00
Gleb Minaev
7e328a5dbf Enhanced DSL constructor a bit. 2022-03-25 00:59:48 +03:00
Gleb Minaev
060f0ee35d Removed comparability feature. 2022-03-25 00:57:32 +03:00
ce82d2d076 Histogram API refactor 2022-03-23 15:51:08 +03:00
3a3a5bd77f Histogram API refactor 2022-03-23 14:07:24 +03:00
29369cd6d7
[WIP] Another histogram refactor 2022-03-22 22:17:20 +03:00
Gleb Minaev
420bf05b22 Fixed annoying JVM clashes 😑 2022-03-22 19:42:59 +03:00
Gleb Minaev
0a5122a974 Prototyped DSL-like constructor for NumberedPolynomial. 2022-03-22 19:40:55 +03:00
Gleb Minaev
d75a41482d Added fabrics for LabeledPolynomial and NumberedPolynomial. 2022-03-22 17:09:33 +03:00
Gleb Minaev
5b8d6b601e Added degreeBy to Numbered.... 2022-03-22 15:37:19 +03:00
Gleb Minaev
b44c99c265 Added multivariate abstractions. 2022-03-22 15:28:34 +03:00
Gleb Minaev
39ce855075 Added constructors for RFs' spaces 2022-03-22 14:25:09 +03:00
Gleb Minaev
2f9e504357 Added division to RFs' Spaces. Added conversion to polynomial and RFs' spaces. Added requirements for RFs' denominators' changes for case of non-integral domain. Added requirements for non-zero divisor to RFs' divisions. 2022-03-22 13:58:29 +03:00
Gleb Minaev
09868f090b Enhanced tests of Double substitution. 2022-03-22 02:39:43 +03:00
Gleb Minaev
98b9a70893 Enhanced tests of Double substitution. 2022-03-22 02:37:26 +03:00
Gleb Minaev
c6d1068df4 Renamed Polynomial, etc. to ListPolynomial, etc. and AbstractPolynomial to Polynomial.
As it was advised by @CommanderTvis.
2022-03-21 23:47:10 +03:00
Gleb Minaev
51b0d232b5 Renamed AbstractPolynomialFractionsSpace to PolynomialSpaceOfFractions 2022-03-21 23:21:55 +03:00
Gleb Minaev
83d57c7295 Added RFs' interface to remove another boilerplate. Fixed bug in RFs' equalsTo. 2022-03-21 21:22:25 +03:00
Gleb Minaev
88e0dcf413 Added usage of more correct exceptions. 2022-03-21 18:26:09 +03:00
Gleb Minaev
25ec59b985 Finished with tests for Polynomial. 2022-03-20 23:22:39 +03:00
Gleb Minaev
fbc21101bb Added test. Fixed isOne and isMinusOne for Polynomial. 2022-03-20 06:26:52 +03:00
Gleb Minaev
5d4514a742 More test tools! More tests!! More fixes of stupid bugs!!! 😭 2022-03-19 19:35:41 +03:00
Gleb Minaev
90a7c4d901 Simplified use of Rational (current BigInt are hard to use and actually useless). Added tests, fixed bug. 2022-03-19 18:08:43 +03:00
Gleb Minaev
a965f5683f Added some tests and some utilities for tests. Fixed bug in utility of PolynomialSpace. 2022-03-19 16:54:30 +03:00
39640498fc
Another histogram refactor 2022-03-19 09:20:32 +03:00
Gleb Minaev
85cd3b4de6 Added some test. Fixed bug in algebraicStub.kt 2022-03-18 20:39:01 +03:00
Gleb Minaev
cdc85291bc Fixed bug in implementations of polynomial operations 2022-03-18 20:04:21 +03:00
Gleb Minaev
ed2f14b68e Optimised existing substitution function. Prototyped substitution for RFs. 2022-03-18 01:47:03 +03:00
Gleb Minaev
86553e9f35 Added utilities. Rewrote polynomial-in-polynomial substitution 2022-03-17 16:28:41 +03:00
Gleb Minaev
d63c4acf10 Added space and scope fabrics for RFs 2022-03-17 16:27:02 +03:00
Gleb Minaev
ffd3ae7684 Optimized allocation during coefficients generation in Polynomial 2022-03-17 16:02:41 +03:00
Gleb Minaev
a8a95c9df7 Fixed typo 2022-03-17 02:15:48 +03:00
Gleb Minaev
e5186d469a Fixed issue with confusing countOfVariables in Numbered... 2022-03-17 02:12:40 +03:00
Gleb Minaev
2082175af5 Fixed typos. 2022-03-16 23:31:07 +03:00
Gleb Minaev
75fd920735 Deleted suddenly missed region marks and unused error classes 2022-03-16 23:22:51 +03:00
Gleb Minaev
3c9d8a4eee Deleted all region marks 2022-03-16 22:44:55 +03:00
Gleb Minaev
24944cdb16 Added support of power function to abstract structures.
Implemented exponentiation by squaring as default implementation of `power`. Updated docs in algebraicStub.kt and updated realisations in it.
2022-03-16 15:19:27 +03:00
Gleb Minaev
9aa131a9c6 Replaced Variable in Labeled... by Symbol and deleted it 2022-03-16 01:06:39 +03:00
Gleb Minaev
16cf1bc65e Implemented all derivative-like functions 2022-03-16 00:47:07 +03:00
Gleb Minaev
bb5e638b31 Added polynomial spaces and scopes fabrics 2022-03-15 20:38:27 +03:00
Gleb Minaev
1f9d8d34f5 Tried to add constructors and/or fabrics for polynomials 2022-03-15 20:18:39 +03:00
Gleb Minaev
91c9ea61da Added derivative-like functions to Polynomial 2022-03-15 18:10:11 +03:00
Gleb Minaev
1754ae0695 Added some docs 2022-03-15 16:43:22 +03:00
Gleb Minaev
79736a0a9b Forgot to remove unnecessary tailrec 2022-03-15 15:36:10 +03:00
Gleb Minaev
f86529d659 Optimized optimizedMultiply and optimizedAddMultiplied for cases of negative value of other and multiplier 2022-03-15 15:35:17 +03:00
Gleb Minaev
ebd7f799ad Attempts to implement derivatives and antiderivatives 2022-03-15 00:47:23 +03:00
Gleb Minaev
31ccf744c5 Deleted useless annotations JvmName, JsName and Suppress 2022-03-14 23:33:00 +03:00
Gleb Minaev
fb01d85197 Removed extra JSName annotations. Now everything builds 2022-03-14 22:23:50 +03:00
Gleb Minaev
44febbdd73 Processed labeledRationalFunctionUtil.kt 2022-03-14 20:19:42 +03:00
Gleb Minaev
dd820da765 1. Prototyped rest 2 algebraic structures of rational functions
2. Added `constantZero` and `constantOne` to abstract spaces and applied them instead of `ring.zero` and `ring.one`
3. Moved logic of `R.isZero` and 5 others to `AbstractRationalFunctionalSpace`
4. Deleted forgotten overridden functions of constants
5. Added KMath contributors' copyright notes
6. Added TODO 😄 The `NumberedPolynomial`'s `countOfVariables` is a confusing
2022-03-14 19:59:53 +03:00
Gleb Minaev
07f4b83722 Fixed forgotten TODOs 2022-03-14 14:18:15 +03:00
Gleb Minaev
de53d032af 1. Prototyped Rational Functions
2. Added abstract interfaces for removing boilerplates
3. Changed or added default values in interfaces
4. Renamed non-operator `equals` to `equalsTo`, and made it infix
2022-03-14 14:14:24 +03:00
Gleb Minaev
033edd3feb Removed kotlin-js-store 2022-03-13 03:55:51 +03:00
Gleb Minaev
59e65afc63 Merge remote-tracking branch 'origin/feature/polynomials' into feature/polynomials
# Conflicts:
#	kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/Interpolator.kt
#	kotlin-js-store/yarn.lock
2022-03-13 03:53:29 +03:00
Gleb Minaev
93de1d5311 Added support for all polynomials. But standard utilities still are not fully implemented. 2022-03-13 03:44:16 +03:00
Gleb Minaev
571c6342dd Regenerated READMEs 2022-03-13 03:44:16 +03:00
Gleb Minaev
cab5958107 Added abstract rational functions 2022-03-13 03:44:16 +03:00
Gleb Minaev
191dd02e47 Restructured Polynomial 2022-03-13 03:44:15 +03:00
Gleb Minaev
843d63c76a Added support for all polynomials. But standard utilities still are not fully implemented. 2022-03-13 03:27:00 +03:00
Gleb Minaev
ffea8cc223 Regenerated READMEs 2022-03-13 03:25:25 +03:00
Gleb Minaev
ab9dcd83b9 Added abstract rational functions 2022-03-10 01:44:14 +03:00
Alexander Nozik
92ba439f2a
Merge pull request #468 from mipt-npm/dev
Build fixes
2022-03-08 23:17:17 +03:00
0b2e8ff25e
Build fixes 2022-03-08 23:15:48 +03:00
Alexander Nozik
df075718db
Merge pull request #466 from mipt-npm/dev
Dev
2022-03-07 22:07:41 +03:00
Iaroslav Postovalov
8518f333e3 Delete yarn.lock 2022-03-08 01:31:31 +07:00
4575ab2b79
Update interpolation API to agree with other conventions. 2022-03-07 10:39:59 +03:00
Gleb Minaev
2483c56f1c Restructured Polynomial 2022-03-03 20:45:35 +03:00
Alexander Nozik
c80f70fe0f
Merge pull request #461 from ivandev0/kylchik/jacobi
Jacobi eigenvalue algorithm
2022-02-20 10:18:06 +03:00
Ivan Kylchik
a621dd7c5b Drop duplicate test from DorBenchmark 2022-02-20 02:55:37 +03:00
Ivan Kylchik
dda6602ed4 Replace complex access to tensor with faster access to buffer in Jacobi algorithm 2022-02-20 02:51:35 +03:00
Ivan Kylchik
b13765ec19 Implement much faster Jacobi algorithm 2022-02-20 02:51:35 +03:00
Ivan Kylchik
7aff774bc1 Improve Jacobi algorithm readability by extracting some logic into helper fun 2022-02-20 02:51:35 +03:00
Ivan Kylchik
7a72a0b979 Implement Jacobi algorithm to find eigenvalues 2022-02-20 02:51:35 +03:00
ac3adfa644
Fix tf dot 2022-02-17 22:46:17 +03:00
Ivan Kylchik
a78e361b17 Implement much faster dot product algorithm for tensors 2022-02-18 00:13:23 +07:00
Alexander Nozik
8974164ec0
Merge pull request #459 from mipt-npm/dev
v0.3.0-dev-18
2022-02-13 17:50:33 +03:00
408443989c
Up version 2022-02-13 17:48:04 +03:00
Iaroslav Postovalov
745a7ad66e Add complete constant folding in kmath-ast by introducing TypedMst, some minor changes 2022-02-11 20:46:30 +07:00
Iaroslav Postovalov
7b1bdc21a4 Copy DerivativeStructure to multiplatform 2022-02-09 22:08:37 +07:00
Alexander Nozik
ef747f642f
Merge pull request #458 from mipt-npm/commandertvis/no-evaluate
Remove Algebra.evaluate(MST) by inlining it into interpret
2022-02-09 18:04:48 +03:00
Iaroslav Postovalov
e094f6e8ee Remove Algebra.evaluate(MST) by inlining in into interpret 2022-02-08 11:43:50 +07:00
53ab8334dd Merge SCI-MR-149: Fix theta 2022-02-02 07:00:26 +00:00
Iaroslav Postovalov
d35516b9af Fix theta 2022-02-02 10:00:45 +07:00
7bb66f6a00
Add TensorFlow prototype 2022-01-29 15:02:46 +03:00
41fc6b4dd9
Merge branch 'feature/tensorflow' into dev 2022-01-28 09:46:55 +03:00
Alexander Nozik
2e13d518f6
Merge pull request #451 from mipt-npm/commandertvis/js-benchmark
Make JS benchmarks of expressions
2022-01-26 17:44:00 +03:00
Iaroslav Postovalov
8607639876 Change units 2022-01-26 20:33:44 +07:00
Iaroslav Postovalov
d10815020d JS benchmarking 2022-01-26 16:46:38 +07:00
91d93b3bb2
restore metaspace 2022-01-04 19:45:24 +03:00
dd8a4796f6
Update gradle plugin and build consistency 2022-01-04 13:15:50 +03:00
479d106165
install Kover plugin 2021-12-30 18:50:47 +03:00
Alexander Nozik
4b4c878e21
Merge pull request #447 from mipt-npm/commandertvis/fixbuild
Do numeric type conversion in JS MST compilers
2021-12-30 16:54:27 +03:00
2f96d619fc
Fix AST JS test 2021-12-29 20:08:26 +03:00
Alexander Nozik
4badc3e044
Merge pull request #448 from breandan/master
Update Kotlin∇ and remove old Maven repositories
2021-12-25 21:20:42 +03:00
breandan
6255a46004 update Kotlin∇ and remove old maven repositories 2021-12-25 12:05:42 -05:00
e11df4fdd5
Add inline to histogram builders 2021-12-18 21:57:06 +03:00
Iaroslav Postovalov
a9779fe38b Do numeric type conversion in JS MST compilers 2021-12-07 12:00:31 +07:00
Alexander Nozik
f6fa288011
Merge pull request #445 from mipt-npm/commandertvis/gram
Rewrite the `ArithmeticsEvaluator.number` rule to handle well both floating-point numbers and integers
2021-12-02 09:40:55 +03:00
Alexander Nozik
a3556ecdb3
Merge pull request #444 from mipt-npm/commandertvis/specialized
Completely specialized expression types for `Int`, `Long`, `Double` and compilation of MST to it
2021-12-02 09:40:26 +03:00
Iaroslav Postovalov
cf5f886226 Rewrite the ArithmeticsEvaluator.number rule to handle well both floating-point numbers and integers 2021-11-29 13:50:06 +07:00
Iaroslav Postovalov
5ba7d74bd2 Completely specialized expression types for Int, Long, Double and compilation of MST to it 2021-11-28 20:56:01 +07:00
Alexander Nozik
c6a4721d64
Merge pull request #443 from mipt-npm/commandertvis/update
Update gradle-tools, make Kotlin 1.6.0 migrations
2021-11-24 11:58:34 +03:00
Iaroslav Postovalov
d2e3110480 Update gradle-tools, do Kotlin 1.6.0 migrations 2021-11-24 15:32:06 +07:00
24799a691f Add inc/dec to counters 2021-11-23 10:32:51 +03:00
Alexander Nozik
4691caaa7f
Merge pull request #435 from alexismanin/feat/permsort
Feat/permsort
2021-11-21 20:21:18 +03:00
Alexis Manin
06a6a99ef0 feat(Core): add new flavors of permSort: allow user to specify a comparator (sort with) or a custom field to use in buffer values (sort by). 2021-11-18 17:44:53 +01:00
Alexis Manin
0f7a25762e feat(Core): add a permutation sorting prototype for buffers
This is a Buffer extension function to create a list of permuted indices that represent the sequence of naturally sorted buffer elements
2021-11-17 13:19:40 +01:00
Iaroslav Postovalov
e38b2e1c53 Only dump ASM classes during tests if according property is passed to Gradle 2021-11-17 19:03:20 +07:00
Alexander Nozik
a6922ab9d8
Merge pull request #440 from mipt-npm/commandertvis/license
Revert license removal and update copyright
2021-11-16 17:38:29 +03:00
Iaroslav Postovalov
7ceb0b69b8 Revert license removal and update copyright 2021-11-16 18:14:34 +07:00
Alexander Nozik
e25827eb14
Merge pull request #437 from mipt-npm/commandertvis/double-specialized
Provide specializations of `AsmBuilder` for `Double`, `Long`, `Int`
2021-11-16 11:41:53 +03:00
Alexander Nozik
b1911ebe2d
Merge pull request #438 from mipt-npm/commandertvis/411
Relax type requirements in algebraExtensions.kt from `Ring` to `Group`
2021-11-16 10:52:41 +03:00
Iaroslav Postovalov
70ac232c15 Relax type requirements in algebraExtensions.kt from Ring to Group 2021-11-16 14:27:20 +07:00
Iaroslav Postovalov
7b50400de5 Provide specializations of AsmBuilder for Double, Long, Int 2021-11-16 14:03:12 +07:00
Iaroslav Postovalov
f231d722c6 Multiple performance improvements related to ASM
1. Argument values are cached in locals
2. Optimized Expression.invoke function
3. lambda=indy is used in kmath-core
2021-11-15 23:29:15 +07:00
4e16cf1c98 Merge remote-tracking branch 'origin/feature/tensorflow' into feature/tensorflow 2021-11-10 20:04:45 +03:00
6c2abdaab0 First tensorflow test. 2021-11-10 20:04:29 +03:00
c583320051 Merge branch 'dev' into feature/tensorflow
# Conflicts:
#	kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensorAlgebra.kt
2021-11-10 11:52:11 +03:00
9a1f8a2266 remove unnecessary toInt 2021-11-10 11:51:20 +03:00
fa9ff4c978 Minor refactoring 2021-11-09 17:56:53 +03:00
d62bc66d4a Refactoring 2021-11-09 13:42:22 +03:00
f6b576071d Add non-boxing BufferView access 2021-11-09 12:25:17 +03:00
1315a8cd34 views cleanup 2021-11-08 19:57:22 +03:00
a1351aa942 Buffer views 2021-11-08 17:50:49 +03:00
bf504ae6c5 Basic series 2021-11-05 16:58:13 +03:00
0e1e97a3ff Multik integration finished (for now) 2021-11-04 10:58:27 +03:00
726864ed0e Refactoring of power 2021-11-03 12:55:29 +03:00
Alexander Nozik
bd0895b268
Merge pull request #426 from grinisrit/dev
fix argmax
2021-11-01 21:48:36 +03:00
Roland Grinis
62e7073ed2 example fixed 2021-11-01 18:03:46 +00:00
Roland Grinis
a994b8a50c fix argmax 2021-11-01 17:55:10 +00:00
b65197f577 revert parts of tensor api to tensors 2021-11-01 19:45:02 +03:00
Alexander Nozik
eb1bc5acc4
Merge pull request #424 from grinisrit/feature/tensorflow
dot fixed for tensorflow
2021-10-29 15:20:20 +03:00
Roland Grinis
db06d10cc2 dot fixed for tensorflow 2021-10-28 19:25:10 +01:00
46e7da9ae0 Tensor algebra generified 2021-10-28 11:18:16 +03:00
0f5f59e175 Merge branch 'dev' into feature/tensorflow 2021-10-28 10:58:53 +03:00
4db7398a28 Tensor algebra generified 2021-10-28 10:58:22 +03:00
64629561af [WIP] TensorFlow refactoring 2021-10-28 10:52:40 +03:00
7bdc54c818 Merge branch 'dev' into feature/tensorflow
# Conflicts:
#	kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensorAlgebra.kt
2021-10-28 09:55:43 +03:00
Alexander Nozik
f8d21ad072
Merge pull request #422 from mipt-npm/refactor/tensor-univeral
Refactor/tensor univeral
2021-10-28 09:51:26 +03:00
29a90efca5 Tensor algebra generified 2021-10-27 14:48:36 +03:00
4635cd3fb3 Refactor TensorAlgebra to take StructureND and inherit AlgebraND 2021-10-26 16:08:02 +03:00
7e59ec5804 Refactor TensorAlgebra to take StructureND and inherit AlgebraND 2021-10-26 09:16:24 +03:00
cc114041c4 Initial implementation of TensorFlow connector 2021-10-24 18:33:39 +03:00
47aeb36979 fix NDArray cast 2021-10-20 17:04:00 +03:00
cfd3f3b7e1 fix NDArray cast 2021-10-20 16:35:52 +03:00
69e6849a12 Name refactoring for tensors 2021-10-20 16:11:36 +03:00
6c4741ede6 [WIP] TensorFlow 2021-10-20 16:06:45 +03:00
40c02f4bd7 Add multik dot for tensors 2021-10-19 10:50:13 +03:00
Alexander Nozik
42259e3eb9
Merge pull request #420 from mipt-npm/dev
0.3.0-dev-17
2021-10-18 13:41:56 +03:00
98bbc8349c 0.3.0-dev-17 2021-10-18 13:18:10 +03:00
Alexander Nozik
ae8655d6af
Merge pull request #419 from mipt-npm/feature/multik
Feature/multik
2021-10-18 13:06:34 +03:00
Alexander Nozik
bfc6cbe5d8
Update multik.kt 2021-10-18 13:04:36 +03:00
dccc92bf2f Switch to multik-default 2021-10-18 12:52:24 +03:00
a81ab474f7 Add multik tensor factories and benchmarks 2021-10-18 11:35:09 +03:00
827f115a92 Multik wrapper 2021-10-17 21:12:14 +03:00
05ae21580b Merge branch 'dev' into feature/multik 2021-10-17 16:44:26 +03:00
9b9fe07044 Specialized operations for ND algebra 2021-10-17 16:42:46 +03:00
6de43ee4ba update multik module 2021-10-17 13:52:40 +03:00
da34d0f71b Merge branch 'dev' into feature/multik 2021-10-17 13:16:39 +03:00
4513b06e87 Shapeless ND and Buffer algebras 2021-10-17 13:09:21 +03:00
688382eed6 Shapeless ND and Buffer algebras 2021-10-17 12:42:35 +03:00
d0354da80a Shapeless ND and Buffer algebras 2021-10-17 11:12:35 +03:00
0ac5363acf Multik wrapper prototype 2021-10-16 11:10:34 +03:00
Alexander Nozik
6a9f4d4626
Merge pull request #417 from mipt-npm/dev
0.3.0-dev-15
2021-10-13 14:56:53 +03:00
8d2770c275 Build tools to 0.10.5 2021-10-13 09:06:54 +03:00
09a9df5213 Add complex power 2021-10-09 20:19:36 +03:00
30e3e80397 Add nd add benchmarks 2021-10-06 12:25:32 +03:00
d9f36365d9 Fix Mean bug 2021-10-04 22:31:06 +03:00
663aaa8b4c Merge remote-tracking branch 'origin/dev' into dev 2021-10-04 12:47:42 +03:00
fd8a61c852 Fix Mean bug 2021-10-04 12:40:30 +03:00
abae29bbed DoubleBuffer algebra refactoring 2021-10-02 18:54:45 +03:00
85aefb5380 Completely remove AlgebraElements.kt 2021-10-02 16:14:38 +03:00
0f634688cc API cleanup 2021-10-02 15:56:57 +03:00
01bbb4bb13 API cleanup 2021-10-02 09:55:52 +03:00
Alexander Nozik
4a066ea364
Merge pull request #415 from V3lop5/master
Added gradle wrapper validation
2021-09-27 18:08:48 +03:00
Paule
a68884142f Added gradle wrapper validation
See https://github.com/marketplace/actions/gradle-wrapper-validation
2021-09-27 12:36:48 +02:00
64781a6785 Move Minuit tmp classes to optimization 2021-09-23 21:44:18 +03:00
974d73e25c Adjust benchmarks. 2021-09-22 22:09:46 +03:00
89eebbecb7 Fix EJML inversion issue 2021-09-21 21:24:27 +03:00
9fcc1b3af2 Split Buffer.kt for better readability 2021-09-19 21:17:26 +03:00
546d56aeee Refactor buffer builders to suit new discoverability pattern 2021-09-19 21:13:07 +03:00
49ec5d1554 Refactor ND builders to suit new discoverability pattern 2021-09-19 20:48:36 +03:00
Alexander Nozik
6dc9e8847a
Merge pull request #404 from mipt-npm/feature/advanced-optimization
Feature/advanced optimization
2021-08-29 11:44:09 +03:00
Alexander Nozik
55ea3658b9
Update CHANGELOG.md
Co-authored-by: Iaroslav Postovalov <38042667+CommanderTvis@users.noreply.github.com>
2021-08-27 18:16:24 +03:00
Alexander Nozik
8581b32448
Apply suggestions from code review
Co-authored-by: Iaroslav Postovalov <38042667+CommanderTvis@users.noreply.github.com>
2021-08-27 18:13:54 +03:00
Alexander Nozik
b0bbdc122e
Merge pull request #412 from mipt-npm/commandertvis/asm-debug
Add debug property for dumping classes generated with ASM
2021-08-21 18:07:27 +03:00
Iaroslav Postovalov
7e0820d861 Add debug property for dumping classes generated with ASM 2021-08-21 19:58:06 +07:00
8d33d6beab Fixed QOW optimization 2021-08-16 16:40:56 +03:00
dfd6e0a949 Merge remote-tracking branch 'origin/dev' into feature/advanced-optimization
# Conflicts:
#	kmath-commons/src/main/kotlin/space/kscience/kmath/commons/optimization/CMOptimization.kt
#	kmath-commons/src/main/kotlin/space/kscience/kmath/commons/optimization/cmFit.kt
#	kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/_generated.kt
#	kmath-stat/src/commonMain/kotlin/space/kscience/kmath/optimization/FunctionOptimization.kt
#	kmath-stat/src/commonMain/kotlin/space/kscience/kmath/optimization/NoDerivFunctionOptimization.kt
#	kmath-stat/src/commonMain/kotlin/space/kscience/kmath/optimization/Optimization.kt
#	kmath-stat/src/commonMain/kotlin/space/kscience/kmath/optimization/XYFit.kt
2021-08-16 09:56:00 +03:00
aaa298616d QOW is working more or less 2021-08-16 09:55:03 +03:00
9b8da4cdcc Fix JS bug with null cast 2021-08-12 20:28:45 +03:00
a020d1545c merge dev 2021-08-06 12:23:24 +03:00
3ba12f4999 Generic Buffer Algebra 2021-07-09 14:11:26 +03:00
95c0b2d3f0 [WIP] optimization with QOW 2021-06-08 14:27:45 +03:00
7f32348e7a Slight adjustment to tensor internals 2021-06-02 21:10:05 +03:00
c8621ee5b7 [WIP] optimization refactoring 2021-05-25 21:11:57 +03:00
f84f7f8e45 Merge branch 'dev' into feature/advanced-optimization
# Conflicts:
#	kmath-commons/src/main/kotlin/space/kscience/kmath/commons/optimization/CMOptimization.kt
#	kmath-commons/src/main/kotlin/space/kscience/kmath/commons/optimization/cmFit.kt
#	kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/DifferentiableExpression.kt
#	kmath-stat/src/commonMain/kotlin/space/kscience/kmath/optimization/FunctionOptimization.kt
#	kmath-stat/src/commonMain/kotlin/space/kscience/kmath/optimization/XYFit.kt
2021-05-25 17:00:02 +03:00
c240fa4a9e [WIP] optimization refactoring 2021-05-25 16:42:23 +03:00
88e94a7fd9 [WIP] Optimization 2021-05-24 17:02:12 +03:00
3ec674c61b Merge branch 'dev' into feature/advanced-optimization
# Conflicts:
#	examples/src/main/kotlin/space/kscience/kmath/functions/integrate.kt
#	examples/src/main/kotlin/space/kscience/kmath/functions/matrixIntegration.kt
#	kmath-commons/src/main/kotlin/space/kscience/kmath/commons/integration/CMGaussRuleIntegrator.kt
#	kmath-commons/src/main/kotlin/space/kscience/kmath/commons/integration/CMIntegrator.kt
#	kmath-commons/src/main/kotlin/space/kscience/kmath/commons/optimization/CMOptimization.kt
#	kmath-commons/src/main/kotlin/space/kscience/kmath/commons/optimization/cmFit.kt
#	kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/GaussIntegrator.kt
#	kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/Integrand.kt
#	kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/MultivariateIntegrand.kt
#	kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/UnivariateIntegrand.kt
#	kmath-functions/src/commonTest/kotlin/space/kscience/kmath/integration/GaussIntegralTest.kt
#	kmath-stat/src/commonMain/kotlin/space/kscience/kmath/optimization/FunctionOptimization.kt
#	kmath-stat/src/commonMain/kotlin/space/kscience/kmath/optimization/NoDerivFunctionOptimization.kt
#	kmath-stat/src/commonMain/kotlin/space/kscience/kmath/optimization/Optimization.kt
2021-05-24 14:44:08 +03:00
7b6361e59d [WIP] optimization refactor in process 2021-04-26 15:02:19 +03:00
257337f4fb [WIP] Refactor optimization 2021-04-25 22:34:59 +03:00
685 changed files with 43700 additions and 11696 deletions

3
.github/CODEOWNERS vendored Normal file
View File

@ -0,0 +1,3 @@
@altavir
/kmath-trajectory @ESchouten

View File

@ -7,35 +7,18 @@ on:
jobs: jobs:
build: build:
strategy: runs-on: windows-latest
matrix: timeout-minutes: 20
os: [ macOS-latest, windows-latest ]
runs-on: ${{matrix.os}}
timeout-minutes: 40
steps: steps:
- name: Checkout the repo - uses: actions/checkout@v3
uses: actions/checkout@v2 - uses: actions/setup-java@v3.5.1
- name: Set up JDK 11
uses: DeLaGuardo/setup-graalvm@4.0
with: with:
graalvm: 21.2.0 java-version: '11'
java: java11 distribution: 'liberica'
arch: amd64 cache: 'gradle'
- name: Cache gradle - name: Gradle Wrapper Validation
uses: actions/cache@v2 uses: gradle/wrapper-validation-action@v1.0.4
- name: Gradle Build
uses: gradle/gradle-build-action@v2.4.2
with: with:
path: | arguments: test jvmTest
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ hashFiles('*.gradle.kts') }}
restore-keys: |
${{ runner.os }}-gradle-
- name: Cache konan
uses: actions/cache@v2
with:
path: ~/.konan
key: ${{ runner.os }}-gradle-${{ hashFiles('*.gradle.kts') }}
restore-keys: |
${{ runner.os }}-gradle-
- name: Build
run: ./gradlew build --build-cache --no-daemon --stacktrace

View File

@ -1,28 +1,31 @@
name: Dokka publication name: Dokka publication
on: on:
push: workflow_dispatch:
branches: [ master ] release:
types: [ created ]
jobs: jobs:
build: build:
runs-on: ubuntu-20.04 runs-on: ubuntu-20.04
timeout-minutes: 40 timeout-minutes: 40
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v3.0.0
- uses: DeLaGuardo/setup-graalvm@4.0 - uses: actions/setup-java@v3.0.0
with: with:
graalvm: 21.2.0 java-version: 11
java: java11 distribution: liberica
arch: amd64 - name: Cache konan
- uses: actions/cache@v2 uses: actions/cache@v3.0.1
with: with:
path: ~/.gradle/caches path: ~/.konan
key: ${{ runner.os }}-gradle-${{ hashFiles('*.gradle.kts') }} key: ${{ runner.os }}-gradle-${{ hashFiles('*.gradle.kts') }}
restore-keys: | restore-keys: |
${{ runner.os }}-gradle- ${{ runner.os }}-gradle-
- run: ./gradlew dokkaHtmlMultiModule --build-cache --no-daemon --no-parallel --stacktrace - uses: gradle/gradle-build-action@v2.4.2
- uses: JamesIves/github-pages-deploy-action@4.1.0 with:
arguments: dokkaHtmlMultiModule --no-parallel
- uses: JamesIves/github-pages-deploy-action@v4.3.0
with: with:
branch: gh-pages branch: gh-pages
folder: build/dokka/htmlMultiModule folder: build/dokka/htmlMultiModule

View File

@ -14,25 +14,13 @@ jobs:
os: [ macOS-latest, windows-latest ] os: [ macOS-latest, windows-latest ]
runs-on: ${{matrix.os}} runs-on: ${{matrix.os}}
steps: steps:
- name: Checkout the repo - uses: actions/checkout@v3.0.0
uses: actions/checkout@v2 - uses: actions/setup-java@v3.10.0
- name: Set up JDK 11
uses: DeLaGuardo/setup-graalvm@4.0
with: with:
graalvm: 21.2.0 java-version: 11
java: java11 distribution: liberica
arch: amd64
- name: Cache gradle
uses: actions/cache@v2
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ hashFiles('*.gradle.kts') }}
restore-keys: |
${{ runner.os }}-gradle-
- name: Cache konan - name: Cache konan
uses: actions/cache@v2 uses: actions/cache@v3.0.1
with: with:
path: ~/.konan path: ~/.konan
key: ${{ runner.os }}-gradle-${{ hashFiles('*.gradle.kts') }} key: ${{ runner.os }}-gradle-${{ hashFiles('*.gradle.kts') }}
@ -40,14 +28,23 @@ jobs:
${{ runner.os }}-gradle- ${{ runner.os }}-gradle-
- name: Publish Windows Artifacts - name: Publish Windows Artifacts
if: matrix.os == 'windows-latest' if: matrix.os == 'windows-latest'
shell: cmd uses: gradle/gradle-build-action@v2.4.2
run: > with:
./gradlew release --no-daemon --build-cache -Ppublishing.enabled=true arguments: |
publishAllPublicationsToSpaceRepository
-Ppublishing.targets=all
-Ppublishing.space.user=${{ secrets.SPACE_APP_ID }} -Ppublishing.space.user=${{ secrets.SPACE_APP_ID }}
-Ppublishing.space.token=${{ secrets.SPACE_APP_SECRET }} -Ppublishing.space.token=${{ secrets.SPACE_APP_SECRET }}
- name: Publish Mac Artifacts - name: Publish Mac Artifacts
if: matrix.os == 'macOS-latest' if: matrix.os == 'macOS-latest'
run: > uses: gradle/gradle-build-action@v2.4.2
./gradlew release --no-daemon --build-cache -Ppublishing.enabled=true -Ppublishing.platform=macosX64 with:
arguments: |
publishMacosX64PublicationToSpaceRepository
publishMacosArm64PublicationToSpaceRepository
publishIosX64PublicationToSpaceRepository
publishIosArm64PublicationToSpaceRepository
publishIosSimulatorArm64PublicationToSpaceRepository
-Ppublishing.targets=all
-Ppublishing.space.user=${{ secrets.SPACE_APP_ID }} -Ppublishing.space.user=${{ secrets.SPACE_APP_ID }}
-Ppublishing.space.token=${{ secrets.SPACE_APP_SECRET }} -Ppublishing.space.token=${{ secrets.SPACE_APP_SECRET }}

12
.gitignore vendored
View File

@ -3,11 +3,10 @@ build/
out/ out/
.idea/ .idea/
!.idea/copyright/
!.idea/scopes/
.vscode/ .vscode/
.fleet/
.kotlin/
# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) # Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
!gradle-wrapper.jar !gradle-wrapper.jar
@ -18,3 +17,8 @@ out/
# Generated by javac -h and runtime # Generated by javac -h and runtime
*.class *.class
*.log *.log
!/.idea/copyright/
!/.idea/scopes/
/gradle/yarn.lock

View File

@ -1,6 +1,7 @@
<component name="CopyrightManager"> <component name="CopyrightManager">
<copyright> <copyright>
<option name="notice" value="Copyright 2018-2021 KMath contributors.&#10;Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file." /> <option name="allowReplaceRegexp" value="Copyright \d{4}-\d{4} KMath" />
<option name="notice" value="Copyright 2018-&amp;#36;today.year KMath contributors.&#10;Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file." />
<option name="myName" value="kmath" /> <option name="myName" value="kmath" />
</copyright> </copyright>
</component> </component>

View File

@ -1,5 +1,5 @@
<component name="CopyrightManager"> <component name="CopyrightManager">
<settings default="kmath"> <settings>
<module2copyright> <module2copyright>
<element module="Apply copyright" copyright="kmath" /> <element module="Apply copyright" copyright="kmath" />
</module2copyright> </module2copyright>

View File

@ -1,4 +1,3 @@
<component name="DependencyValidationManager"> <component name="DependencyValidationManager">
<scope name="Apply copyright" <scope name="Apply copyright" pattern="!file[*]:*//testData//*&amp;&amp;!file[*]:testData//*&amp;&amp;!file[*]:*.gradle.kts&amp;&amp;!file[*]:*.gradle&amp;&amp;!file[group:kotlin-ultimate]:*/&amp;&amp;!file[kotlin.libraries]:stdlib/api//*" />
pattern="!file[*]:*//testData//*&amp;&amp;!file[*]:testData//*&amp;&amp;!file[*]:*.gradle.kts&amp;&amp;!file[*]:*.gradle&amp;&amp;!file[group:kotlin-ultimate]:*/&amp;&amp;!file[kotlin.libraries]:stdlib/api//*"/>
</component> </component>

View File

@ -1,3 +1,48 @@
import kotlin.io.path.readText
val projectName = "kmath"
job("Build") { job("Build") {
gradlew("openjdk:11", "build") //Perform only jvm tests
gradlew("spc.registry.jetbrains.space/p/sci/containers/kotlin-ci:1.0.3", "test", "jvmTest")
}
job("Publish") {
startOn {
gitPush { enabled = false }
}
container("spc.registry.jetbrains.space/p/sci/containers/kotlin-ci:1.0.3") {
env["SPACE_USER"] = "{{ project:space_user }}"
env["SPACE_TOKEN"] = "{{ project:space_token }}"
kotlinScript { api ->
val spaceUser = System.getenv("SPACE_USER")
val spaceToken = System.getenv("SPACE_TOKEN")
// write the version to the build directory
api.gradlew("version")
//read the version from build file
val version = java.nio.file.Path.of("build/project-version.txt").readText()
val revisionSuffix = if (version.endsWith("SNAPSHOT")) {
"-" + api.gitRevision().take(7)
} else {
""
}
api.space().projects.automation.deployments.start(
project = api.projectIdentifier(),
targetIdentifier = TargetIdentifier.Key(projectName),
version = version + revisionSuffix,
// automatically update deployment status based on the status of a job
syncWithAutomationJob = true
)
api.gradlew(
"publishAllPublicationsToSpaceRepository",
"-Ppublishing.space.user=\"$spaceUser\"",
"-Ppublishing.space.token=\"$spaceToken\"",
)
}
}
} }

0
.space/CODEOWNERS Normal file
View File

View File

@ -1,7 +1,96 @@
# KMath # KMath
## [Unreleased] ## Unreleased
### Added ### Added
- Metropolis-Hastings sampler
### Changed
### Deprecated
### Removed
### Fixed
### Security
## 0.4.0-dev-3 - 2024-02-18
### Added
- Reification. Explicit `SafeType` for algebras.
- Integer division algebras.
- Float32 geometries.
- New Attributes-kt module that could be used as stand-alone. It declares. type-safe attributes containers.
- Explicit `mutableStructureND` builders for mutable structures.
- `Buffer.asList()` zero-copy transformation.
- Wasm support.
- Parallel implementation of `LinearSpace` for Float64
- Parallel buffer factories
### Changed
- Buffer copy removed from API (added as an extension).
- Default naming for algebra and buffers now uses IntXX/FloatXX notation instead of Java types.
- Remove unnecessary inlines in basic algebras.
- QuaternionField -> QuaternionAlgebra and does not implement `Field` anymore since it is non-commutative
- kmath-geometry is split into `euclidean2d` and `euclidean3d`
- Features replaced with Attributes.
- Transposed refactored.
- Kmath-memory is moved on top of core.
### Deprecated
- ND4J engine
### Removed
- `asPolynomial` function due to scope pollution
- Codegend for ejml (450 lines of codegen for 1000 lines of code is too much)
### Fixed
- Median statistics
- Complex power of negative real numbers
- Add proper mutability for MutableBufferND rows and columns
- Generic Float32 and Float64 vectors are used in geometry algebras.
## 0.3.1 - 2023-04-09
### Added
- Wasm support for `memory`, `core`, `complex` and `functions` modules.
- Generic builders for `BufferND` and `MutableBufferND`
- `NamedMatrix` - matrix with symbol-based indexing
- `Expression` with default arguments
- Type-aliases for numbers like `Float64`
- Autodiff for generic algebra elements in core!
- Algebra now has an obligatory `bufferFactory` (#477).
### Changed
- Removed marker `Vector` type for geometry
- Geometry uses type-safe angles
- Tensor operations switched to prefix notation
- Row-wise and column-wise ND shapes in the core
- Shape is read-only
- Major refactor of tensors (only minor API changes)
- Kotlin 1.8.20
- `LazyStructure` `deffered` -> `async` to comply with coroutines code style
- Default `dot` operation in tensor algebra no longer support broadcasting. Instead `matmul` operation is added
to `DoubleTensorAlgebra`.
- Multik went MPP
### Removed
- Trajectory moved to https://github.com/SciProgCentre/maps-kt
- Polynomials moved to https://github.com/SciProgCentre/kmath-polynomial
## 0.3.0
### Added
- `ScaleOperations` interface - `ScaleOperations` interface
- `Field` extends `ScaleOperations` - `Field` extends `ScaleOperations`
- Basic integration API - Basic integration API
@ -13,10 +102,21 @@
- Extended operations for ND4J fields - Extended operations for ND4J fields
- Jupyter Notebook integration module (kmath-jupyter) - Jupyter Notebook integration module (kmath-jupyter)
- `@PerformancePitfall` annotation to mark possibly slow API - `@PerformancePitfall` annotation to mark possibly slow API
- Unified architecture for Integration and Optimization using features.
- `BigInt` operation performance improvement and fixes by @zhelenskiy (#328) - `BigInt` operation performance improvement and fixes by @zhelenskiy (#328)
- Integration between `MST` and Symja `IExpr` - Integration between `MST` and Symja `IExpr`
- Complex power
- Separate methods for UInt, Int and Number powers. NaN safety.
- Tensorflow prototype
- `ValueAndErrorField`
- MST compilation to WASM: #286
- Jafama integration: #176
- `contentEquals` with tolerance: #364
- Compilation to TeX for MST: #254
### Changed ### Changed
- Annotations moved to `space.kscience.kmath`
- Exponential operations merged with hyperbolic functions - Exponential operations merged with hyperbolic functions
- Space is replaced by Group. Space is reserved for vector spaces. - Space is replaced by Group. Space is reserved for vector spaces.
- VectorSpace is now a vector space - VectorSpace is now a vector space
@ -36,10 +136,24 @@
- Remove Any restriction on polynomials - Remove Any restriction on polynomials
- Add `out` variance to type parameters of `StructureND` and its implementations where possible - Add `out` variance to type parameters of `StructureND` and its implementations where possible
- Rename `DifferentiableMstExpression` to `KotlingradExpression` - Rename `DifferentiableMstExpression` to `KotlingradExpression`
- `FeatureSet` now accepts only `Feature`. It is possible to override keys and use interfaces.
- Use `Symbol` factory function instead of `StringSymbol`
- New discoverability pattern: `<Type>.algebra.<nd/etc>`
- Adjusted commons-math API for linear solvers to match conventions.
- Buffer algebra does not require size anymore
- Operations -> Ops
- Default Buffer and ND algebras are now Ops and lack neutral elements (0, 1) as well as algebra-level shapes.
- Tensor algebra takes read-only structures as input and inherits AlgebraND
- `UnivariateDistribution` renamed to `Distribution1D`
- Rework of histograms.
- `UnivariateFunction` -> `Function1D`, `MultivariateFunction` -> `FunctionND`
### Deprecated ### Deprecated
- Specialized `DoubleBufferAlgebra`
### Removed ### Removed
- Nearest in Domain. To be implemented in geometry package. - Nearest in Domain. To be implemented in geometry package.
- Number multiplication and division in main Algebra chain - Number multiplication and division in main Algebra chain
- `contentEquals` from Buffer. It moved to the companion. - `contentEquals` from Buffer. It moved to the companion.
@ -47,15 +161,17 @@
- Expression algebra builders - Expression algebra builders
- Complex and Quaternion no longer are elements. - Complex and Quaternion no longer are elements.
- Second generic from DifferentiableExpression - Second generic from DifferentiableExpression
- Algebra elements are completely removed. Use algebra contexts instead.
### Fixed ### Fixed
- Ring inherits RingOperations, not GroupOperations - Ring inherits RingOperations, not GroupOperations
- Univariate histogram filling - Univariate histogram filling
### Security ## 0.2.0
## [0.2.0]
### Added ### Added
- `fun` annotation for SAM interfaces in library - `fun` annotation for SAM interfaces in library
- Explicit `public` visibility for all public APIs - Explicit `public` visibility for all public APIs
- Better trigonometric and hyperbolic functions for `AutoDiffField` (https://github.com/mipt-npm/kmath/pull/140) - Better trigonometric and hyperbolic functions for `AutoDiffField` (https://github.com/mipt-npm/kmath/pull/140)
@ -75,6 +191,7 @@
- Basic Quaternion vector support in `kmath-complex`. - Basic Quaternion vector support in `kmath-complex`.
### Changed ### Changed
- Package changed from `scientifik` to `space.kscience` - Package changed from `scientifik` to `space.kscience`
- Gradle version: 6.6 -> 6.8.2 - Gradle version: 6.6 -> 6.8.2
- Minor exceptions refactor (throwing `IllegalArgumentException` by argument checks instead of `IllegalStateException`) - Minor exceptions refactor (throwing `IllegalArgumentException` by argument checks instead of `IllegalStateException`)
@ -84,7 +201,7 @@
- Full autodiff refactoring based on `Symbol` - Full autodiff refactoring based on `Symbol`
- `kmath-prob` renamed to `kmath-stat` - `kmath-prob` renamed to `kmath-stat`
- Grid generators moved to `kmath-for-real` - Grid generators moved to `kmath-for-real`
- Use `Point<Double>` instead of specialized type in `kmath-for-real` - Use `Point<Float64>` instead of specialized type in `kmath-for-real`
- Optimized dot product for buffer matrices moved to `kmath-for-real` - Optimized dot product for buffer matrices moved to `kmath-for-real`
- EjmlMatrix context is an object - EjmlMatrix context is an object
- Matrix LUP `inverse` renamed to `inverseWithLup` - Matrix LUP `inverse` renamed to `inverseWithLup`
@ -98,9 +215,8 @@
- `symbol` method in `Algebra` renamed to `bindSymbol` to avoid ambiguity - `symbol` method in `Algebra` renamed to `bindSymbol` to avoid ambiguity
- Add `out` projection to `Buffer` generic - Add `out` projection to `Buffer` generic
### Deprecated
### Removed ### Removed
- `kmath-koma` module because it doesn't support Kotlin 1.4. - `kmath-koma` module because it doesn't support Kotlin 1.4.
- Support of `legacy` JS backend (we will support only IR) - Support of `legacy` JS backend (we will support only IR)
- `toGrid` method. - `toGrid` method.
@ -109,22 +225,24 @@
- StructureND identity and equals - StructureND identity and equals
### Fixed ### Fixed
- `symbol` method in `MstExtendedField` (https://github.com/mipt-npm/kmath/pull/140) - `symbol` method in `MstExtendedField` (https://github.com/mipt-npm/kmath/pull/140)
### Security ## 0.1.4
## [0.1.4]
### Added ### Added
- Functional Expressions API - Functional Expressions API
- Mathematical Syntax Tree, its interpreter and API - Mathematical Syntax Tree, its interpreter and API
- String to MST parser (https://github.com/mipt-npm/kmath/pull/120) - String to MST parser (https://github.com/mipt-npm/kmath/pull/120)
- MST to JVM bytecode translator (https://github.com/mipt-npm/kmath/pull/94) - MST to JVM bytecode translator (https://github.com/mipt-npm/kmath/pull/94)
- FloatBuffer (specialized MutableBuffer over FloatArray) - FloatBuffer (specialized MutableBuffer over FloatArray)
- FlaggedBuffer to associate primitive numbers buffer with flags (to mark values infinite or missing, etc.) - FlaggedBuffer to associate primitive numbers buffer with flags (to mark values infinite or missing, etc.)
- Specialized builder functions for all primitive buffers like `IntBuffer(25) { it + 1 }` (https://github.com/mipt-npm/kmath/pull/125) - Specialized builder functions for all primitive buffers
like `IntBuffer(25) { it + 1 }` (https://github.com/mipt-npm/kmath/pull/125)
- Interface `NumericAlgebra` where `number` operation is available to convert numbers to algebraic elements - Interface `NumericAlgebra` where `number` operation is available to convert numbers to algebraic elements
- Inverse trigonometric functions support in ExtendedField (`asin`, `acos`, `atan`) (https://github.com/mipt-npm/kmath/pull/114) - Inverse trigonometric functions support in
ExtendedField (`asin`, `acos`, `atan`) (https://github.com/mipt-npm/kmath/pull/114)
- New space extensions: `average` and `averageWith` - New space extensions: `average` and `averageWith`
- Local coding conventions - Local coding conventions
- Geometric Domains API in `kmath-core` - Geometric Domains API in `kmath-core`
@ -133,10 +251,12 @@
- Norm support for `Complex` - Norm support for `Complex`
### Changed ### Changed
- `readAsMemory` now has `throws IOException` in JVM signature. - `readAsMemory` now has `throws IOException` in JVM signature.
- Several functions taking functional types were made `inline`. - Several functions taking functional types were made `inline`.
- Several functions taking functional types now have `callsInPlace` contracts. - Several functions taking functional types now have `callsInPlace` contracts.
- BigInteger and BigDecimal algebra: JBigDecimalField has companion object with default math context; minor optimizations - BigInteger and BigDecimal algebra: JBigDecimalField has companion object with default math context; minor
optimizations
- `power(T, Int)` extension function has preconditions and supports `Field<T>` - `power(T, Int)` extension function has preconditions and supports `Field<T>`
- Memory objects have more preconditions (overflow checking) - Memory objects have more preconditions (overflow checking)
- `tg` function is renamed to `tan` (https://github.com/mipt-npm/kmath/pull/114) - `tg` function is renamed to `tan` (https://github.com/mipt-npm/kmath/pull/114)
@ -144,6 +264,7 @@
- Moved probability distributions to commons-rng and to `kmath-prob` - Moved probability distributions to commons-rng and to `kmath-prob`
### Fixed ### Fixed
- Missing copy method in Memory implementation on JS (https://github.com/mipt-npm/kmath/pull/106) - Missing copy method in Memory implementation on JS (https://github.com/mipt-npm/kmath/pull/106)
- D3.dim value in `kmath-dimensions` - D3.dim value in `kmath-dimensions`
- Multiplication in integer rings in `kmath-core` (https://github.com/mipt-npm/kmath/pull/101) - Multiplication in integer rings in `kmath-core` (https://github.com/mipt-npm/kmath/pull/101)

184
README.md
View File

@ -1,6 +1,6 @@
[![JetBrains Research](https://jb.gg/badges/research.svg)](https://confluence.jetbrains.com/display/ALL/JetBrains+on+GitHub) [![JetBrains Research](https://jb.gg/badges/research.svg)](https://confluence.jetbrains.com/display/ALL/JetBrains+on+GitHub)
[![DOI](https://zenodo.org/badge/129486382.svg)](https://zenodo.org/badge/latestdoi/129486382) [![DOI](https://zenodo.org/badge/129486382.svg)](https://zenodo.org/badge/latestdoi/129486382)
![Gradle build](https://github.com/mipt-npm/kmath/workflows/Gradle%20build/badge.svg) ![Gradle build](https://github.com/SciProgCentre/kmath/workflows/Gradle%20build/badge.svg)
[![Maven Central](https://img.shields.io/maven-central/v/space.kscience/kmath-core.svg?label=Maven%20Central)](https://search.maven.org/search?q=g:%22space.kscience%22) [![Maven Central](https://img.shields.io/maven-central/v/space.kscience/kmath-core.svg?label=Maven%20Central)](https://search.maven.org/search?q=g:%22space.kscience%22)
[![Space](https://img.shields.io/badge/dynamic/xml?color=orange&label=Space&query=//metadata/versioning/latest&url=https%3A%2F%2Fmaven.pkg.jetbrains.space%2Fmipt-npm%2Fp%2Fsci%2Fmaven%2Fspace%2Fkscience%2Fkmath-core%2Fmaven-metadata.xml)](https://maven.pkg.jetbrains.space/mipt-npm/p/sci/maven/space/kscience/) [![Space](https://img.shields.io/badge/dynamic/xml?color=orange&label=Space&query=//metadata/versioning/latest&url=https%3A%2F%2Fmaven.pkg.jetbrains.space%2Fmipt-npm%2Fp%2Fsci%2Fmaven%2Fspace%2Fkscience%2Fkmath-core%2Fmaven-metadata.xml)](https://maven.pkg.jetbrains.space/mipt-npm/p/sci/maven/space/kscience/)
@ -11,18 +11,22 @@ analog to Python's NumPy library. Later we found that kotlin is much more flexib
architecture designs. In contrast to `numpy` and `scipy` it is modular and has a lightweight core. The `numpy`-like architecture designs. In contrast to `numpy` and `scipy` it is modular and has a lightweight core. The `numpy`-like
experience could be achieved with [kmath-for-real](/kmath-for-real) extension module. experience could be achieved with [kmath-for-real](/kmath-for-real) extension module.
[Documentation site (**WIP**)](https://mipt-npm.github.io/kmath/) [Documentation site](https://SciProgCentre.github.io/kmath/)
## Publications and talks ## Publications and talks
* [A conceptual article about context-oriented design](https://proandroiddev.com/an-introduction-context-oriented-programming-in-kotlin-2e79d316b0a2) * [A conceptual article about context-oriented design](https://proandroiddev.com/an-introduction-context-oriented-programming-in-kotlin-2e79d316b0a2)
* [Another article about context-oriented design](https://proandroiddev.com/diving-deeper-into-context-oriented-programming-in-kotlin-3ecb4ec38814) * [Another article about context-oriented design](https://proandroiddev.com/diving-deeper-into-context-oriented-programming-in-kotlin-3ecb4ec38814)
* [ACAT 2019 conference paper](https://aip.scitation.org/doi/abs/10.1063/1.5130103) * [ACAT 2019 conference paper](https://aip.scitation.org/doi/abs/10.1063/1.5130103)
* [A talk at KotlinConf 2019 about using kotlin for science](https://youtu.be/LI_5TZ7tnOE?si=4LknX41gl_YeUbIe)
* [A talk on architecture at Joker-2021 (in Russian)](https://youtu.be/1bZ2doHiRRM?si=9w953ro9yu98X_KJ)
* [The same talk in English](https://youtu.be/yP5DIc2fVwQ?si=louZzQ1dcXV6gP10)
* [A seminar on tensor API](https://youtu.be/0H99wUs0xTM?si=6c__04jrByFQtVpo)
# Goal # Goal
* Provide a flexible and powerful API to work with mathematics abstractions in Kotlin-multiplatform (JVM, JS and Native) * Provide a flexible and powerful API to work with mathematics abstractions in Kotlin-multiplatform (JVM, JS, Native and
. Wasm).
* Provide basic multiplatform implementations for those abstractions (without significant performance optimization). * Provide basic multiplatform implementations for those abstractions (without significant performance optimization).
* Provide bindings and wrappers with those abstractions for popular optimized platform libraries. * Provide bindings and wrappers with those abstractions for popular optimized platform libraries.
@ -44,59 +48,29 @@ module definitions below. The module stability could have the following levels:
* **PROTOTYPE**. On this level there are no compatibility guarantees. All methods and classes form those modules could * **PROTOTYPE**. On this level there are no compatibility guarantees. All methods and classes form those modules could
break any moment. You can still use it, but be sure to fix the specific version. break any moment. You can still use it, but be sure to fix the specific version.
* **EXPERIMENTAL**. The general API is decided, but some changes could be made. Volatile API is marked * **EXPERIMENTAL**. The general API is decided, but some changes could be made. Volatile API is marked
with `@UnstableKmathAPI` or other stability warning annotations. with `@UnstableKMathAPI` or other stability warning annotations.
* **DEVELOPMENT**. API breaking generally follows semantic versioning ideology. There could be changes in minor * **DEVELOPMENT**. API breaking generally follows semantic versioning ideology. There could be changes in minor
versions, but not in patch versions. API is protected versions, but not in patch versions. API is protected
with [binary-compatibility-validator](https://github.com/Kotlin/binary-compatibility-validator) tool. with [binary-compatibility-validator](https://github.com/Kotlin/binary-compatibility-validator) tool.
* **STABLE**. The API stabilized. Breaking changes are allowed only in major releases. * **STABLE**. The API stabilized. Breaking changes are allowed only in major releases.
<!--Current feature list is [here](/docs/features.md)-->
<!--* **Array-like structures** Full support of many-dimensional array-like structures -->
<!--including mixed arithmetic operations and function operations over arrays and numbers (with the added benefit of static type checking).-->
<!--* **Histograms** Fast multi-dimensional histograms.-->
<!--* **Streaming** Streaming operations on mathematical objects and objects buffers.-->
<!--* **Type-safe dimensions** Type-safe dimensions for matrix operations.-->
<!--* **Commons-math wrapper** It is planned to gradually wrap most parts of -->
<!--[Apache commons-math](http://commons.apache.org/proper/commons-math/) library in Kotlin code and maybe rewrite some -->
<!--parts to better suit the Kotlin programming paradigm, however there is no established roadmap for that. Feel free to -->
<!--submit a feature request if you want something to be implemented first.-->
<!-- -->
<!--## Planned features-->
<!--* **Messaging** A mathematical notation to support multi-language and multi-node communication for mathematical tasks.-->
<!--* **Array statistics** -->
<!--* **Integration** Univariate and multivariate integration framework.-->
<!--* **Probability and distributions**-->
<!--* **Fitting** Non-linear curve fitting facilities-->
## Modules ## Modules
<hr/>
* ### [benchmarks](benchmarks) ### [attributes-kt](attributes-kt)
> An API and basic implementation for arranging objects in a continuous memory block.
> >
> **Maturity**: DEVELOPMENT
### [benchmarks](benchmarks)
> >
> **Maturity**: EXPERIMENTAL > **Maturity**: EXPERIMENTAL
<hr/>
* ### [examples](examples) ### [examples](examples)
>
> >
> **Maturity**: EXPERIMENTAL > **Maturity**: EXPERIMENTAL
<hr/>
* ### [kmath-ast](kmath-ast) ### [kmath-ast](kmath-ast)
>
> >
> **Maturity**: EXPERIMENTAL > **Maturity**: EXPERIMENTAL
> >
@ -106,26 +80,23 @@ module definitions below. The module stability could have the following levels:
> - [mst-js-codegen](kmath-ast/src/jsMain/kotlin/space/kscience/kmath/estree/estree.kt) : Dynamic MST to JS compiler > - [mst-js-codegen](kmath-ast/src/jsMain/kotlin/space/kscience/kmath/estree/estree.kt) : Dynamic MST to JS compiler
> - [rendering](kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/MathRenderer.kt) : Extendable MST rendering > - [rendering](kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/MathRenderer.kt) : Extendable MST rendering
<hr/>
* ### [kmath-commons](kmath-commons) ### [kmath-commons](kmath-commons)
> > Commons math binding for kmath
> >
> **Maturity**: EXPERIMENTAL > **Maturity**: EXPERIMENTAL
<hr/>
* ### [kmath-complex](kmath-complex) ### [kmath-complex](kmath-complex)
> Complex numbers and quaternions. > Complex numbers and quaternions.
> >
> **Maturity**: PROTOTYPE > **Maturity**: PROTOTYPE
> >
> **Features:** > **Features:**
> - [complex](kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Complex.kt) : Complex Numbers > - [complex](kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Complex.kt) : Complex numbers operations
> - [quaternion](kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Quaternion.kt) : Quaternions > - [quaternion](kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Quaternion.kt) : Quaternions and their composition
<hr/>
* ### [kmath-core](kmath-core) ### [kmath-core](kmath-core)
> Core classes, algebra definitions, basic linear algebra > Core classes, algebra definitions, basic linear algebra
> >
> **Maturity**: DEVELOPMENT > **Maturity**: DEVELOPMENT
@ -140,23 +111,19 @@ objects to the expression by providing a context. Expressions can be used for a
performance calculations to code generation. performance calculations to code generation.
> - [domains](kmath-core/src/commonMain/kotlin/space/kscience/kmath/domains) : Domains > - [domains](kmath-core/src/commonMain/kotlin/space/kscience/kmath/domains) : Domains
> - [autodiff](kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/SimpleAutoDiff.kt) : Automatic differentiation > - [autodiff](kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/SimpleAutoDiff.kt) : Automatic differentiation
> - [Parallel linear algebra](kmath-core/#) : Parallel implementation for `LinearAlgebra`
<hr/>
* ### [kmath-coroutines](kmath-coroutines) ### [kmath-coroutines](kmath-coroutines)
>
> >
> **Maturity**: EXPERIMENTAL > **Maturity**: EXPERIMENTAL
<hr/>
* ### [kmath-dimensions](kmath-dimensions) ### [kmath-dimensions](kmath-dimensions)
> > A proof of concept module for adding type-safe dimensions to structures
> >
> **Maturity**: PROTOTYPE > **Maturity**: PROTOTYPE
<hr/>
* ### [kmath-ejml](kmath-ejml) ### [kmath-ejml](kmath-ejml)
>
> >
> **Maturity**: PROTOTYPE > **Maturity**: PROTOTYPE
> >
@ -165,9 +132,8 @@ performance calculations to code generation.
> - [ejml-matrix](kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlMatrix.kt) : Matrix implementation. > - [ejml-matrix](kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlMatrix.kt) : Matrix implementation.
> - [ejml-linear-space](kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlLinearSpace.kt) : LinearSpace implementations. > - [ejml-linear-space](kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlLinearSpace.kt) : LinearSpace implementations.
<hr/>
* ### [kmath-for-real](kmath-for-real) ### [kmath-for-real](kmath-for-real)
> Extension module that should be used to achieve numpy-like behavior. > Extension module that should be used to achieve numpy-like behavior.
All operations are specialized to work with `Double` numbers without declaring algebraic contexts. All operations are specialized to work with `Double` numbers without declaring algebraic contexts.
One can still use generic algebras though. One can still use generic algebras though.
@ -179,10 +145,9 @@ One can still use generic algebras though.
> - [DoubleMatrix](kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/DoubleMatrix.kt) : Numpy-like operations for 2d real structures > - [DoubleMatrix](kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/DoubleMatrix.kt) : Numpy-like operations for 2d real structures
> - [grids](kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/structures/grids.kt) : Uniform grid generators > - [grids](kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/structures/grids.kt) : Uniform grid generators
<hr/>
* ### [kmath-functions](kmath-functions) ### [kmath-functions](kmath-functions)
> > Functions, integration and interpolation
> >
> **Maturity**: EXPERIMENTAL > **Maturity**: EXPERIMENTAL
> >
@ -193,38 +158,30 @@ One can still use generic algebras though.
> - [spline interpolation](kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/SplineInterpolator.kt) : Cubic spline XY interpolator. > - [spline interpolation](kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/SplineInterpolator.kt) : Cubic spline XY interpolator.
> - [integration](kmath-functions/#) : Univariate and multivariate quadratures > - [integration](kmath-functions/#) : Univariate and multivariate quadratures
<hr/>
* ### [kmath-geometry](kmath-geometry) ### [kmath-geometry](kmath-geometry)
>
> >
> **Maturity**: PROTOTYPE > **Maturity**: PROTOTYPE
<hr/>
* ### [kmath-histograms](kmath-histograms) ### [kmath-histograms](kmath-histograms)
>
> >
> **Maturity**: PROTOTYPE > **Maturity**: PROTOTYPE
<hr/>
* ### [kmath-jafama](kmath-jafama) ### [kmath-jafama](kmath-jafama)
> Jafama integration module
> >
> > **Maturity**: DEPRECATED
> **Maturity**: PROTOTYPE
> >
> **Features:** > **Features:**
> - [jafama-double](kmath-jafama/src/main/kotlin/space/kscience/kmath/jafama/) : Double ExtendedField implementations based on Jafama > - [jafama-double](kmath-jafama/src/main/kotlin/space/kscience/kmath/jafama/) : Double ExtendedField implementations based on Jafama
<hr/>
* ### [kmath-jupyter](kmath-jupyter) ### [kmath-jupyter](kmath-jupyter)
>
> >
> **Maturity**: PROTOTYPE > **Maturity**: PROTOTYPE
<hr/>
* ### [kmath-kotlingrad](kmath-kotlingrad) ### [kmath-kotlingrad](kmath-kotlingrad)
> > Kotlin∇ integration module
> >
> **Maturity**: EXPERIMENTAL > **Maturity**: EXPERIMENTAL
> >
@ -232,40 +189,47 @@ One can still use generic algebras though.
> - [differentiable-mst-expression](kmath-kotlingrad/src/main/kotlin/space/kscience/kmath/kotlingrad/KotlingradExpression.kt) : MST based DifferentiableExpression. > - [differentiable-mst-expression](kmath-kotlingrad/src/main/kotlin/space/kscience/kmath/kotlingrad/KotlingradExpression.kt) : MST based DifferentiableExpression.
> - [scalars-adapters](kmath-kotlingrad/src/main/kotlin/space/kscience/kmath/kotlingrad/scalarsAdapters.kt) : Conversions between Kotlin∇'s SFun and MST > - [scalars-adapters](kmath-kotlingrad/src/main/kotlin/space/kscience/kmath/kotlingrad/scalarsAdapters.kt) : Conversions between Kotlin∇'s SFun and MST
<hr/>
* ### [kmath-memory](kmath-memory) ### [kmath-memory](kmath-memory)
> An API and basic implementation for arranging objects in a continuous memory block. > An API and basic implementation for arranging objects in a continuous memory block.
> >
> **Maturity**: DEVELOPMENT > **Maturity**: DEVELOPMENT
<hr/>
* ### [kmath-nd4j](kmath-nd4j) ### [kmath-multik](kmath-multik)
> JetBrains Multik connector
> >
> **Maturity**: PROTOTYPE
### [kmath-nd4j](kmath-nd4j)
> ND4J NDStructure implementation and according NDAlgebra classes
> >
> **Maturity**: EXPERIMENTAL > **Maturity**: DEPRECATED
> >
> **Features:** > **Features:**
> - [nd4jarraystructure](kmath-nd4j/#) : NDStructure wrapper for INDArray > - [nd4jarraystructure](kmath-nd4j/#) : NDStructure wrapper for INDArray
> - [nd4jarrayrings](kmath-nd4j/#) : Rings over Nd4jArrayStructure of Int and Long > - [nd4jarrayrings](kmath-nd4j/#) : Rings over Nd4jArrayStructure of Int and Long
> - [nd4jarrayfields](kmath-nd4j/#) : Fields over Nd4jArrayStructure of Float and Double > - [nd4jarrayfields](kmath-nd4j/#) : Fields over Nd4jArrayStructure of Float and Double
<hr/>
* ### [kmath-stat](kmath-stat) ### [kmath-optimization](kmath-optimization)
>
> >
> **Maturity**: EXPERIMENTAL > **Maturity**: EXPERIMENTAL
<hr/>
* ### [kmath-symja](kmath-symja) ### [kmath-stat](kmath-stat)
> >
> **Maturity**: EXPERIMENTAL
### [kmath-symja](kmath-symja)
> Symja integration module
> >
> **Maturity**: PROTOTYPE > **Maturity**: PROTOTYPE
<hr/>
* ### [kmath-tensors](kmath-tensors) ### [kmath-tensorflow](kmath-tensorflow)
> Google tensorflow connector
> >
> **Maturity**: PROTOTYPE
### [kmath-tensors](kmath-tensors)
> >
> **Maturity**: PROTOTYPE > **Maturity**: PROTOTYPE
> >
@ -274,13 +238,15 @@ One can still use generic algebras though.
> - [tensor algebra with broadcasting](kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/BroadcastDoubleTensorAlgebra.kt) : Basic linear algebra operations implemented with broadcasting. > - [tensor algebra with broadcasting](kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/BroadcastDoubleTensorAlgebra.kt) : Basic linear algebra operations implemented with broadcasting.
> - [linear algebra operations](kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/api/LinearOpsTensorAlgebra.kt) : Advanced linear algebra operations like LU decomposition, SVD, etc. > - [linear algebra operations](kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/api/LinearOpsTensorAlgebra.kt) : Advanced linear algebra operations like LU decomposition, SVD, etc.
<hr/>
* ### [kmath-viktor](kmath-viktor) ### [kmath-viktor](kmath-viktor)
> Binding for https://github.com/JetBrains-Research/viktor
> >
> **Maturity**: DEPRECATED
### [test-utils](test-utils)
> >
> **Maturity**: DEVELOPMENT > **Maturity**: EXPERIMENTAL
<hr/>
## Multi-platform support ## Multi-platform support
@ -288,23 +254,24 @@ One can still use generic algebras though.
KMath is developed as a multi-platform library, which means that most of the interfaces are declared in the KMath is developed as a multi-platform library, which means that most of the interfaces are declared in the
[common source sets](/kmath-core/src/commonMain) and implemented there wherever it is possible. In some cases, features [common source sets](/kmath-core/src/commonMain) and implemented there wherever it is possible. In some cases, features
are delegated to platform-specific implementations even if they could be provided in the common module for performance are delegated to platform-specific implementations even if they could be provided in the common module for performance
reasons. Currently, the Kotlin/JVM is the primary platform, however Kotlin/Native and Kotlin/JS contributions and reasons. Currently, Kotlin/JVM is the primary platform, however, Kotlin/Native and Kotlin/JS contributions and
feedback are also welcome. feedback are also welcome.
## Performance ## Performance
Calculation performance is one of major goals of KMath in the future, but in some cases it is impossible to achieve both Calculation of performance is one of the major goals of KMath in the future, but in some cases it is impossible to
achieve both
performance and flexibility. performance and flexibility.
We expect to focus on creating convenient universal API first and then work on increasing performance for specific We expect to focus on creating a convenient universal API first and then work on increasing performance for specific
cases. We expect the worst KMath benchmarks will perform better than native Python, but worse than optimized cases. We expect the worst KMath benchmarks will perform better than native Python, but worse than optimized
native/SciPy (mostly due to boxing operations on primitive numbers). The best performance of optimized parts could be native/SciPy (mostly due to boxing operations on primitive numbers). The best performance of optimized parts could be
better than SciPy. better than SciPy.
## Requirements ## Requirements
KMath currently relies on JDK 11 for compilation and execution of Kotlin-JVM part. We recommend to use GraalVM-CE 11 for KMath currently relies on JDK 11 for compilation and execution of Kotlin-JVM part. We recommend using GraalVM-CE or
execution to get better performance. Oracle GraalVM for execution to get better performance.
### Repositories ### Repositories
@ -319,16 +286,15 @@ repositories {
} }
dependencies { dependencies {
api("space.kscience:kmath-core:0.3.0-dev-14") api("space.kscience:kmath-core:$version")
// api("space.kscience:kmath-core-jvm:0.3.0-dev-14") for jvm-specific version // api("space.kscience:kmath-core-jvm:$version") for jvm-specific version
} }
``` ```
Gradle `6.0+` is required for multiplatform artifacts.
## Contributing ## Contributing
The project requires a lot of additional work. The most important thing we need is a feedback about what features are The project requires a lot of additional work. The most important thing we need is feedback about what features are
required the most. Feel free to create feature requests. We are also welcome to code contributions, especially in issues required the most. Feel free to create feature requests. We are also welcome to code contributions, especially in issues
marked with marked
[waiting for a hero](https://github.com/mipt-npm/kmath/labels/waiting%20for%20a%20hero) label. with [good first issue](hhttps://github.com/SciProgCentre/kmath/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22)
label.

21
attributes-kt/README.md Normal file
View File

@ -0,0 +1,21 @@
# Module attributes-kt
## Usage
## Artifact:
The Maven coordinates of this project are `space.kscience:attributes-kt:0.1.0`.
**Gradle Kotlin DSL:**
```kotlin
repositories {
maven("https://repo.kotlin.link")
mavenCentral()
}
dependencies {
implementation("space.kscience:attributes-kt:0.1.0")
}
```

View File

@ -0,0 +1,104 @@
public abstract interface class space/kscience/attributes/Attribute {
}
public abstract interface class space/kscience/attributes/AttributeContainer {
public abstract fun getAttributes ()Lspace/kscience/attributes/Attributes;
}
public abstract interface class space/kscience/attributes/AttributeScope {
}
public abstract interface class space/kscience/attributes/AttributeWithDefault : space/kscience/attributes/Attribute {
public abstract fun getDefault ()Ljava/lang/Object;
}
public abstract interface class space/kscience/attributes/Attributes {
public static final field Companion Lspace/kscience/attributes/Attributes$Companion;
public abstract fun equals (Ljava/lang/Object;)Z
public fun get (Lspace/kscience/attributes/Attribute;)Ljava/lang/Object;
public abstract fun getContent ()Ljava/util/Map;
public fun getKeys ()Ljava/util/Set;
public abstract fun hashCode ()I
public abstract fun toString ()Ljava/lang/String;
}
public final class space/kscience/attributes/Attributes$Companion {
public final fun equals (Lspace/kscience/attributes/Attributes;Lspace/kscience/attributes/Attributes;)Z
public final fun getEMPTY ()Lspace/kscience/attributes/Attributes;
}
public final class space/kscience/attributes/AttributesBuilder : space/kscience/attributes/Attributes {
public final fun add (Lspace/kscience/attributes/SetAttribute;Ljava/lang/Object;)V
public final fun build ()Lspace/kscience/attributes/Attributes;
public fun equals (Ljava/lang/Object;)Z
public fun getContent ()Ljava/util/Map;
public fun hashCode ()I
public final fun invoke (Lspace/kscience/attributes/Attribute;Ljava/lang/Object;)V
public final fun put (Lspace/kscience/attributes/Attribute;Ljava/lang/Object;)V
public final fun putAll (Lspace/kscience/attributes/Attributes;)V
public final fun remove (Lspace/kscience/attributes/SetAttribute;Ljava/lang/Object;)V
public final fun set (Lspace/kscience/attributes/Attribute;Ljava/lang/Object;)V
public fun toString ()Ljava/lang/String;
}
public final class space/kscience/attributes/AttributesBuilderKt {
public static final fun Attributes (Lkotlin/jvm/functions/Function1;)Lspace/kscience/attributes/Attributes;
}
public final class space/kscience/attributes/AttributesKt {
public static final fun Attributes (Lspace/kscience/attributes/Attribute;)Lspace/kscience/attributes/Attributes;
public static final fun Attributes (Lspace/kscience/attributes/Attribute;Ljava/lang/Object;)Lspace/kscience/attributes/Attributes;
public static final fun getOrDefault (Lspace/kscience/attributes/Attributes;Lspace/kscience/attributes/AttributeWithDefault;)Ljava/lang/Object;
public static final fun isEmpty (Lspace/kscience/attributes/Attributes;)Z
public static final fun modified (Lspace/kscience/attributes/Attributes;Lkotlin/jvm/functions/Function1;)Lspace/kscience/attributes/Attributes;
public static final fun plus (Lspace/kscience/attributes/Attributes;Lspace/kscience/attributes/Attributes;)Lspace/kscience/attributes/Attributes;
public static final fun withAttribute (Lspace/kscience/attributes/Attributes;Lspace/kscience/attributes/Attribute;)Lspace/kscience/attributes/Attributes;
public static final fun withAttribute (Lspace/kscience/attributes/Attributes;Lspace/kscience/attributes/Attribute;Ljava/lang/Object;)Lspace/kscience/attributes/Attributes;
public static final fun withAttributeElement (Lspace/kscience/attributes/Attributes;Lspace/kscience/attributes/SetAttribute;Ljava/lang/Object;)Lspace/kscience/attributes/Attributes;
public static final fun withoutAttribute (Lspace/kscience/attributes/Attributes;Lspace/kscience/attributes/Attribute;)Lspace/kscience/attributes/Attributes;
public static final fun withoutAttributeElement (Lspace/kscience/attributes/Attributes;Lspace/kscience/attributes/SetAttribute;Ljava/lang/Object;)Lspace/kscience/attributes/Attributes;
}
public abstract interface class space/kscience/attributes/FlagAttribute : space/kscience/attributes/Attribute {
}
public abstract class space/kscience/attributes/PolymorphicAttribute : space/kscience/attributes/Attribute {
public synthetic fun <init> (Lkotlin/reflect/KType;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun equals (Ljava/lang/Object;)Z
public final fun getType-V0oMfBY ()Lkotlin/reflect/KType;
public fun hashCode ()I
}
public final class space/kscience/attributes/PolymorphicAttributeKt {
public static final fun get (Lspace/kscience/attributes/Attributes;Lkotlin/jvm/functions/Function0;)Ljava/lang/Object;
public static final fun set (Lspace/kscience/attributes/AttributesBuilder;Lkotlin/jvm/functions/Function0;Ljava/lang/Object;)V
}
public final class space/kscience/attributes/SafeType {
public static final synthetic fun box-impl (Lkotlin/reflect/KType;)Lspace/kscience/attributes/SafeType;
public static fun constructor-impl (Lkotlin/reflect/KType;)Lkotlin/reflect/KType;
public fun equals (Ljava/lang/Object;)Z
public static fun equals-impl (Lkotlin/reflect/KType;Ljava/lang/Object;)Z
public static final fun equals-impl0 (Lkotlin/reflect/KType;Lkotlin/reflect/KType;)Z
public final fun getKType ()Lkotlin/reflect/KType;
public fun hashCode ()I
public static fun hashCode-impl (Lkotlin/reflect/KType;)I
public fun toString ()Ljava/lang/String;
public static fun toString-impl (Lkotlin/reflect/KType;)Ljava/lang/String;
public final synthetic fun unbox-impl ()Lkotlin/reflect/KType;
}
public final class space/kscience/attributes/SafeTypeKt {
public static final fun getKClass-X0YbwmU (Lkotlin/reflect/KType;)Lkotlin/reflect/KClass;
}
public abstract interface class space/kscience/attributes/SetAttribute : space/kscience/attributes/Attribute {
}
public abstract interface annotation class space/kscience/attributes/UnstableAttributesAPI : java/lang/annotation/Annotation {
}
public abstract interface class space/kscience/attributes/WithType {
public abstract fun getType-V0oMfBY ()Lkotlin/reflect/KType;
}

View File

@ -0,0 +1,20 @@
plugins {
id("space.kscience.gradle.mpp")
`maven-publish`
}
version = rootProject.extra.get("attributesVersion").toString()
kscience {
jvm()
js()
native()
wasm()
}
readme {
maturity = space.kscience.gradle.Maturity.DEVELOPMENT
description = """
An API and basic implementation for arranging objects in a continuous memory block.
""".trimIndent()
}

View File

@ -0,0 +1,29 @@
/*
* Copyright 2018-2023 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package space.kscience.attributes
/**
* A marker interface for an attribute. Attributes are used as keys to access contents of type [T] in the container.
*/
public interface Attribute<T>
/**
* An attribute that could be either present or absent
*/
public interface FlagAttribute : Attribute<Unit>
/**
* An attribute with a default value
*/
public interface AttributeWithDefault<T> : Attribute<T> {
public val default: T
}
/**
* Attribute containing a set of values
*/
public interface SetAttribute<V> : Attribute<Set<V>>

View File

@ -0,0 +1,20 @@
/*
* Copyright 2018-2023 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package space.kscience.attributes
/**
* A container for [Attributes]
*/
public interface AttributeContainer {
public val attributes: Attributes
}
/**
* A scope, where attribute keys could be resolved.
* [O] is used only to resolve types in compile-time.
*/
public interface AttributeScope<O>

View File

@ -0,0 +1,157 @@
/*
* Copyright 2018-2023 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package space.kscience.attributes
/**
* A set of attributes. The implementation must guarantee that [content] keys correspond to their value types.
*/
public interface Attributes {
/**
* Raw content for this [Attributes]
*/
public val content: Map<out Attribute<*>, Any?>
/**
* Attribute keys contained in this [Attributes]
*/
public val keys: Set<Attribute<*>> get() = content.keys
/**
* Provide an attribute value. Return null if attribute is not present or if its value is null.
*/
@Suppress("UNCHECKED_CAST")
public operator fun <T> get(attribute: Attribute<T>): T? = content[attribute] as? T
override fun toString(): String
override fun equals(other: Any?): Boolean
override fun hashCode(): Int
public companion object {
public val EMPTY: Attributes = object : Attributes {
override val content: Map<out Attribute<*>, Any?> get() = emptyMap()
override fun toString(): String = "Attributes.EMPTY"
override fun equals(other: Any?): Boolean = (other as? Attributes)?.isEmpty() ?: false
override fun hashCode(): Int = Unit.hashCode()
}
public fun equals(a1: Attributes, a2: Attributes): Boolean =
a1.keys == a2.keys && a1.keys.all { a1[it] == a2[it] }
}
}
internal class MapAttributes(override val content: Map<out Attribute<*>, Any?>) : Attributes {
override fun toString(): String = "Attributes(value=${content.entries})"
override fun equals(other: Any?): Boolean = other is Attributes && Attributes.equals(this, other)
override fun hashCode(): Int = content.hashCode()
}
public fun Attributes.isEmpty(): Boolean = keys.isEmpty()
/**
* Get attribute value or default
*/
public fun <T> Attributes.getOrDefault(attribute: AttributeWithDefault<T>): T = get(attribute) ?: attribute.default
/**
* Check if there is an attribute that matches given key by type and adheres to [predicate].
*/
@Suppress("UNCHECKED_CAST")
public inline fun <T, reified A : Attribute<T>> Attributes.hasAny(predicate: (value: T) -> Boolean): Boolean =
content.any { (mapKey, mapValue) -> mapKey is A && predicate(mapValue as T) }
/**
* Check if there is an attribute of given type (subtypes included)
*/
public inline fun <reified A : Attribute<*>> Attributes.hasAny(): Boolean =
content.any { (mapKey, _) -> mapKey is A }
/**
* Check if [Attributes] contains a flag. Multiple keys that are instances of a flag could be present
*/
public inline fun <reified A : FlagAttribute> Attributes.hasFlag(): Boolean =
content.keys.any { it is A }
/**
* Create [Attributes] with an added or replaced attribute key.
*/
public fun <T, A : Attribute<T>> Attributes.withAttribute(
attribute: A,
attrValue: T,
): Attributes = MapAttributes(content + (attribute to attrValue))
public fun <A : Attribute<Unit>> Attributes.withAttribute(attribute: A): Attributes =
withAttribute(attribute, Unit)
/**
* Create a new [Attributes] by modifying the current one
*/
public fun <O> Attributes.modified(block: AttributesBuilder<O>.() -> Unit): Attributes = Attributes<O> {
putAll(this@modified)
block()
}
/**
* Create new [Attributes] by removing [attribute] key
*/
public fun Attributes.withoutAttribute(attribute: Attribute<*>): Attributes = MapAttributes(content.minus(attribute))
/**
* Add an element to a [SetAttribute]
*/
public fun <T, A : SetAttribute<T>> Attributes.withAttributeElement(
attribute: A,
attrValue: T,
): Attributes {
val currentSet: Set<T> = get(attribute) ?: emptySet()
return MapAttributes(
content + (attribute to (currentSet + attrValue))
)
}
/**
* Remove an element from [SetAttribute]
*/
public fun <T, A : SetAttribute<T>> Attributes.withoutAttributeElement(
attribute: A,
attrValue: T,
): Attributes {
val currentSet: Set<T> = get(attribute) ?: emptySet()
return MapAttributes(content + (attribute to (currentSet - attrValue)))
}
/**
* Create [Attributes] with a single key
*/
public fun <T, A : Attribute<T>> Attributes(
attribute: A,
attrValue: T,
): Attributes = MapAttributes(mapOf(attribute to attrValue))
/**
* Create Attributes with a single [Unit] valued attribute
*/
public fun <A : Attribute<Unit>> Attributes(
attribute: A,
): Attributes = MapAttributes(mapOf(attribute to Unit))
/**
* Create a new [Attributes] that overlays [other] on top of this set of attributes. New attributes are added.
* Existing attribute keys are replaced.
*/
public operator fun Attributes.plus(other: Attributes): Attributes = when {
isEmpty() -> other
other.isEmpty() -> this
else -> MapAttributes(content + other.content)
}
/**
* Create a new [Attributes] with removed [key] (if it is present).
*/
public operator fun Attributes.minus(key: Attribute<*>): Attributes =
if (content.contains(key)) MapAttributes(content.minus(key)) else this

View File

@ -0,0 +1,68 @@
/*
* Copyright 2018-2023 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package space.kscience.attributes
/**
* A builder for [Attributes].
* The builder is not thread safe
*
* @param O type marker of an owner object, for which these attributes are made
*/
public class AttributesBuilder<out O> internal constructor() : Attributes {
private val map = mutableMapOf<Attribute<*>, Any?>()
override fun toString(): String = "Attributes(value=${map.entries})"
override fun equals(other: Any?): Boolean = other is Attributes && Attributes.equals(this, other)
override fun hashCode(): Int = map.hashCode()
override val content: Map<out Attribute<*>, Any?> get() = map
public operator fun <T> set(attribute: Attribute<T>, value: T?) {
if (value == null) {
map.remove(attribute)
} else {
map[attribute] = value
}
}
public operator fun <V> Attribute<V>.invoke(value: V?) {
set(this, value)
}
public infix fun <V> Attribute<V>.put(value: V?) {
set(this, value)
}
/**
* Put all attributes for given [attributes]
*/
public fun putAll(attributes: Attributes) {
map.putAll(attributes.content)
}
public infix fun <V> SetAttribute<V>.add(attrValue: V) {
val currentSet: Set<V> = get(this) ?: emptySet()
map[this] = currentSet + attrValue
}
/**
* Remove an element from [SetAttribute]
*/
public infix fun <V> SetAttribute<V>.remove(attrValue: V) {
val currentSet: Set<V> = get(this) ?: emptySet()
map[this] = currentSet - attrValue
}
public fun build(): Attributes = MapAttributes(map)
}
/**
* Create [Attributes] with a given [builder]
* @param O the type for which attributes are built. The type is used only during compilation phase for static extension dispatch
*/
public fun <O> Attributes(builder: AttributesBuilder<O>.() -> Unit): Attributes =
AttributesBuilder<O>().apply(builder).build()

View File

@ -0,0 +1,34 @@
/*
* Copyright 2018-2023 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package space.kscience.attributes
/**
* An attribute that has a type parameter for value
* @param type parameter-type
*/
public abstract class PolymorphicAttribute<T>(public val type: SafeType<T>) : Attribute<T> {
override fun equals(other: Any?): Boolean = other != null &&
(this::class == other::class) &&
(other as? PolymorphicAttribute<*>)?.type == this.type
override fun hashCode(): Int = this::class.hashCode() + type.hashCode()
}
/**
* Get a polymorphic attribute using attribute factory
*/
@UnstableAttributesAPI
public operator fun <T> Attributes.get(attributeKeyBuilder: () -> PolymorphicAttribute<T>): T? =
get(attributeKeyBuilder())
/**
* Set a polymorphic attribute using its factory
*/
@UnstableAttributesAPI
public operator fun <O, T> AttributesBuilder<O>.set(attributeKeyBuilder: () -> PolymorphicAttribute<T>, value: T) {
set(attributeKeyBuilder(), value)
}

View File

@ -0,0 +1,35 @@
/*
* Copyright 2018-2023 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package space.kscience.attributes
import kotlin.jvm.JvmInline
import kotlin.reflect.KClass
import kotlin.reflect.KType
import kotlin.reflect.typeOf
/**
* Safe variant ok Kotlin [KType] that ensures that the type parameter is of the same type as [kType]
*
* @param kType raw [KType]
*/
@JvmInline
public value class SafeType<out T> @PublishedApi internal constructor(public val kType: KType)
public inline fun <reified T> safeTypeOf(): SafeType<T> = SafeType(typeOf<T>())
/**
* Derive Kotlin [KClass] from this type and fail if the type is not a class (should not happen)
*/
@Suppress("UNCHECKED_CAST")
@UnstableAttributesAPI
public val <T> SafeType<T>.kClass: KClass<T & Any> get() = kType.classifier as KClass<T & Any>
/**
* An interface containing [type] for dynamic type checking.
*/
public interface WithType<out T> {
public val type: SafeType<T>
}

View File

@ -0,0 +1,17 @@
/*
* Copyright 2018-2023 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package space.kscience.attributes
/**
* Marks declarations that are still experimental in the Attributes-kt APIs, which means that the design of the corresponding
* declarations has open issues that may (or may not) lead to their changes in the future. Roughly speaking, there is
* a chance of those declarations will be deprecated in the future or the semantics of their behavior may change
* in some way that may break some code.
*/
@MustBeDocumented
@Retention(value = AnnotationRetention.BINARY)
@RequiresOptIn("This API is unstable and could change in future", RequiresOptIn.Level.WARNING)
public annotation class UnstableAttributesAPI

119
benchmarks/README.md Normal file
View File

@ -0,0 +1,119 @@
# BenchmarksResult
## Report for benchmark configuration <code>main</code>
* Run on Java HotSpot(TM) 64-Bit Server VM (build 21.0.4+8-LTS-jvmci-23.1-b41) with Java process:
```
C:\Users\altavir\scoop\apps\graalvm-oracle-21jdk\current\bin\java.exe -XX:ThreadPriorityPolicy=1 -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCIProduct -XX:-UnlockExperimentalVMOptions -Dfile.encoding=UTF-8 -Duser.country=US -Duser.language=en -Duser.variant
```
* JMH 1.21 was used in `thrpt` mode with 5 warmup iterations by 10 s and 5 measurement iterations by 10 s.
### [ArrayBenchmark](src/jvmMain/kotlin/space/kscience/kmath/benchmarks/ArrayBenchmark.kt)
| Benchmark | Score |
|:---------:|:-----:|
|`benchmarkArrayRead`|1.9E+07 &plusmn; 2.3E+05 ops/s|
|`benchmarkBufferRead`|1.4E+07 &plusmn; 8.7E+05 ops/s|
|`nativeBufferRead`|1.4E+07 &plusmn; 1.3E+06 ops/s|
### [BigIntBenchmark](src/jvmMain/kotlin/space/kscience/kmath/benchmarks/BigIntBenchmark.kt)
| Benchmark | Score |
|:---------:|:-----:|
|`jvmAdd`|5.1E+07 &plusmn; 1.3E+06 ops/s|
|`jvmAddLarge`|5.1E+04 &plusmn; 8.2E+02 ops/s|
|`jvmMultiply`|8.5E+07 &plusmn; 9.7E+06 ops/s|
|`jvmMultiplyLarge`|2.5E+02 &plusmn; 15 ops/s|
|`jvmParsing10`|8.7E+06 &plusmn; 5.1E+05 ops/s|
|`jvmParsing16`|6.4E+06 &plusmn; 1.8E+05 ops/s|
|`jvmPower`|28 &plusmn; 0.79 ops/s|
|`jvmSmallAdd`|7.0E+07 &plusmn; 4.3E+06 ops/s|
|`kmAdd`|4.8E+07 &plusmn; 2.2E+06 ops/s|
|`kmAddLarge`|3.5E+04 &plusmn; 3.7E+03 ops/s|
|`kmMultiply`|6.7E+07 &plusmn; 1.5E+07 ops/s|
|`kmMultiplyLarge`|54 &plusmn; 4.2 ops/s|
|`kmParsing10`|4.5E+06 &plusmn; 8.3E+04 ops/s|
|`kmParsing16`|4.9E+06 &plusmn; 1.1E+05 ops/s|
|`kmPower`|10 &plusmn; 0.96 ops/s|
|`kmSmallAdd`|4.1E+07 &plusmn; 5.9E+05 ops/s|
### [BufferBenchmark](src/jvmMain/kotlin/space/kscience/kmath/benchmarks/BufferBenchmark.kt)
| Benchmark | Score |
|:---------:|:-----:|
|`bufferViewReadWrite`|5.8E+06 &plusmn; 1.6E+05 ops/s|
|`bufferViewReadWriteSpecialized`|5.6E+06 &plusmn; 2.6E+05 ops/s|
|`complexBufferReadWrite`|6.6E+06 &plusmn; 2.7E+05 ops/s|
|`doubleArrayReadWrite`|7.5E+06 &plusmn; 1.0E+06 ops/s|
|`doubleBufferReadWrite`|8.0E+06 &plusmn; 6.7E+05 ops/s|
### [DotBenchmark](src/jvmMain/kotlin/space/kscience/kmath/benchmarks/DotBenchmark.kt)
| Benchmark | Score |
|:---------:|:-----:|
|`bufferedDot`|1.3 &plusmn; 0.020 ops/s|
|`cmDot`|0.47 &plusmn; 0.42 ops/s|
|`cmDotWithConversion`|0.76 &plusmn; 0.13 ops/s|
|`ejmlDot`|6.7 &plusmn; 0.091 ops/s|
|`ejmlDotWithConversion`|6.4 &plusmn; 0.82 ops/s|
|`multikDot`|40 &plusmn; 6.7 ops/s|
|`parallelDot`|12 &plusmn; 1.8 ops/s|
|`tensorDot`|1.2 &plusmn; 0.041 ops/s|
|`tfDot`|5.9 &plusmn; 0.49 ops/s|
### [ExpressionsInterpretersBenchmark](src/jvmMain/kotlin/space/kscience/kmath/benchmarks/ExpressionsInterpretersBenchmark.kt)
| Benchmark | Score |
|:---------:|:-----:|
|`asmGenericExpression`|29 &plusmn; 1.2 ops/s|
|`asmPrimitiveExpression`|43 &plusmn; 1.3 ops/s|
|`asmPrimitiveExpressionArray`|71 &plusmn; 0.38 ops/s|
|`functionalExpression`|5.6 &plusmn; 0.11 ops/s|
|`justCalculate`|69 &plusmn; 9.0 ops/s|
|`mstExpression`|7.1 &plusmn; 0.020 ops/s|
|`rawExpression`|41 &plusmn; 1.5 ops/s|
### [IntegrationBenchmark](src/jvmMain/kotlin/space/kscience/kmath/benchmarks/IntegrationBenchmark.kt)
| Benchmark | Score |
|:---------:|:-----:|
|`complexIntegration`|3.6E+03 &plusmn; 1.9E+02 ops/s|
|`doubleIntegration`|3.7E+03 &plusmn; 12 ops/s|
### [JafamaBenchmark](src/jvmMain/kotlin/space/kscience/kmath/benchmarks/JafamaBenchmark.kt)
| Benchmark | Score |
|:---------:|:-----:|
|`core`|38 &plusmn; 0.64 ops/s|
|`jafama`|52 &plusmn; 0.36 ops/s|
|`strictJafama`|52 &plusmn; 4.0 ops/s|
### [MatrixInverseBenchmark](src/jvmMain/kotlin/space/kscience/kmath/benchmarks/MatrixInverseBenchmark.kt)
| Benchmark | Score |
|:---------:|:-----:|
|`cmLUPInversion`|2.2E+03 &plusmn; 76 ops/s|
|`ejmlInverse`|1.3E+03 &plusmn; 5.7 ops/s|
|`kmathLupInversion`|9.5E+02 &plusmn; 1.8E+02 ops/s|
|`kmathParallelLupInversion`|9.1E+02 &plusmn; 1.4E+02 ops/s|
### [NDFieldBenchmark](src/jvmMain/kotlin/space/kscience/kmath/benchmarks/NDFieldBenchmark.kt)
| Benchmark | Score |
|:---------:|:-----:|
|`boxingFieldAdd`|7.7 &plusmn; 0.79 ops/s|
|`multikAdd`|6.5 &plusmn; 0.33 ops/s|
|`multikInPlaceAdd`|64 &plusmn; 0.79 ops/s|
|`specializedFieldAdd`|8.0 &plusmn; 0.090 ops/s|
|`tensorAdd`|9.2 &plusmn; 0.053 ops/s|
|`tensorInPlaceAdd`|17 &plusmn; 10 ops/s|
|`viktorAdd`|7.6 &plusmn; 1.2 ops/s|
### [ViktorBenchmark](src/jvmMain/kotlin/space/kscience/kmath/benchmarks/ViktorBenchmark.kt)
| Benchmark | Score |
|:---------:|:-----:|
|`doubleFieldAddition`|7.7 &plusmn; 0.34 ops/s|
|`rawViktor`|5.9 &plusmn; 1.1 ops/s|
|`viktorFieldAddition`|7.3 &plusmn; 1.1 ops/s|
### [ViktorLogBenchmark](src/jvmMain/kotlin/space/kscience/kmath/benchmarks/ViktorLogBenchmark.kt)
| Benchmark | Score |
|:---------:|:-----:|
|`rawViktorLog`|1.4 &plusmn; 0.076 ops/s|
|`realFieldLog`|1.3 &plusmn; 0.069 ops/s|
|`viktorFieldLog`|1.3 &plusmn; 0.032 ops/s|

View File

@ -1,11 +1,14 @@
@file:Suppress("UNUSED_VARIABLE") import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import com.fasterxml.jackson.module.kotlin.readValue
import space.kscience.kmath.benchmarks.addBenchmarkProperties import kotlinx.benchmark.gradle.BenchmarksExtension
import java.time.LocalDateTime
import java.time.ZoneId
import java.util.*
plugins { plugins {
kotlin("multiplatform") kotlin("multiplatform")
kotlin("plugin.allopen") alias(spclibs.plugins.kotlin.plugin.allopen)
id("org.jetbrains.kotlinx.benchmark") alias(spclibs.plugins.kotlinx.benchmark)
} }
allOpen.annotation("org.openjdk.jmh.annotations.State") allOpen.annotation("org.openjdk.jmh.annotations.State")
@ -13,19 +16,25 @@ sourceSets.register("benchmarks")
repositories { repositories {
mavenCentral() mavenCentral()
maven("https://repo.kotlin.link")
maven("https://clojars.org/repo")
maven("https://jitpack.io")
maven("http://logicrunch.research.it.uu.se/maven") {
isAllowInsecureProtocol = true
}
} }
kotlin { kotlin {
jvm() jvm()
js(IR) {
nodejs()
}
sourceSets { sourceSets {
all {
languageSettings {
progressiveMode = true
optIn("kotlin.contracts.ExperimentalContracts")
optIn("kotlin.ExperimentalUnsignedTypes")
optIn("space.kscience.kmath.UnstableKMathAPI")
}
}
val commonMain by getting { val commonMain by getting {
dependencies { dependencies {
implementation(project(":kmath-ast")) implementation(project(":kmath-ast"))
@ -35,8 +44,10 @@ kotlin {
implementation(project(":kmath-stat")) implementation(project(":kmath-stat"))
implementation(project(":kmath-dimensions")) implementation(project(":kmath-dimensions"))
implementation(project(":kmath-for-real")) implementation(project(":kmath-for-real"))
implementation(project(":kmath-jafama")) implementation(project(":kmath-tensors"))
implementation("org.jetbrains.kotlinx:kotlinx-benchmark-runtime:0.3.1") implementation(project(":kmath-multik"))
implementation(libs.multik.default)
implementation(spclibs.kotlinx.benchmark.runtime)
} }
} }
@ -47,6 +58,9 @@ kotlin {
implementation(project(":kmath-nd4j")) implementation(project(":kmath-nd4j"))
implementation(project(":kmath-kotlingrad")) implementation(project(":kmath-kotlingrad"))
implementation(project(":kmath-viktor")) implementation(project(":kmath-viktor"))
implementation(project(":kmath-jafama"))
implementation(projects.kmath.kmathTensorflow)
implementation("org.tensorflow:tensorflow-core-platform:0.4.0")
implementation("org.nd4j:nd4j-native:1.0.0-M1") implementation("org.nd4j:nd4j-native:1.0.0-M1")
// uncomment if your system supports AVX2 // uncomment if your system supports AVX2
// val os = System.getProperty("os.name") // val os = System.getProperty("os.name")
@ -67,12 +81,13 @@ benchmark {
// Setup configurations // Setup configurations
targets { targets {
register("jvm") register("jvm")
register("js")
} }
fun kotlinx.benchmark.gradle.BenchmarkConfiguration.commonConfiguration() { fun kotlinx.benchmark.gradle.BenchmarkConfiguration.commonConfiguration() {
warmups = 1 warmups = 2
iterations = 5 iterations = 5
iterationTime = 1000 iterationTime = 2000
iterationTimeUnit = "ms" iterationTimeUnit = "ms"
} }
@ -81,13 +96,23 @@ benchmark {
include("BufferBenchmark") include("BufferBenchmark")
} }
configurations.register("nd") {
commonConfiguration()
include("NDFieldBenchmark")
}
configurations.register("dot") { configurations.register("dot") {
commonConfiguration() commonConfiguration()
include("DotBenchmark") include("DotBenchmark")
} }
configurations.register("expressions") { configurations.register("expressions") {
commonConfiguration() // Some extra precision
warmups = 2
iterations = 10
iterationTime = 10
iterationTimeUnit = "s"
outputTimeUnit = "s"
include("ExpressionsInterpretersBenchmark") include("ExpressionsInterpretersBenchmark")
} }
@ -105,34 +130,152 @@ benchmark {
commonConfiguration() commonConfiguration()
include("JafamaBenchmark") include("JafamaBenchmark")
} }
configurations.register("tensorAlgebra") {
commonConfiguration()
include("TensorAlgebraBenchmark")
}
configurations.register("viktor") {
commonConfiguration()
include("ViktorBenchmark")
}
configurations.register("viktorLog") {
commonConfiguration()
include("ViktorLogBenchmark")
}
configurations.register("integration") {
commonConfiguration()
include("IntegrationBenchmark")
}
} }
// Fix kotlinx-benchmarks bug kotlin {
afterEvaluate { jvmToolchain(11)
val jvmBenchmarkJar by tasks.getting(org.gradle.jvm.tasks.Jar::class) { compilerOptions {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE optIn.addAll(
"space.kscience.kmath.UnstableKMathAPI"
)
} }
} }
kotlin.sourceSets.all { private data class JmhReport(
with(languageSettings) { val jmhVersion: String,
useExperimentalAnnotation("kotlin.contracts.ExperimentalContracts") val benchmark: String,
useExperimentalAnnotation("kotlin.ExperimentalUnsignedTypes") val mode: String,
useExperimentalAnnotation("space.kscience.kmath.misc.UnstableKMathAPI") val threads: Int,
val forks: Int,
val jvm: String,
val jvmArgs: List<String>,
val jdkVersion: String,
val vmName: String,
val vmVersion: String,
val warmupIterations: Int,
val warmupTime: String,
val warmupBatchSize: Int,
val measurementIterations: Int,
val measurementTime: String,
val measurementBatchSize: Int,
val params: Map<String, String> = emptyMap(),
val primaryMetric: PrimaryMetric,
val secondaryMetrics: Map<String, SecondaryMetric>,
) {
interface Metric {
val score: Double
val scoreError: Double
val scoreConfidence: List<Double>
val scorePercentiles: Map<Double, Double>
val scoreUnit: String
} }
}
tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> { data class PrimaryMetric(
kotlinOptions { override val score: Double,
jvmTarget = "11" override val scoreError: Double,
freeCompilerArgs = freeCompilerArgs + "-Xjvm-default=all" override val scoreConfidence: List<Double>,
} override val scorePercentiles: Map<Double, Double>,
} override val scoreUnit: String,
val rawDataHistogram: List<List<List<List<Double>>>>? = null,
val rawData: List<List<Double>>? = null,
) : Metric
data class SecondaryMetric(
override val score: Double,
override val scoreError: Double,
override val scoreConfidence: List<Double>,
override val scorePercentiles: Map<Double, Double>,
override val scoreUnit: String,
val rawData: List<List<Double>>,
) : Metric
}
readme { readme {
maturity = ru.mipt.npm.gradle.Maturity.EXPERIMENTAL maturity = space.kscience.gradle.Maturity.EXPERIMENTAL
}
addBenchmarkProperties() val jsonMapper = jacksonObjectMapper()
fun noun(number: Number, singular: String, plural: String) = if (number.toLong() == 1L) singular else plural
extensions.findByType(BenchmarksExtension::class.java)?.configurations?.forEach { cfg ->
val propertyName =
"benchmark${cfg.name.replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() }}"
logger.info("Processing benchmark data from benchmark ${cfg.name} into readme property $propertyName")
val launches = layout.buildDirectory.dir("reports/benchmarks/${cfg.name}").get().asFile
if (!launches.exists()) return@forEach
property(propertyName) {
val resDirectory = launches.listFiles()?.maxByOrNull {
LocalDateTime.parse(it.name).atZone(ZoneId.systemDefault()).toInstant()
}
if (resDirectory == null || !(resDirectory.resolve("jvm.json")).exists()) {
"> **Can't find appropriate benchmark data. Try generating readme files after running benchmarks**."
} else {
val reports: List<JmhReport> =
jsonMapper.readValue<List<JmhReport>>(resDirectory.resolve("jvm.json"))
buildString {
appendLine("## Report for benchmark configuration <code>${cfg.name}</code>")
appendLine()
val first = reports.first()
appendLine("* Run on ${first.vmName} (build ${first.vmVersion}) with Java process:")
appendLine()
appendLine("```")
appendLine(
"${first.jvm} ${
first.jvmArgs.joinToString(" ")
}"
)
appendLine("```")
appendLine(
"* JMH ${first.jmhVersion} was used in `${first.mode}` mode with ${first.warmupIterations} warmup ${
noun(first.warmupIterations, "iteration", "iterations")
} by ${first.warmupTime} and ${first.measurementIterations} measurement ${
noun(first.measurementIterations, "iteration", "iterations")
} by ${first.measurementTime}."
)
reports.groupBy { it.benchmark.substringBeforeLast(".") }.forEach { (cl, compare) ->
appendLine("### [${cl.substringAfterLast(".")}](src/jvmMain/kotlin/${cl.replace(".","/")}.kt)")
appendLine()
appendLine("| Benchmark | Score |")
appendLine("|:---------:|:-----:|")
compare.forEach { report ->
val benchmarkName = report.benchmark.substringAfterLast(".")
val score = String.format("%.2G", report.primaryMetric.score)
val error = String.format("%.2G", report.primaryMetric.scoreError)
appendLine("|`$benchmarkName`|$score &plusmn; $error ${report.primaryMetric.scoreUnit}|")
}
}
}
}
}
}
}

View File

@ -0,0 +1,5 @@
# BenchmarksResult
${benchmarkMain}

View File

@ -0,0 +1,108 @@
/*
* Copyright 2018-2024 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package space.kscience.kmath.benchmarks
import kotlinx.benchmark.Benchmark
import kotlinx.benchmark.Blackhole
import kotlinx.benchmark.Scope
import kotlinx.benchmark.State
import space.kscience.kmath.UnstableKMathAPI
import space.kscience.kmath.expressions.*
import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.operations.bindSymbol
import space.kscience.kmath.operations.invoke
import space.kscience.kmath.structures.Float64
import kotlin.math.sin
import kotlin.random.Random
import space.kscience.kmath.estree.compileToExpression as estreeCompileToExpression
import space.kscience.kmath.wasm.compileToExpression as wasmCompileToExpression
@State(Scope.Benchmark)
class ExpressionsInterpretersBenchmark {
/**
* Benchmark case for [Expression] created with [expressionInExtendedField].
*/
@Benchmark
fun functionalExpression(blackhole: Blackhole) = invokeAndSum(functional, blackhole)
/**
* Benchmark case for [Expression] created with [toExpression].
*/
@Benchmark
fun mstExpression(blackhole: Blackhole) = invokeAndSum(mst, blackhole)
/**
* Benchmark case for [Expression] created with [compileToExpression].
*/
@Benchmark
fun wasmExpression(blackhole: Blackhole) = invokeAndSum(wasm, blackhole)
/**
* Benchmark case for [Expression] created with [compileToExpression].
*/
@Benchmark
fun estreeExpression(blackhole: Blackhole) = invokeAndSum(estree, blackhole)
/**
* Benchmark case for [Expression] implemented manually with `kotlin.math` functions.
*/
@Benchmark
fun rawExpression(blackhole: Blackhole) = invokeAndSum(raw, blackhole)
/**
* Benchmark case for direct computation w/o [Expression].
*/
@Benchmark
fun justCalculate(blackhole: Blackhole) {
val random = Random(0)
var sum = 0.0
repeat(times) {
val x = random.nextDouble()
sum += x * 2.0 + 2.0 / x - 16.0 / sin(x)
}
blackhole.consume(sum)
}
private fun invokeAndSum(expr: Expression<Float64>, blackhole: Blackhole) {
val random = Random(0)
var sum = 0.0
val m = HashMap<Symbol, Double>()
repeat(times) {
m[x] = random.nextDouble()
sum += expr(m)
}
blackhole.consume(sum)
}
private companion object {
private val x by symbol
private const val times = 1_000_000
private val functional = Float64Field.expression {
val x = bindSymbol(Symbol.x)
x * number(2.0) + 2.0 / x - 16.0 / sin(x)
}
private val node = MstExtendedField {
x * 2.0 + number(2.0) / x - number(16.0) / sin(x)
}
private val mst = node.toExpression(Float64Field)
@OptIn(UnstableKMathAPI::class)
private val wasm = node.wasmCompileToExpression(Float64Field)
private val estree = node.estreeCompileToExpression(Float64Field)
private val raw = Expression<Float64> { args ->
val x = args.getValue(x)
x * 2.0 + 2.0 / x - 16.0 / sin(x)
}
}
}

View File

@ -1,6 +1,6 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2024 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
package space.kscience.kmath.benchmarks package space.kscience.kmath.benchmarks

View File

@ -1,6 +1,6 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2024 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
package space.kscience.kmath.benchmarks package space.kscience.kmath.benchmarks
@ -10,8 +10,11 @@ import kotlinx.benchmark.Blackhole
import org.openjdk.jmh.annotations.Benchmark import org.openjdk.jmh.annotations.Benchmark
import org.openjdk.jmh.annotations.Scope import org.openjdk.jmh.annotations.Scope
import org.openjdk.jmh.annotations.State import org.openjdk.jmh.annotations.State
import space.kscience.kmath.misc.UnstableKMathAPI import space.kscience.kmath.UnstableKMathAPI
import space.kscience.kmath.operations.* import space.kscience.kmath.operations.BigIntField
import space.kscience.kmath.operations.JBigIntegerField
import space.kscience.kmath.operations.invoke
import space.kscience.kmath.operations.parseBigInteger
import java.math.BigInteger import java.math.BigInteger
@ -19,12 +22,24 @@ import java.math.BigInteger
@State(Scope.Benchmark) @State(Scope.Benchmark)
internal class BigIntBenchmark { internal class BigIntBenchmark {
val kmSmallNumber = BigIntField.number(100)
val jvmSmallNumber = JBigIntegerField.number(100)
val kmNumber = BigIntField.number(Int.MAX_VALUE) val kmNumber = BigIntField.number(Int.MAX_VALUE)
val jvmNumber = JBigIntegerField.number(Int.MAX_VALUE) val jvmNumber = JBigIntegerField.number(Int.MAX_VALUE)
val largeKmNumber = BigIntField { number(11).pow(100_000U) } val kmLargeNumber = BigIntField { number(11).pow(100_000U) }
val largeJvmNumber: BigInteger = JBigIntegerField { number(11).pow(100_000) } val jvmLargeNumber: BigInteger = JBigIntegerField { number(11).pow(100_000) }
val bigExponent = 50_000 val bigExponent = 50_000
@Benchmark
fun kmSmallAdd(blackhole: Blackhole) = BigIntField {
blackhole.consume(kmSmallNumber + kmSmallNumber + kmSmallNumber)
}
@Benchmark
fun jvmSmallAdd(blackhole: Blackhole) = JBigIntegerField {
blackhole.consume(jvmSmallNumber + jvmSmallNumber + jvmSmallNumber)
}
@Benchmark @Benchmark
fun kmAdd(blackhole: Blackhole) = BigIntField { fun kmAdd(blackhole: Blackhole) = BigIntField {
blackhole.consume(kmNumber + kmNumber + kmNumber) blackhole.consume(kmNumber + kmNumber + kmNumber)
@ -37,12 +52,12 @@ internal class BigIntBenchmark {
@Benchmark @Benchmark
fun kmAddLarge(blackhole: Blackhole) = BigIntField { fun kmAddLarge(blackhole: Blackhole) = BigIntField {
blackhole.consume(largeKmNumber + largeKmNumber + largeKmNumber) blackhole.consume(kmLargeNumber + kmLargeNumber + kmLargeNumber)
} }
@Benchmark @Benchmark
fun jvmAddLarge(blackhole: Blackhole) = JBigIntegerField { fun jvmAddLarge(blackhole: Blackhole) = JBigIntegerField {
blackhole.consume(largeJvmNumber + largeJvmNumber + largeJvmNumber) blackhole.consume(jvmLargeNumber + jvmLargeNumber + jvmLargeNumber)
} }
@Benchmark @Benchmark
@ -52,7 +67,7 @@ internal class BigIntBenchmark {
@Benchmark @Benchmark
fun kmMultiplyLarge(blackhole: Blackhole) = BigIntField { fun kmMultiplyLarge(blackhole: Blackhole) = BigIntField {
blackhole.consume(largeKmNumber*largeKmNumber) blackhole.consume(kmLargeNumber * kmLargeNumber)
} }
@Benchmark @Benchmark
@ -62,7 +77,7 @@ internal class BigIntBenchmark {
@Benchmark @Benchmark
fun jvmMultiplyLarge(blackhole: Blackhole) = JBigIntegerField { fun jvmMultiplyLarge(blackhole: Blackhole) = JBigIntegerField {
blackhole.consume(largeJvmNumber*largeJvmNumber) blackhole.consume(jvmLargeNumber * jvmLargeNumber)
} }
@Benchmark @Benchmark

View File

@ -1,39 +1,80 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2024 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
package space.kscience.kmath.benchmarks package space.kscience.kmath.benchmarks
import kotlinx.benchmark.Benchmark import kotlinx.benchmark.Benchmark
import kotlinx.benchmark.Blackhole
import kotlinx.benchmark.Scope import kotlinx.benchmark.Scope
import kotlinx.benchmark.State import kotlinx.benchmark.State
import space.kscience.kmath.complex.Complex import space.kscience.kmath.complex.Complex
import space.kscience.kmath.complex.ComplexField
import space.kscience.kmath.complex.complex import space.kscience.kmath.complex.complex
import space.kscience.kmath.structures.DoubleBuffer import space.kscience.kmath.operations.invoke
import space.kscience.kmath.structures.MutableBuffer import space.kscience.kmath.structures.Buffer
import space.kscience.kmath.structures.Float64Buffer
import space.kscience.kmath.structures.getDouble
import space.kscience.kmath.structures.permute
@State(Scope.Benchmark) @State(Scope.Benchmark)
internal class BufferBenchmark { internal class BufferBenchmark {
@Benchmark
fun genericDoubleBufferReadWrite() {
val buffer = DoubleBuffer(size) { it.toDouble() }
@Benchmark
fun doubleArrayReadWrite(blackhole: Blackhole) {
val buffer = DoubleArray(size) { it.toDouble() }
var res = 0.0
(0 until size).forEach { (0 until size).forEach {
buffer[it] res += buffer[it]
} }
blackhole.consume(res)
} }
@Benchmark @Benchmark
fun complexBufferReadWrite() { fun doubleBufferReadWrite(blackhole: Blackhole) {
val buffer = MutableBuffer.complex(size / 2) { Complex(it.toDouble(), -it.toDouble()) } val buffer = Float64Buffer(size) { it.toDouble() }
var res = 0.0
(0 until size / 2).forEach { (0 until size).forEach {
buffer[it] res += buffer[it]
} }
blackhole.consume(res)
}
@Benchmark
fun bufferViewReadWrite(blackhole: Blackhole) {
val buffer = Float64Buffer(size) { it.toDouble() }.permute(reversedIndices)
var res = 0.0
(0 until size).forEach {
res += buffer[it]
}
blackhole.consume(res)
}
@Benchmark
fun bufferViewReadWriteSpecialized(blackhole: Blackhole) {
val buffer = Float64Buffer(size) { it.toDouble() }.permute(reversedIndices)
var res = 0.0
(0 until size).forEach {
res += buffer.getDouble(it)
}
blackhole.consume(res)
}
@Benchmark
fun complexBufferReadWrite(blackhole: Blackhole) = ComplexField {
val buffer = Buffer.complex(size / 2) { Complex(it.toDouble(), -it.toDouble()) }
var res = zero
(0 until size / 2).forEach {
res += buffer[it]
}
blackhole.consume(res)
} }
private companion object { private companion object {
private const val size = 100 private const val size = 100
private val reversedIndices = IntArray(size) { it }.apply { reverse() }
} }
} }

View File

@ -1,6 +1,6 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2024 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
package space.kscience.kmath.benchmarks package space.kscience.kmath.benchmarks
@ -11,9 +11,12 @@ import kotlinx.benchmark.Scope
import kotlinx.benchmark.State import kotlinx.benchmark.State
import space.kscience.kmath.commons.linear.CMLinearSpace import space.kscience.kmath.commons.linear.CMLinearSpace
import space.kscience.kmath.ejml.EjmlLinearSpaceDDRM import space.kscience.kmath.ejml.EjmlLinearSpaceDDRM
import space.kscience.kmath.linear.LinearSpace import space.kscience.kmath.linear.Float64ParallelLinearSpace
import space.kscience.kmath.linear.invoke import space.kscience.kmath.linear.invoke
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.linear.linearSpace
import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.tensorflow.produceWithTF
import space.kscience.kmath.tensors.core.tensorAlgebra
import kotlin.random.Random import kotlin.random.Random
@State(Scope.Benchmark) @State(Scope.Benchmark)
@ -23,8 +26,12 @@ internal class DotBenchmark {
const val dim = 1000 const val dim = 1000
//creating invertible matrix //creating invertible matrix
val matrix1 = LinearSpace.real.buildMatrix(dim, dim) { i, j -> if (i <= j) random.nextDouble() else 0.0 } val matrix1 = Float64Field.linearSpace.buildMatrix(dim, dim) { _, _ ->
val matrix2 = LinearSpace.real.buildMatrix(dim, dim) { i, j -> if (i <= j) random.nextDouble() else 0.0 } random.nextDouble()
}
val matrix2 = Float64Field.linearSpace.buildMatrix(dim, dim) { _, _ ->
random.nextDouble()
}
val cmMatrix1 = CMLinearSpace { matrix1.toCM() } val cmMatrix1 = CMLinearSpace { matrix1.toCM() }
val cmMatrix2 = CMLinearSpace { matrix2.toCM() } val cmMatrix2 = CMLinearSpace { matrix2.toCM() }
@ -33,38 +40,54 @@ internal class DotBenchmark {
val ejmlMatrix2 = EjmlLinearSpaceDDRM { matrix2.toEjml() } val ejmlMatrix2 = EjmlLinearSpaceDDRM { matrix2.toEjml() }
} }
@Benchmark @Benchmark
fun cmDot(blackhole: Blackhole) { fun tfDot(blackhole: Blackhole) {
CMLinearSpace.run { blackhole.consume(
Float64Field.produceWithTF {
matrix1 dot matrix1
}
)
}
@Benchmark
fun cmDotWithConversion(blackhole: Blackhole) = CMLinearSpace {
blackhole.consume(matrix1 dot matrix2)
}
@Benchmark
fun cmDot(blackhole: Blackhole) = CMLinearSpace {
blackhole.consume(cmMatrix1 dot cmMatrix2) blackhole.consume(cmMatrix1 dot cmMatrix2)
} }
}
@Benchmark @Benchmark
fun ejmlDot(blackhole: Blackhole) { fun ejmlDot(blackhole: Blackhole) = EjmlLinearSpaceDDRM {
EjmlLinearSpaceDDRM {
blackhole.consume(ejmlMatrix1 dot ejmlMatrix2) blackhole.consume(ejmlMatrix1 dot ejmlMatrix2)
} }
@Benchmark
fun ejmlDotWithConversion(blackhole: Blackhole) = EjmlLinearSpaceDDRM {
blackhole.consume(matrix1 dot matrix2)
} }
@Benchmark @Benchmark
fun ejmlDotWithConversion(blackhole: Blackhole) { fun multikDot(blackhole: Blackhole) = with(multikAlgebra) {
EjmlLinearSpaceDDRM {
blackhole.consume(matrix1 dot matrix2) blackhole.consume(matrix1 dot matrix2)
} }
}
@Benchmark @Benchmark
fun bufferedDot(blackhole: Blackhole) { fun tensorDot(blackhole: Blackhole) = with(Float64Field.tensorAlgebra) {
LinearSpace.auto(DoubleField).invoke {
blackhole.consume(matrix1 dot matrix2) blackhole.consume(matrix1 dot matrix2)
} }
}
@Benchmark @Benchmark
fun realDot(blackhole: Blackhole) { fun bufferedDot(blackhole: Blackhole) = with(Float64Field.linearSpace) {
LinearSpace.real {
blackhole.consume(matrix1 dot matrix2) blackhole.consume(matrix1 dot matrix2)
} }
@Benchmark
fun parallelDot(blackhole: Blackhole) = with(Float64ParallelLinearSpace) {
blackhole.consume(matrix1 dot matrix2)
} }
} }

View File

@ -1,6 +1,6 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2024 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
package space.kscience.kmath.benchmarks package space.kscience.kmath.benchmarks
@ -11,9 +11,11 @@ import kotlinx.benchmark.Scope
import kotlinx.benchmark.State import kotlinx.benchmark.State
import space.kscience.kmath.asm.compileToExpression import space.kscience.kmath.asm.compileToExpression
import space.kscience.kmath.expressions.* import space.kscience.kmath.expressions.*
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Algebra
import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.operations.bindSymbol import space.kscience.kmath.operations.bindSymbol
import space.kscience.kmath.operations.invoke import space.kscience.kmath.operations.invoke
import space.kscience.kmath.structures.Float64
import kotlin.math.sin import kotlin.math.sin
import kotlin.random.Random import kotlin.random.Random
@ -35,7 +37,30 @@ internal class ExpressionsInterpretersBenchmark {
* Benchmark case for [Expression] created with [compileToExpression]. * Benchmark case for [Expression] created with [compileToExpression].
*/ */
@Benchmark @Benchmark
fun asmExpression(blackhole: Blackhole) = invokeAndSum(asm, blackhole) fun asmGenericExpression(blackhole: Blackhole) = invokeAndSum(asmGeneric, blackhole)
/**
* Benchmark case for [Expression] created with [compileToExpression].
*/
@Benchmark
fun asmPrimitiveExpressionArray(blackhole: Blackhole) {
val random = Random(0)
var sum = 0.0
val m = DoubleArray(1)
repeat(times) {
m[xIdx] = random.nextDouble()
sum += asmPrimitive(m)
}
blackhole.consume(sum)
}
/**
* Benchmark case for [Expression] created with [compileToExpression].
*/
@Benchmark
fun asmPrimitiveExpression(blackhole: Blackhole) = invokeAndSum(asmPrimitive, blackhole)
/** /**
* Benchmark case for [Expression] implemented manually with `kotlin.math` functions. * Benchmark case for [Expression] implemented manually with `kotlin.math` functions.
@ -59,12 +84,14 @@ internal class ExpressionsInterpretersBenchmark {
blackhole.consume(sum) blackhole.consume(sum)
} }
private fun invokeAndSum(expr: Expression<Double>, blackhole: Blackhole) { private fun invokeAndSum(expr: Expression<Float64>, blackhole: Blackhole) {
val random = Random(0) val random = Random(0)
var sum = 0.0 var sum = 0.0
val m = HashMap<Symbol, Double>()
repeat(times) { repeat(times) {
sum += expr(x to random.nextDouble()) m[x] = random.nextDouble()
sum += expr(m)
} }
blackhole.consume(sum) blackhole.consume(sum)
@ -72,21 +99,25 @@ internal class ExpressionsInterpretersBenchmark {
private companion object { private companion object {
private val x by symbol private val x by symbol
private val algebra = DoubleField
private const val times = 1_000_000 private const val times = 1_000_000
private val functional = DoubleField.expressionInExtendedField { private val functional = Float64Field.expression {
bindSymbol(x) * number(2.0) + number(2.0) / bindSymbol(x) - number(16.0) / sin(bindSymbol(x)) val x = bindSymbol(Symbol.x)
x * number(2.0) + 2.0 / x - 16.0 / sin(x)
} }
private val node = MstExtendedField { private val node = MstExtendedField {
x * 2.0 + number(2.0) / x - number(16.0) / sin(x) x * 2.0 + number(2.0) / x - number(16.0) / sin(x)
} }
private val mst = node.toExpression(DoubleField) private val mst = node.toExpression(Float64Field)
private val asm = node.compileToExpression(DoubleField)
private val raw = Expression<Double> { args -> private val asmPrimitive = node.compileToExpression(Float64Field)
private val xIdx = asmPrimitive.indexer.indexOf(x)
private val asmGeneric = node.compileToExpression(Float64Field as Algebra<Float64>)
private val raw = Expression<Float64> { args ->
val x = args[x]!! val x = args[x]!!
x * 2.0 + 2.0 / x - 16.0 / sin(x) x * 2.0 + 2.0 / x - 16.0 / sin(x)
} }

View File

@ -0,0 +1,40 @@
/*
* Copyright 2018-2024 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package space.kscience.kmath.benchmarks
import org.openjdk.jmh.annotations.Benchmark
import org.openjdk.jmh.annotations.Scope
import org.openjdk.jmh.annotations.State
import org.openjdk.jmh.infra.Blackhole
import space.kscience.kmath.complex.Complex
import space.kscience.kmath.complex.algebra
import space.kscience.kmath.integration.gaussIntegrator
import space.kscience.kmath.integration.integrate
import space.kscience.kmath.integration.value
import space.kscience.kmath.operations.algebra
@State(Scope.Benchmark)
internal class IntegrationBenchmark {
@Benchmark
fun doubleIntegration(blackhole: Blackhole) {
val res = Double.algebra.gaussIntegrator.integrate(0.0..1.0, intervals = 1000) { x: Double ->
//sin(1 / x)
1 / x
}.value
blackhole.consume(res)
}
@Benchmark
fun complexIntegration(blackhole: Blackhole) = with(Complex.algebra) {
val res = gaussIntegrator.integrate(0.0..1.0, intervals = 1000) { x: Double ->
// sin(1 / x) + i * cos(1 / x)
1 / x - i / x
}.value
blackhole.consume(res)
}
}

View File

@ -1,6 +1,6 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2024 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
package space.kscience.kmath.benchmarks package space.kscience.kmath.benchmarks
@ -11,10 +11,8 @@ import org.openjdk.jmh.annotations.Scope
import org.openjdk.jmh.annotations.State import org.openjdk.jmh.annotations.State
import space.kscience.kmath.jafama.JafamaDoubleField import space.kscience.kmath.jafama.JafamaDoubleField
import space.kscience.kmath.jafama.StrictJafamaDoubleField import space.kscience.kmath.jafama.StrictJafamaDoubleField
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.operations.invoke import space.kscience.kmath.operations.invoke
import kotlin.contracts.InvocationKind
import kotlin.contracts.contract
import kotlin.random.Random import kotlin.random.Random
@State(Scope.Benchmark) @State(Scope.Benchmark)
@ -26,7 +24,7 @@ internal class JafamaBenchmark {
@Benchmark @Benchmark
fun core(blackhole: Blackhole) = invokeBenchmarks(blackhole) { x -> fun core(blackhole: Blackhole) = invokeBenchmarks(blackhole) { x ->
DoubleField { x * power(x, 4) * exp(x) / cos(x) + sin(x) } Float64Field { x * power(x, 4) * exp(x) / cos(x) + sin(x) }
} }
@Benchmark @Benchmark
@ -36,7 +34,6 @@ internal class JafamaBenchmark {
} }
private inline fun invokeBenchmarks(blackhole: Blackhole, expr: (Double) -> Double) { private inline fun invokeBenchmarks(blackhole: Blackhole, expr: (Double) -> Double) {
contract { callsInPlace(expr, InvocationKind.AT_LEAST_ONCE) }
val rng = Random(0) val rng = Random(0)
repeat(1000000) { blackhole.consume(expr(rng.nextDouble())) } repeat(1000000) { blackhole.consume(expr(rng.nextDouble())) }
} }

View File

@ -1,6 +1,6 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2024 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
package space.kscience.kmath.benchmarks package space.kscience.kmath.benchmarks
@ -10,13 +10,13 @@ import kotlinx.benchmark.Blackhole
import kotlinx.benchmark.Scope import kotlinx.benchmark.Scope
import kotlinx.benchmark.State import kotlinx.benchmark.State
import space.kscience.kmath.commons.linear.CMLinearSpace import space.kscience.kmath.commons.linear.CMLinearSpace
import space.kscience.kmath.commons.linear.inverse import space.kscience.kmath.commons.linear.lupSolver
import space.kscience.kmath.ejml.EjmlLinearSpaceDDRM import space.kscience.kmath.ejml.EjmlLinearSpaceDDRM
import space.kscience.kmath.linear.InverseMatrixFeature
import space.kscience.kmath.linear.LinearSpace
import space.kscience.kmath.linear.inverseWithLup
import space.kscience.kmath.linear.invoke import space.kscience.kmath.linear.invoke
import space.kscience.kmath.nd.getFeature import space.kscience.kmath.linear.linearSpace
import space.kscience.kmath.linear.lupSolver
import space.kscience.kmath.linear.parallel
import space.kscience.kmath.operations.algebra
import kotlin.random.Random import kotlin.random.Random
@State(Scope.Benchmark) @State(Scope.Benchmark)
@ -25,7 +25,7 @@ internal class MatrixInverseBenchmark {
private val random = Random(1224) private val random = Random(1224)
private const val dim = 100 private const val dim = 100
private val space = LinearSpace.real private val space = Double.algebra.linearSpace
//creating invertible matrix //creating invertible matrix
private val u = space.buildMatrix(dim, dim) { i, j -> if (i <= j) random.nextDouble() else 0.0 } private val u = space.buildMatrix(dim, dim) { i, j -> if (i <= j) random.nextDouble() else 0.0 }
@ -35,20 +35,23 @@ internal class MatrixInverseBenchmark {
@Benchmark @Benchmark
fun kmathLupInversion(blackhole: Blackhole) { fun kmathLupInversion(blackhole: Blackhole) {
blackhole.consume(LinearSpace.real.inverseWithLup(matrix)) blackhole.consume(Double.algebra.linearSpace.lupSolver().inverse(matrix))
} }
@Benchmark @Benchmark
fun cmLUPInversion(blackhole: Blackhole) { fun kmathParallelLupInversion(blackhole: Blackhole) {
CMLinearSpace { blackhole.consume(Double.algebra.linearSpace.parallel.lupSolver().inverse(matrix))
blackhole.consume(inverse(matrix))
}
} }
@Benchmark @Benchmark
fun ejmlInverse(blackhole: Blackhole) { fun cmLUPInversion(blackhole: Blackhole) = CMLinearSpace {
EjmlLinearSpaceDDRM { blackhole.consume(lupSolver().inverse(matrix))
blackhole.consume(matrix.getFeature<InverseMatrixFeature<Double>>()?.inverse)
} }
@Benchmark
fun ejmlInverse(blackhole: Blackhole) = EjmlLinearSpaceDDRM {
blackhole.consume(matrix.toEjml().inverted())
} }
} }

View File

@ -1,6 +1,6 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2024 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
package space.kscience.kmath.benchmarks package space.kscience.kmath.benchmarks
@ -9,45 +9,89 @@ import kotlinx.benchmark.Benchmark
import kotlinx.benchmark.Blackhole import kotlinx.benchmark.Blackhole
import kotlinx.benchmark.Scope import kotlinx.benchmark.Scope
import kotlinx.benchmark.State import kotlinx.benchmark.State
import org.jetbrains.kotlinx.multik.api.Multik
import org.jetbrains.kotlinx.multik.api.ones
import org.jetbrains.kotlinx.multik.ndarray.data.DN
import org.jetbrains.kotlinx.multik.ndarray.data.DataType
import space.kscience.kmath.UnsafeKMathAPI
import space.kscience.kmath.nd.* import space.kscience.kmath.nd.*
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.nd4j.nd4j
import space.kscience.kmath.structures.Buffer import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.structures.Float64
import space.kscience.kmath.tensors.core.DoubleTensor
import space.kscience.kmath.tensors.core.one
import space.kscience.kmath.tensors.core.tensorAlgebra
import space.kscience.kmath.viktor.viktorAlgebra
@State(Scope.Benchmark) @State(Scope.Benchmark)
internal class NDFieldBenchmark { internal class NDFieldBenchmark {
@Benchmark
fun autoFieldAdd(blackhole: Blackhole) {
with(autoField) {
var res: StructureND<Double> = one
repeat(n) { res += one }
blackhole.consume(res)
}
}
@Benchmark
fun specializedFieldAdd(blackhole: Blackhole) {
with(specializedField) {
var res: StructureND<Double> = one
repeat(n) { res += 1.0 }
blackhole.consume(res)
}
}
@Benchmark
fun boxingFieldAdd(blackhole: Blackhole) {
with(genericField) {
var res: StructureND<Double> = one
repeat(n) { res += 1.0 }
blackhole.consume(res)
}
}
private companion object { private companion object {
private const val dim = 1000 private const val dim = 1000
private const val n = 100 private const val n = 100
private val autoField = AlgebraND.auto(DoubleField, dim, dim) private val shape = ShapeND(dim, dim)
private val specializedField = AlgebraND.real(dim, dim) private val specializedField = Float64Field.ndAlgebra
private val genericField = AlgebraND.field(DoubleField, Buffer.Companion::boxing, dim, dim) private val genericField = BufferedFieldOpsND(Float64Field)
private val nd4jField = Float64Field.nd4j
private val viktorField = Float64Field.viktorAlgebra
} }
@Benchmark
fun specializedFieldAdd(blackhole: Blackhole) = with(specializedField) {
var res: StructureND<Float64> = one(shape)
repeat(n) { res += 1.0 }
blackhole.consume(res)
}
@Benchmark
fun boxingFieldAdd(blackhole: Blackhole) = with(genericField) {
var res: StructureND<Float64> = one(shape)
repeat(n) { res += 1.0 }
blackhole.consume(res)
}
@Benchmark
fun multikAdd(blackhole: Blackhole) = with(multikAlgebra) {
var res: StructureND<Float64> = one(shape)
repeat(n) { res += 1.0 }
blackhole.consume(res)
}
@Benchmark
fun viktorAdd(blackhole: Blackhole) = with(viktorField) {
var res: StructureND<Float64> = one(shape)
repeat(n) { res += 1.0 }
blackhole.consume(res)
}
@Benchmark
fun tensorAdd(blackhole: Blackhole) = with(Double.tensorAlgebra) {
var res: DoubleTensor = one(shape)
repeat(n) { res = res + 1.0 }
blackhole.consume(res)
}
@Benchmark
fun tensorInPlaceAdd(blackhole: Blackhole) = with(Double.tensorAlgebra) {
val res: DoubleTensor = one(shape)
repeat(n) { res += 1.0 }
blackhole.consume(res)
}
@OptIn(UnsafeKMathAPI::class)
@Benchmark
fun multikInPlaceAdd(blackhole: Blackhole) = with(multikAlgebra) {
val res = Multik.ones<Double, DN>(shape.asArray(), DataType.DoubleDataType).wrap()
repeat(n) { res += 1.0 }
blackhole.consume(res)
}
// @Benchmark
// fun nd4jAdd(blackhole: Blackhole) = with(nd4jField) {
// var res: StructureND<Float64> = one(dim, dim)
// repeat(n) { res += 1.0 }
// blackhole.consume(res)
// }
} }

View File

@ -0,0 +1,39 @@
/*
* Copyright 2018-2024 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package space.kscience.kmath.benchmarks
import kotlinx.benchmark.Benchmark
import kotlinx.benchmark.Blackhole
import kotlinx.benchmark.Scope
import kotlinx.benchmark.State
import space.kscience.kmath.linear.linearSpace
import space.kscience.kmath.linear.matrix
import space.kscience.kmath.linear.symmetric
import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.tensors.core.symEigJacobi
import space.kscience.kmath.tensors.core.symEigSvd
import space.kscience.kmath.tensors.core.tensorAlgebra
import kotlin.random.Random
@State(Scope.Benchmark)
internal class TensorAlgebraBenchmark {
companion object {
private val random = Random(12224)
private const val dim = 30
private val matrix = Float64Field.linearSpace.matrix(dim, dim).symmetric { _, _ -> random.nextDouble() }
}
@Benchmark
fun tensorSymEigSvd(blackhole: Blackhole) = with(Double.tensorAlgebra) {
blackhole.consume(symEigSvd(matrix, 1e-10))
}
@Benchmark
fun tensorSymEigJacobi(blackhole: Blackhole) = with(Double.tensorAlgebra) {
blackhole.consume(symEigJacobi(matrix, 50, 1e-10))
}
}

View File

@ -1,6 +1,6 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2024 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
package space.kscience.kmath.benchmarks package space.kscience.kmath.benchmarks
@ -10,28 +10,21 @@ import kotlinx.benchmark.Blackhole
import kotlinx.benchmark.Scope import kotlinx.benchmark.Scope
import kotlinx.benchmark.State import kotlinx.benchmark.State
import org.jetbrains.bio.viktor.F64Array import org.jetbrains.bio.viktor.F64Array
import space.kscience.kmath.nd.AlgebraND import space.kscience.kmath.nd.ShapeND
import space.kscience.kmath.nd.StructureND import space.kscience.kmath.nd.StructureND
import space.kscience.kmath.nd.auto import space.kscience.kmath.nd.ndAlgebra
import space.kscience.kmath.nd.real import space.kscience.kmath.nd.one
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.viktor.ViktorNDField import space.kscience.kmath.structures.Float64
import space.kscience.kmath.viktor.ViktorFieldND
@State(Scope.Benchmark) @State(Scope.Benchmark)
internal class ViktorBenchmark { internal class ViktorBenchmark {
@Benchmark
fun automaticFieldAddition(blackhole: Blackhole) {
with(autoField) {
var res: StructureND<Double> = one
repeat(n) { res += 1.0 }
blackhole.consume(res)
}
}
@Benchmark @Benchmark
fun realFieldAddition(blackhole: Blackhole) { fun doubleFieldAddition(blackhole: Blackhole) {
with(realField) { with(doubleField) {
var res: StructureND<Double> = one var res: StructureND<Float64> = one(shape)
repeat(n) { res += 1.0 } repeat(n) { res += 1.0 }
blackhole.consume(res) blackhole.consume(res)
} }
@ -40,7 +33,7 @@ internal class ViktorBenchmark {
@Benchmark @Benchmark
fun viktorFieldAddition(blackhole: Blackhole) { fun viktorFieldAddition(blackhole: Blackhole) {
with(viktorField) { with(viktorField) {
var res = one var res = one(shape)
repeat(n) { res += 1.0 } repeat(n) { res += 1.0 }
blackhole.consume(res) blackhole.consume(res)
} }
@ -57,10 +50,10 @@ internal class ViktorBenchmark {
private companion object { private companion object {
private const val dim = 1000 private const val dim = 1000
private const val n = 100 private const val n = 100
private val shape = ShapeND(dim, dim)
// automatically build context most suited for given type. // automatically build context most suited for given type.
private val autoField = AlgebraND.auto(DoubleField, dim, dim) private val doubleField = Float64Field.ndAlgebra
private val realField = AlgebraND.real(dim, dim) private val viktorField = ViktorFieldND(dim, dim)
private val viktorField = ViktorNDField(dim, dim)
} }
} }

View File

@ -1,6 +1,6 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2024 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
package space.kscience.kmath.benchmarks package space.kscience.kmath.benchmarks
@ -10,19 +10,19 @@ import kotlinx.benchmark.Blackhole
import kotlinx.benchmark.Scope import kotlinx.benchmark.Scope
import kotlinx.benchmark.State import kotlinx.benchmark.State
import org.jetbrains.bio.viktor.F64Array import org.jetbrains.bio.viktor.F64Array
import space.kscience.kmath.nd.AlgebraND import space.kscience.kmath.nd.ShapeND
import space.kscience.kmath.nd.auto import space.kscience.kmath.nd.ndAlgebra
import space.kscience.kmath.nd.real import space.kscience.kmath.nd.one
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.viktor.ViktorFieldND import space.kscience.kmath.viktor.ViktorFieldND
@State(Scope.Benchmark) @State(Scope.Benchmark)
internal class ViktorLogBenchmark { internal class ViktorLogBenchmark {
@Benchmark @Benchmark
fun realFieldLog(blackhole: Blackhole) { fun realFieldLog(blackhole: Blackhole) {
with(realNdField) { with(doubleField) {
val fortyTwo = produce { 42.0 } val fortyTwo = structureND(shape) { 42.0 }
var res = one var res = one(shape)
repeat(n) { res = ln(fortyTwo) } repeat(n) { res = ln(fortyTwo) }
blackhole.consume(res) blackhole.consume(res)
} }
@ -31,7 +31,7 @@ internal class ViktorLogBenchmark {
@Benchmark @Benchmark
fun viktorFieldLog(blackhole: Blackhole) { fun viktorFieldLog(blackhole: Blackhole) {
with(viktorField) { with(viktorField) {
val fortyTwo = produce { 42.0 } val fortyTwo = structureND(shape) { 42.0 }
var res = one var res = one
repeat(n) { res = ln(fortyTwo) } repeat(n) { res = ln(fortyTwo) }
blackhole.consume(res) blackhole.consume(res)
@ -49,10 +49,10 @@ internal class ViktorLogBenchmark {
private companion object { private companion object {
private const val dim = 1000 private const val dim = 1000
private const val n = 100 private const val n = 100
private val shape = ShapeND(dim, dim)
// automatically build context most suited for given type. // automatically build context most suited for given type.
private val autoField = AlgebraND.auto(DoubleField, dim, dim) private val doubleField = Float64Field.ndAlgebra
private val realNdField = AlgebraND.real(dim, dim) private val viktorField = ViktorFieldND(dim, dim)
private val viktorField = ViktorFieldND(intArrayOf(dim, dim))
} }
} }

View File

@ -0,0 +1,11 @@
/*
* Copyright 2018-2024 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package space.kscience.kmath.benchmarks
import org.jetbrains.kotlinx.multik.default.DefaultEngine
import space.kscience.kmath.multik.MultikDoubleAlgebra
val multikAlgebra = MultikDoubleAlgebra(DefaultEngine())

View File

@ -1,31 +1,28 @@
import java.net.URL import space.kscience.gradle.useApache2Licence
import space.kscience.gradle.useSPCTeam
plugins { plugins {
id("ru.mipt.npm.gradle.project") alias(spclibs.plugins.kscience.project)
kotlin("jupyter.api") apply false alias(spclibs.plugins.kotlinx.kover)
} }
val attributesVersion by extra("0.2.0")
allprojects { allprojects {
repositories { repositories {
maven("https://clojars.org/repo") maven("https://repo.kotlin.link")
maven("https://jitpack.io")
maven("http://logicrunch.research.it.uu.se/maven") {
isAllowInsecureProtocol = true
}
maven("https://oss.sonatype.org/content/repositories/snapshots") maven("https://oss.sonatype.org/content/repositories/snapshots")
mavenCentral() mavenCentral()
} }
group = "space.kscience" group = "space.kscience"
version = "0.3.0-dev-14" version = "0.4.1-dev"
} }
subprojects { subprojects {
if (name.startsWith("kmath")) apply<MavenPublishPlugin>() if (name.startsWith("kmath")) apply<MavenPublishPlugin>()
afterEvaluate { plugins.withId("org.jetbrains.dokka") {
tasks.withType<org.jetbrains.dokka.gradle.DokkaTaskPartial> { tasks.withType<org.jetbrains.dokka.gradle.DokkaTaskPartial> {
dependsOn(tasks["assemble"]) dependsOn(tasks["assemble"])
@ -39,7 +36,7 @@ subprojects {
localDirectory.set(kotlinDir) localDirectory.set(kotlinDir)
remoteUrl.set( remoteUrl.set(
URL("https://github.com/mipt-npm/${rootProject.name}/tree/master/${this@subprojects.name}/$kotlinDirPath") uri("https://github.com/SciProgCentre/kmath/tree/master/${this@subprojects.name}/$kotlinDirPath").toURL()
) )
} }
@ -64,9 +61,12 @@ subprojects {
readme.readmeTemplate = file("docs/templates/README-TEMPLATE.md") readme.readmeTemplate = file("docs/templates/README-TEMPLATE.md")
ksciencePublish { ksciencePublish {
vcs("https://github.com/mipt-npm/kmath") pom("https://github.com/SciProgCentre/kmath") {
space(publish = true) useApache2Licence()
sonatype(publish = true) useSPCTeam()
}
repository("spc", "https://maven.sciprog.center/kscience")
sonatype("https://oss.sonatype.org")
} }
apiValidation.nonPublicMarkers.add("space.kscience.kmath.misc.UnstableKMathAPI") apiValidation.nonPublicMarkers.add("space.kscience.kmath.UnstableKMathAPI")

View File

@ -1,20 +0,0 @@
plugins {
`kotlin-dsl`
kotlin("plugin.serialization") version "1.4.31"
}
repositories {
maven("https://repo.kotlin.link")
mavenCentral()
gradlePluginPortal()
}
dependencies {
api("org.jetbrains.kotlinx:kotlinx-serialization-json:1.1.0")
api("ru.mipt.npm:gradle-tools:0.10.2")
api("org.jetbrains.kotlinx:kotlinx-benchmark-plugin:0.3.1")
}
kotlin.sourceSets.all {
languageSettings.useExperimentalAnnotation("kotlin.ExperimentalStdlibApi")
}

View File

@ -1,60 +0,0 @@
/*
* Copyright 2018-2021 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
*/
package space.kscience.kmath.benchmarks
import kotlinx.serialization.Serializable
@Serializable
data class JmhReport(
val jmhVersion: String,
val benchmark: String,
val mode: String,
val threads: Int,
val forks: Int,
val jvm: String,
val jvmArgs: List<String>,
val jdkVersion: String,
val vmName: String,
val vmVersion: String,
val warmupIterations: Int,
val warmupTime: String,
val warmupBatchSize: Int,
val measurementIterations: Int,
val measurementTime: String,
val measurementBatchSize: Int,
val params: Map<String, String> = emptyMap(),
val primaryMetric: PrimaryMetric,
val secondaryMetrics: Map<String, SecondaryMetric>,
) {
interface Metric {
val score: Double
val scoreError: Double
val scoreConfidence: List<Double>
val scorePercentiles: Map<Double, Double>
val scoreUnit: String
}
@Serializable
data class PrimaryMetric(
override val score: Double,
override val scoreError: Double,
override val scoreConfidence: List<Double>,
override val scorePercentiles: Map<Double, Double>,
override val scoreUnit: String,
val rawDataHistogram: List<List<List<List<Double>>>>? = null,
val rawData: List<List<Double>>? = null,
) : Metric
@Serializable
data class SecondaryMetric(
override val score: Double,
override val scoreError: Double,
override val scoreConfidence: List<Double>,
override val scorePercentiles: Map<Double, Double>,
override val scoreUnit: String,
val rawData: List<List<Double>>,
) : Metric
}

View File

@ -1,100 +0,0 @@
/*
* Copyright 2018-2021 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
*/
package space.kscience.kmath.benchmarks
import kotlinx.benchmark.gradle.BenchmarksExtension
import kotlinx.serialization.*
import kotlinx.serialization.json.*
import org.gradle.api.Project
import ru.mipt.npm.gradle.KScienceReadmeExtension
import java.time.*
import java.time.format.*
import java.time.temporal.ChronoField.*
private val ISO_DATE_TIME: DateTimeFormatter = DateTimeFormatterBuilder().run {
parseCaseInsensitive()
appendValue(YEAR, 4, 10, SignStyle.EXCEEDS_PAD)
appendLiteral('-')
appendValue(MONTH_OF_YEAR, 2)
appendLiteral('-')
appendValue(DAY_OF_MONTH, 2)
appendLiteral('T')
appendValue(HOUR_OF_DAY, 2)
appendLiteral('.')
appendValue(MINUTE_OF_HOUR, 2)
optionalStart()
appendLiteral('.')
appendValue(SECOND_OF_MINUTE, 2)
optionalStart()
appendFraction(NANO_OF_SECOND, 0, 9, true)
optionalStart()
appendOffsetId()
optionalStart()
appendLiteral('[')
parseCaseSensitive()
appendZoneRegionId()
appendLiteral(']')
toFormatter()
}
private fun noun(number: Number, singular: String, plural: String) = if (number.toLong() == 1L) singular else plural
fun Project.addBenchmarkProperties() {
val benchmarksProject = this
rootProject.subprojects.forEach { p ->
p.extensions.findByType(KScienceReadmeExtension::class.java)?.run {
benchmarksProject.extensions.findByType(BenchmarksExtension::class.java)?.configurations?.forEach { cfg ->
property("benchmark${cfg.name.replaceFirstChar(Char::uppercase)}") {
val launches = benchmarksProject.buildDir.resolve("reports/benchmarks/${cfg.name}")
val resDirectory = launches.listFiles()?.maxByOrNull {
LocalDateTime.parse(it.name, ISO_DATE_TIME).atZone(ZoneId.systemDefault()).toInstant()
}
if (resDirectory == null) {
"> **Can't find appropriate benchmark data. Try generating readme files after running benchmarks**."
} else {
val reports =
Json.decodeFromString<List<JmhReport>>(resDirectory.resolve("jvm.json").readText())
buildString {
appendLine("<details>")
appendLine("<summary>")
appendLine("Report for benchmark configuration <code>${cfg.name}</code>")
appendLine("</summary>")
appendLine()
val first = reports.first()
appendLine("* Run on ${first.vmName} (build ${first.vmVersion}) with Java process:")
appendLine()
appendLine("```")
appendLine("${first.jvm} ${
first.jvmArgs.joinToString(" ")
}")
appendLine("```")
appendLine("* JMH ${first.jmhVersion} was used in `${first.mode}` mode with ${first.warmupIterations} warmup ${
noun(first.warmupIterations, "iteration", "iterations")
} by ${first.warmupTime} and ${first.measurementIterations} measurement ${
noun(first.measurementIterations, "iteration", "iterations")
} by ${first.measurementTime}.")
appendLine()
appendLine("| Benchmark | Score |")
appendLine("|:---------:|:-----:|")
reports.forEach { report ->
appendLine("|`${report.benchmark}`|${report.primaryMetric.score} &plusmn; ${report.primaryMetric.scoreError} ${report.primaryMetric.scoreUnit}|")
}
appendLine("</details>")
}
}
}
}
}
}
}

View File

@ -1,425 +0,0 @@
/*
* Copyright 2018-2021 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
*/
@file:Suppress("KDocUnresolvedReference")
package space.kscience.kmath.ejml.codegen
import org.intellij.lang.annotations.Language
import java.io.File
private fun Appendable.appendEjmlVector(type: String, ejmlMatrixType: String) {
@Language("kotlin") val text = """/**
* [EjmlVector] specialization for [$type].
*/
public class Ejml${type}Vector<out M : $ejmlMatrixType>(override val origin: M) : EjmlVector<$type, M>(origin) {
init {
require(origin.numRows == 1) { "The origin matrix must have only one row to form a vector" }
}
override operator fun get(index: Int): $type = origin[0, index]
}"""
appendLine(text)
appendLine()
}
private fun Appendable.appendEjmlMatrix(type: String, ejmlMatrixType: String) {
val text = """/**
* [EjmlMatrix] specialization for [$type].
*/
public class Ejml${type}Matrix<out M : $ejmlMatrixType>(override val origin: M) : EjmlMatrix<$type, M>(origin) {
override operator fun get(i: Int, j: Int): $type = origin[i, j]
}"""
appendLine(text)
appendLine()
}
private fun Appendable.appendEjmlLinearSpace(
type: String,
kmathAlgebra: String,
ejmlMatrixParentTypeMatrix: String,
ejmlMatrixType: String,
ejmlMatrixDenseType: String,
ops: String,
denseOps: String,
isDense: Boolean,
) {
@Language("kotlin") val text = """/**
* [EjmlLinearSpace] implementation based on [CommonOps_$ops], [DecompositionFactory_${ops}] operations and
* [${ejmlMatrixType}] matrices.
*/
public object EjmlLinearSpace${ops} : EjmlLinearSpace<${type}, ${kmathAlgebra}, $ejmlMatrixType>() {
/**
* The [${kmathAlgebra}] reference.
*/
override val elementAlgebra: $kmathAlgebra get() = $kmathAlgebra
@Suppress("UNCHECKED_CAST")
override fun Matrix<${type}>.toEjml(): Ejml${type}Matrix<${ejmlMatrixType}> = when {
this is Ejml${type}Matrix<*> && origin is $ejmlMatrixType -> this as Ejml${type}Matrix<${ejmlMatrixType}>
else -> buildMatrix(rowNum, colNum) { i, j -> get(i, j) }
}
@Suppress("UNCHECKED_CAST")
override fun Point<${type}>.toEjml(): Ejml${type}Vector<${ejmlMatrixType}> = when {
this is Ejml${type}Vector<*> && origin is $ejmlMatrixType -> this as Ejml${type}Vector<${ejmlMatrixType}>
else -> Ejml${type}Vector(${ejmlMatrixType}(size, 1).also {
(0 until it.numRows).forEach { row -> it[row, 0] = get(row) }
})
}
override fun buildMatrix(
rows: Int,
columns: Int,
initializer: ${kmathAlgebra}.(i: Int, j: Int) -> ${type},
): Ejml${type}Matrix<${ejmlMatrixType}> = ${ejmlMatrixType}(rows, columns).also {
(0 until rows).forEach { row ->
(0 until columns).forEach { col -> it[row, col] = elementAlgebra.initializer(row, col) }
}
}.wrapMatrix()
override fun buildVector(
size: Int,
initializer: ${kmathAlgebra}.(Int) -> ${type},
): Ejml${type}Vector<${ejmlMatrixType}> = Ejml${type}Vector(${ejmlMatrixType}(size, 1).also {
(0 until it.numRows).forEach { row -> it[row, 0] = elementAlgebra.initializer(row) }
})
private fun <T : ${ejmlMatrixParentTypeMatrix}> T.wrapMatrix() = Ejml${type}Matrix(this)
private fun <T : ${ejmlMatrixParentTypeMatrix}> T.wrapVector() = Ejml${type}Vector(this)
override fun Matrix<${type}>.unaryMinus(): Matrix<${type}> = this * elementAlgebra { -one }
override fun Matrix<${type}>.dot(other: Matrix<${type}>): Ejml${type}Matrix<${ejmlMatrixType}> {
val out = ${ejmlMatrixType}(1, 1)
CommonOps_${ops}.mult(toEjml().origin, other.toEjml().origin, out)
return out.wrapMatrix()
}
override fun Matrix<${type}>.dot(vector: Point<${type}>): Ejml${type}Vector<${ejmlMatrixType}> {
val out = ${ejmlMatrixType}(1, 1)
CommonOps_${ops}.mult(toEjml().origin, vector.toEjml().origin, out)
return out.wrapVector()
}
override operator fun Matrix<${type}>.minus(other: Matrix<${type}>): Ejml${type}Matrix<${ejmlMatrixType}> {
val out = ${ejmlMatrixType}(1, 1)
CommonOps_${ops}.add(
elementAlgebra.one,
toEjml().origin,
elementAlgebra { -one },
other.toEjml().origin,
out,${
if (isDense) "" else
"""
null,
null,"""
}
)
return out.wrapMatrix()
}
override operator fun Matrix<${type}>.times(value: ${type}): Ejml${type}Matrix<${ejmlMatrixType}> {
val res = ${ejmlMatrixType}(1, 1)
CommonOps_${ops}.scale(value, toEjml().origin, res)
return res.wrapMatrix()
}
override fun Point<${type}>.unaryMinus(): Ejml${type}Vector<${ejmlMatrixType}> {
val res = ${ejmlMatrixType}(1, 1)
CommonOps_${ops}.changeSign(toEjml().origin, res)
return res.wrapVector()
}
override fun Matrix<${type}>.plus(other: Matrix<${type}>): Ejml${type}Matrix<${ejmlMatrixType}> {
val out = ${ejmlMatrixType}(1, 1)
CommonOps_${ops}.add(
elementAlgebra.one,
toEjml().origin,
elementAlgebra.one,
other.toEjml().origin,
out,${
if (isDense) "" else
"""
null,
null,"""
}
)
return out.wrapMatrix()
}
override fun Point<${type}>.plus(other: Point<${type}>): Ejml${type}Vector<${ejmlMatrixType}> {
val out = ${ejmlMatrixType}(1, 1)
CommonOps_${ops}.add(
elementAlgebra.one,
toEjml().origin,
elementAlgebra.one,
other.toEjml().origin,
out,${
if (isDense) "" else
"""
null,
null,"""
}
)
return out.wrapVector()
}
override fun Point<${type}>.minus(other: Point<${type}>): Ejml${type}Vector<${ejmlMatrixType}> {
val out = ${ejmlMatrixType}(1, 1)
CommonOps_${ops}.add(
elementAlgebra.one,
toEjml().origin,
elementAlgebra { -one },
other.toEjml().origin,
out,${
if (isDense) "" else
"""
null,
null,"""
}
)
return out.wrapVector()
}
override fun ${type}.times(m: Matrix<${type}>): Ejml${type}Matrix<${ejmlMatrixType}> = m * this
override fun Point<${type}>.times(value: ${type}): Ejml${type}Vector<${ejmlMatrixType}> {
val res = ${ejmlMatrixType}(1, 1)
CommonOps_${ops}.scale(value, toEjml().origin, res)
return res.wrapVector()
}
override fun ${type}.times(v: Point<${type}>): Ejml${type}Vector<${ejmlMatrixType}> = v * this
@UnstableKMathAPI
override fun <F : StructureFeature> getFeature(structure: Matrix<${type}>, type: KClass<out F>): F? {
structure.getFeature(type)?.let { return it }
val origin = structure.toEjml().origin
return when (type) {
${
if (isDense)
""" InverseMatrixFeature::class -> object : InverseMatrixFeature<${type}> {
override val inverse: Matrix<${type}> by lazy {
val res = origin.copy()
CommonOps_${ops}.invert(res)
res.wrapMatrix()
}
}
DeterminantFeature::class -> object : DeterminantFeature<${type}> {
override val determinant: $type by lazy { CommonOps_${ops}.det(origin) }
}
SingularValueDecompositionFeature::class -> object : SingularValueDecompositionFeature<${type}> {
private val svd by lazy {
DecompositionFactory_${ops}.svd(origin.numRows, origin.numCols, true, true, false)
.apply { decompose(origin.copy()) }
}
override val u: Matrix<${type}> by lazy { svd.getU(null, false).wrapMatrix() }
override val s: Matrix<${type}> by lazy { svd.getW(null).wrapMatrix() }
override val v: Matrix<${type}> by lazy { svd.getV(null, false).wrapMatrix() }
override val singularValues: Point<${type}> by lazy { ${type}Buffer(svd.singularValues) }
}
QRDecompositionFeature::class -> object : QRDecompositionFeature<${type}> {
private val qr by lazy {
DecompositionFactory_${ops}.qr().apply { decompose(origin.copy()) }
}
override val q: Matrix<${type}> by lazy {
qr.getQ(null, false).wrapMatrix() + OrthogonalFeature
}
override val r: Matrix<${type}> by lazy { qr.getR(null, false).wrapMatrix() + UFeature }
}
CholeskyDecompositionFeature::class -> object : CholeskyDecompositionFeature<${type}> {
override val l: Matrix<${type}> by lazy {
val cholesky =
DecompositionFactory_${ops}.chol(structure.rowNum, true).apply { decompose(origin.copy()) }
cholesky.getT(null).wrapMatrix() + LFeature
}
}
LupDecompositionFeature::class -> object : LupDecompositionFeature<${type}> {
private val lup by lazy {
DecompositionFactory_${ops}.lu(origin.numRows, origin.numCols).apply { decompose(origin.copy()) }
}
override val l: Matrix<${type}> by lazy {
lup.getLower(null).wrapMatrix() + LFeature
}
override val u: Matrix<${type}> by lazy {
lup.getUpper(null).wrapMatrix() + UFeature
}
override val p: Matrix<${type}> by lazy { lup.getRowPivot(null).wrapMatrix() }
}""" else """ QRDecompositionFeature::class -> object : QRDecompositionFeature<$type> {
private val qr by lazy {
DecompositionFactory_${ops}.qr(FillReducing.NONE).apply { decompose(origin.copy()) }
}
override val q: Matrix<${type}> by lazy {
qr.getQ(null, false).wrapMatrix() + OrthogonalFeature
}
override val r: Matrix<${type}> by lazy { qr.getR(null, false).wrapMatrix() + UFeature }
}
CholeskyDecompositionFeature::class -> object : CholeskyDecompositionFeature<${type}> {
override val l: Matrix<${type}> by lazy {
val cholesky =
DecompositionFactory_${ops}.cholesky().apply { decompose(origin.copy()) }
(cholesky.getT(null) as ${ejmlMatrixParentTypeMatrix}).wrapMatrix() + LFeature
}
}
LUDecompositionFeature::class, DeterminantFeature::class, InverseMatrixFeature::class -> object :
LUDecompositionFeature<${type}>, DeterminantFeature<${type}>, InverseMatrixFeature<${type}> {
private val lu by lazy {
DecompositionFactory_${ops}.lu(FillReducing.NONE).apply { decompose(origin.copy()) }
}
override val l: Matrix<${type}> by lazy {
lu.getLower(null).wrapMatrix() + LFeature
}
override val u: Matrix<${type}> by lazy {
lu.getUpper(null).wrapMatrix() + UFeature
}
override val inverse: Matrix<${type}> by lazy {
var a = origin
val inverse = ${ejmlMatrixDenseType}(1, 1)
val solver = LinearSolverFactory_${ops}.lu(FillReducing.NONE)
if (solver.modifiesA()) a = a.copy()
val i = CommonOps_${denseOps}.identity(a.numRows)
solver.solve(i, inverse)
inverse.wrapMatrix()
}
override val determinant: $type by lazy { elementAlgebra.number(lu.computeDeterminant().real) }
}"""
}
else -> null
}?.let(type::cast)
}
/**
* Solves for *x* in the following equation: *x = [a] <sup>-1</sup> &middot; [b]*.
*
* @param a the base matrix.
* @param b n by p matrix.
* @return the solution for *x* that is n by p.
*/
public fun solve(a: Matrix<${type}>, b: Matrix<${type}>): Ejml${type}Matrix<${ejmlMatrixType}> {
val res = ${ejmlMatrixType}(1, 1)
CommonOps_${ops}.solve(${ejmlMatrixType}(a.toEjml().origin), ${ejmlMatrixType}(b.toEjml().origin), res)
return res.wrapMatrix()
}
/**
* Solves for *x* in the following equation: *x = [a] <sup>-1</sup> &middot; [b]*.
*
* @param a the base matrix.
* @param b n by p vector.
* @return the solution for *x* that is n by p.
*/
public fun solve(a: Matrix<${type}>, b: Point<${type}>): Ejml${type}Vector<${ejmlMatrixType}> {
val res = ${ejmlMatrixType}(1, 1)
CommonOps_${ops}.solve(${ejmlMatrixType}(a.toEjml().origin), ${ejmlMatrixType}(b.toEjml().origin), res)
return Ejml${type}Vector(res)
}
}"""
appendLine(text)
appendLine()
}
/**
* Generates routine EJML classes.
*/
fun ejmlCodegen(outputFile: String): Unit = File(outputFile).run {
parentFile.mkdirs()
writer().use {
it.appendLine("/*")
it.appendLine(" * Copyright 2018-2021 KMath contributors.")
it.appendLine(" * Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.")
it.appendLine(" */")
it.appendLine()
it.appendLine("/* This file is generated with buildSrc/src/main/kotlin/space/kscience/kmath/ejml/codegen/ejmlCodegen.kt */")
it.appendLine()
it.appendLine("package space.kscience.kmath.ejml")
it.appendLine()
it.appendLine("""import org.ejml.data.*
import org.ejml.dense.row.CommonOps_DDRM
import org.ejml.dense.row.CommonOps_FDRM
import org.ejml.dense.row.factory.DecompositionFactory_DDRM
import org.ejml.dense.row.factory.DecompositionFactory_FDRM
import org.ejml.sparse.FillReducing
import org.ejml.sparse.csc.CommonOps_DSCC
import org.ejml.sparse.csc.CommonOps_FSCC
import org.ejml.sparse.csc.factory.DecompositionFactory_DSCC
import org.ejml.sparse.csc.factory.DecompositionFactory_FSCC
import org.ejml.sparse.csc.factory.LinearSolverFactory_DSCC
import org.ejml.sparse.csc.factory.LinearSolverFactory_FSCC
import space.kscience.kmath.linear.*
import space.kscience.kmath.linear.Matrix
import space.kscience.kmath.misc.UnstableKMathAPI
import space.kscience.kmath.nd.StructureFeature
import space.kscience.kmath.operations.DoubleField
import space.kscience.kmath.operations.FloatField
import space.kscience.kmath.operations.invoke
import space.kscience.kmath.structures.DoubleBuffer
import space.kscience.kmath.structures.FloatBuffer
import kotlin.reflect.KClass
import kotlin.reflect.cast""")
it.appendLine()
it.appendEjmlVector("Double", "DMatrix")
it.appendEjmlVector("Float", "FMatrix")
it.appendEjmlMatrix("Double", "DMatrix")
it.appendEjmlMatrix("Float", "FMatrix")
it.appendEjmlLinearSpace("Double", "DoubleField", "DMatrix", "DMatrixRMaj", "DMatrixRMaj", "DDRM", "DDRM", true)
it.appendEjmlLinearSpace("Float", "FloatField", "FMatrix", "FMatrixRMaj", "FMatrixRMaj", "FDRM", "FDRM", true)
it.appendEjmlLinearSpace(
type = "Double",
kmathAlgebra = "DoubleField",
ejmlMatrixParentTypeMatrix = "DMatrix",
ejmlMatrixType = "DMatrixSparseCSC",
ejmlMatrixDenseType = "DMatrixRMaj",
ops = "DSCC",
denseOps = "DDRM",
isDense = false,
)
it.appendEjmlLinearSpace(
type = "Float",
kmathAlgebra = "FloatField",
ejmlMatrixParentTypeMatrix = "FMatrix",
ejmlMatrixType = "FMatrixSparseCSC",
ejmlMatrixDenseType = "FMatrixRMaj",
ops = "FSCC",
denseOps = "FDRM",
isDense = false,
)
}
}

View File

@ -17,4 +17,4 @@ own `MemoryBuffer.create()` factory).
## Buffer performance ## Buffer performance
One should avoid using default boxing buffer wherever it is possible. Try to use primitive buffers or memory buffers One should avoid using default boxing buffer wherever it is possible. Try to use primitive buffers or memory buffers
instead . instead.

View File

@ -1,20 +1,27 @@
# Coding Conventions # Coding Conventions
Generally, KMath code follows general [Kotlin coding conventions](https://kotlinlang.org/docs/reference/coding-conventions.html), but with a number of small changes and clarifications. Generally, KMath code follows
general [Kotlin coding conventions](https://kotlinlang.org/docs/reference/coding-conventions.html), but with a number of
small changes and clarifications.
## Utility Class Naming ## Utility Class Naming
Filename should coincide with a name of one of the classes contained in the file or start with small letter and describe its contents. Filename should coincide with a name of one of the classes contained in the file or start with small letter and describe
its contents.
The code convention [here](https://kotlinlang.org/docs/reference/coding-conventions.html#source-file-names) says that file names should start with a capital letter even if file does not contain classes. Yet starting utility classes and aggregators with a small letter seems to be a good way to visually separate those files. The code convention [here](https://kotlinlang.org/docs/reference/coding-conventions.html#source-file-names) says that
file names should start with a capital letter even if file does not contain classes. Yet starting utility classes and
aggregators with a small letter seems to be a good way to visually separate those files.
This convention could be changed in future in a non-breaking way. This convention could be changed in future in a non-breaking way.
## Private Variable Naming ## Private Variable Naming
Private variables' names may start with underscore `_` for of the private mutable variable is shadowed by the public read-only value with the same meaning. Private variables' names may start with underscore `_` for of the private mutable variable is shadowed by the public
read-only value with the same meaning.
This rule does not permit underscores in names, but it is sometimes useful to "underscore" the fact that public and private versions draw up the same entity. It is allowed only for private variables. This rule does not permit underscores in names, but it is sometimes useful to "underscore" the fact that public and
private versions draw up the same entity. It is allowed only for private variables.
This convention could be changed in future in a non-breaking way. This convention could be changed in future in a non-breaking way.
@ -24,4 +31,5 @@ Use one-liners when they occupy single code window line both for functions and p
`val b: String get() = "fff"`. The same should be performed with multiline expressions when they could be `val b: String get() = "fff"`. The same should be performed with multiline expressions when they could be
cleanly separated. cleanly separated.
There is no universal consensus whenever use `fun a() = ...` or `fun a() { return ... }`. Yet from reader outlook one-lines seem to better show that the property or function is easily calculated. There is no universal consensus whenever use `fun a() = ...` or `fun a() { return ... }`. Yet from reader outlook
one-lines seem to better show that the property or function is easily calculated.

1020
docs/diagrams/core.puml Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,16 +1,19 @@
# Expressions # Expressions
Expressions is a feature, which allows constructing lazily or immediately calculated parametric mathematical expressions. Expressions is a feature, which allows constructing lazily or immediately calculated parametric mathematical
expressions.
The potential use-cases for it (so far) are following: The potential use-cases for it (so far) are following:
* lazy evaluation (in general simple lambda is better, but there are some border cases); * lazy evaluation (in general simple lambda is better, but there are some border cases);
* automatic differentiation in single-dimension and in multiple dimensions; * automatic differentiation in single-dimension and in multiple dimensions;
* generation of mathematical syntax trees with subsequent code generation for other languages; * generation of mathematical syntax trees with subsequent code generation for other languages;
* symbolic computations, especially differentiation (and some other actions with `kmath-symja` integration with Symja's `IExpr`&mdash;integration, simplification, and more); * symbolic computations, especially differentiation (and some other actions with `kmath-symja` integration with
Symja's `IExpr`&mdash;integration, simplification, and more);
* visualization with `kmath-jupyter`. * visualization with `kmath-jupyter`.
The workhorse of this API is `Expression` interface, which exposes single `operator fun invoke(arguments: Map<Symbol, T>): T` The workhorse of this API is `Expression` interface, which exposes
single `operator fun invoke(arguments: Map<Symbol, T>): T`
method. `ExpressionAlgebra` is used to generate expressions and introduce variables. method. `ExpressionAlgebra` is used to generate expressions and introduce variables.
Currently there are two implementations: Currently there are two implementations:
@ -18,4 +21,4 @@ Currently there are two implementations:
* Generic `ExpressionField` in `kmath-core` which allows construction of custom lazy expressions * Generic `ExpressionField` in `kmath-core` which allows construction of custom lazy expressions
* Auto-differentiation expression in `kmath-commons` module allows using full power of `DerivativeStructure` * Auto-differentiation expression in `kmath-commons` module allows using full power of `DerivativeStructure`
from commons-math. **TODO: add example** from commons-math. **TODO: add example**

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- <!--
- Copyright 2018-2021 KMath contributors. - Copyright 2018-2024 KMath contributors.
- Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. - Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
--> -->
<svg <svg

Before

Width:  |  Height:  |  Size: 249 KiB

After

Width:  |  Height:  |  Size: 249 KiB

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- <!--
- Copyright 2018-2021 KMath contributors. - Copyright 2018-2024 KMath contributors.
- Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. - Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
--> -->
<svg <svg

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- <!--
- Copyright 2018-2021 KMath contributors. - Copyright 2018-2024 KMath contributors.
- Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. - Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
--> -->
<svg <svg

Before

Width:  |  Height:  |  Size: 278 KiB

After

Width:  |  Height:  |  Size: 278 KiB

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- <!--
- Copyright 2018-2021 KMath contributors. - Copyright 2018-2024 KMath contributors.
- Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. - Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
--> -->
<svg <svg

Before

Width:  |  Height:  |  Size: 118 KiB

After

Width:  |  Height:  |  Size: 118 KiB

View File

@ -1,8 +1,12 @@
## Basic linear algebra layout ## Basic linear algebra layout
KMath support for linear algebra organized in a context-oriented way, which means that operations are in most cases declared in context classes, and are not the members of classes that store data. This allows more flexible approach to maintain multiple back-ends. The new operations added as extensions to contexts instead of being member functions of data structures. KMath support for linear algebra organized in a context-oriented way, which means that operations are in most cases
declared in context classes, and are not the members of classes that store data. This allows more flexible approach to
maintain multiple back-ends. The new operations added as extensions to contexts instead of being member functions of
data structures.
The main context for linear algebra over matrices and vectors is `LinearSpace`, which defines addition and dot products of matrices and vectors: The main context for linear algebra over matrices and vectors is `LinearSpace`, which defines addition and dot products
of matrices and vectors:
```kotlin ```kotlin
import space.kscience.kmath.linear.* import space.kscience.kmath.linear.*
@ -28,4 +32,5 @@ LinearSpace.Companion.real {
## Backends overview ## Backends overview
### EJML ### EJML
### Commons Math ### Commons Math

View File

@ -8,6 +8,7 @@ One of the most sought after features of mathematical libraries is the high-perf
structures. In `kmath` performance depends on which particular context was used for operation. structures. In `kmath` performance depends on which particular context was used for operation.
Let us consider following contexts: Let us consider following contexts:
```kotlin ```kotlin
// automatically build context most suited for given type. // automatically build context most suited for given type.
val autoField = NDField.auto(DoubleField, dim, dim) val autoField = NDField.auto(DoubleField, dim, dim)
@ -16,6 +17,7 @@ Let us consider following contexts:
//A generic boxing field. It should be used for objects, not primitives. //A generic boxing field. It should be used for objects, not primitives.
val genericField = NDField.buffered(DoubleField, dim, dim) val genericField = NDField.buffered(DoubleField, dim, dim)
``` ```
Now let us perform several tests and see, which implementation is best suited for each case: Now let us perform several tests and see, which implementation is best suited for each case:
## Test case ## Test case
@ -24,22 +26,27 @@ To test performance we will take 2d-structures with `dim = 1000` and add a struc
to it `n = 1000` times. to it `n = 1000` times.
## Specialized ## Specialized
The code to run this looks like: The code to run this looks like:
```kotlin ```kotlin
specializedField.run { specializedField.run {
var res: NDBuffer<Double> = one var res: NDBuffer<Float64> = one
repeat(n) { repeat(n) {
res += 1.0 res += 1.0
} }
} }
``` ```
The performance of this code is the best of all tests since it inlines all operations and is specialized for operation The performance of this code is the best of all tests since it inlines all operations and is specialized for operation
with doubles. We will measure everything else relative to this one, so time for this test will be `1x` (real time with doubles. We will measure everything else relative to this one, so time for this test will be `1x` (real time
on my computer is about 4.5 seconds). The only problem with this approach is that it requires specifying type on my computer is about 4.5 seconds). The only problem with this approach is that it requires specifying type
from the beginning. Everyone does so anyway, so it is the recommended approach. from the beginning. Everyone does so anyway, so it is the recommended approach.
## Automatic ## Automatic
Let's do the same with automatic field inference: Let's do the same with automatic field inference:
```kotlin ```kotlin
autoField.run { autoField.run {
var res = one var res = one
@ -48,13 +55,16 @@ Let's do the same with automatic field inference:
} }
} }
``` ```
Ths speed of this operation is approximately the same as for specialized case since `NDField.auto` just Ths speed of this operation is approximately the same as for specialized case since `NDField.auto` just
returns the same `RealNDField` in this case. Of course, it is usually better to use specialized method to be sure. returns the same `RealNDField` in this case. Of course, it is usually better to use specialized method to be sure.
## Lazy ## Lazy
Lazy field does not produce a structure when asked, instead it generates an empty structure and fills it on-demand Lazy field does not produce a structure when asked, instead it generates an empty structure and fills it on-demand
using coroutines to parallelize computations. using coroutines to parallelize computations.
When one calls When one calls
```kotlin ```kotlin
lazyField.run { lazyField.run {
var res = one var res = one
@ -63,12 +73,14 @@ When one calls
} }
} }
``` ```
The result will be calculated almost immediately but the result will be empty. To get the full result The result will be calculated almost immediately but the result will be empty. To get the full result
structure one needs to call all its elements. In this case computation overhead will be huge. So this field never structure one needs to call all its elements. In this case computation overhead will be huge. So this field never
should be used if one expects to use the full result structure. Though if one wants only small fraction, it could should be used if one expects to use the full result structure. Though if one wants only small fraction, it could
save a lot of time. save a lot of time.
This field still could be used with reasonable performance if call code is changed: This field still could be used with reasonable performance if call code is changed:
```kotlin ```kotlin
lazyField.run { lazyField.run {
val res = one.map { val res = one.map {
@ -82,30 +94,37 @@ This field still could be used with reasonable performance if call code is chang
res.elements().forEach { it.second } res.elements().forEach { it.second }
} }
``` ```
In this case it completes in about `4x-5x` time due to boxing. In this case it completes in about `4x-5x` time due to boxing.
## Boxing ## Boxing
The boxing field produced by The boxing field produced by
```kotlin ```kotlin
genericField.run { genericField.run {
var res: NDBuffer<Double> = one var res: NDBuffer<Float64> = one
repeat(n) { repeat(n) {
res += 1.0 res += 1.0
} }
} }
``` ```
is the slowest one, because it requires boxing and unboxing the `double` on each operation. It takes about is the slowest one, because it requires boxing and unboxing the `double` on each operation. It takes about
`15x` time (**TODO: there seems to be a problem here, it should be slow, but not that slow**). This field should `15x` time (**TODO: there seems to be a problem here, it should be slow, but not that slow**). This field should
never be used for primitives. never be used for primitives.
## Element operation ## Element operation
Let us also check the speed for direct operations on elements: Let us also check the speed for direct operations on elements:
```kotlin ```kotlin
var res = genericField.one var res = genericField.one
repeat(n) { repeat(n) {
res += 1.0 res += 1.0
} }
``` ```
One would expect to be at least as slow as field operation, but in fact, this one takes only `2x` time to complete. One would expect to be at least as slow as field operation, but in fact, this one takes only `2x` time to complete.
It happens, because in this particular case it does not use actual `NDField` but instead calculated directly It happens, because in this particular case it does not use actual `NDField` but instead calculated directly
via extension function. via extension function.
@ -114,6 +133,7 @@ via extension function.
Usually it is bad idea to compare the direct numerical operation performance in different languages, but it hard to Usually it is bad idea to compare the direct numerical operation performance in different languages, but it hard to
work completely without frame of reference. In this case, simple numpy code: work completely without frame of reference. In this case, simple numpy code:
```python ```python
import numpy as np import numpy as np
@ -121,7 +141,9 @@ res = np.ones((1000,1000))
for i in range(1000): for i in range(1000):
res = res + 1.0 res = res + 1.0
``` ```
gives the completion time of about `1.1x`, which means that specialized kotlin code in fact is working faster (I think it is
gives the completion time of about `1.1x`, which means that specialized kotlin code in fact is working faster (I think
it is
because better memory management). Of course if one writes `res += 1.0`, the performance will be different, because better memory management). Of course if one writes `res += 1.0`, the performance will be different,
but it would be different case, because numpy overrides `+=` with in-place operations. In-place operations are but it would be different case, because numpy overrides `+=` with in-place operations. In-place operations are
available in `kmath` with `MutableNDStructure` but there is no field for it (one can still work with mapping available in `kmath` with `MutableNDStructure` but there is no field for it (one can still work with mapping

223
docs/polynomials.md Normal file
View File

@ -0,0 +1,223 @@
# Polynomials and Rational Functions
KMath provides a way to work with uni- and multivariate polynomials and rational functions. It includes full support of
arithmetic operations of integers, **constants** (elements of ring polynomials are build over), variables (for certain
multivariate implementations), polynomials and rational functions encapsulated in so-called **polynomial space** and *
*rational function space** and some other utilities such as algebraic differentiation and substitution.
## Concrete realizations
There are 3 approaches to represent polynomials:
1. For univariate polynomials one can represent and store polynomial as a list of coefficients for each power of the
variable. I.e. polynomial $a_0 + \dots + a_n x^n $ can be represented as a finite sequence $(a_0; \dots; a_n)$. (
Compare to sequential definition of polynomials.)
2. For multivariate polynomials one can represent and store polynomial as a matching (in programming it is called "map"
or "dictionary", in math it is
called [functional relation](https://en.wikipedia.org/wiki/Binary_relation#Special_types_of_binary_relations)) of
each "**term signature**" (that describes what variables and in what powers appear in the term) with corresponding
coefficient of the term. But there are 2 possible approaches of term signature representation:
1. One can number all the variables, so term signature can be represented as a sequence describing powers of the
variables. I.e. signature of term $c \\; x_0^{d_0} \dots x_n^{d_n} $ (for natural or zero $d_i $) can be
represented as a finite sequence $(d_0; \dots; d_n)$.
2. One can represent variables as objects ("**labels**"), so term signature can be also represented as a matching of
each appeared variable with its power in the term. I.e. signature of term $c \\; x_0^{d_0} \dots x_n^{d_n} $ (for
natural non-zero $d_i $) can be represented as a finite matching $(x_0 \to d_1; \dots; x_n \to d_n)$.
All that three approaches are implemented by "list", "numbered", and "labeled" versions of polynomials and polynomial
spaces respectively. Whereas all rational functions are represented as fractions with corresponding polynomial numerator
and denominator, and rational functions' spaces are implemented in the same way as usual field of rational numbers (or
more precisely, as any field of fractions over integral domain) should be implemented.
So here are a bit of details. Let `C` by type of constants. Then:
1. `ListPolynomial`, `ListPolynomialSpace`, `ListRationalFunction` and `ListRationalFunctionSpace` implement the first
scenario. `ListPolynomial` stores polynomial $a_0 + \dots + a_n x^n $ as a coefficients
list `listOf(a_0, ..., a_n)` (of type `List<C>`).
They also have variation `ScalableListPolynomialSpace` that replaces former polynomials and
implements `ScaleOperations`.
2. `NumberedPolynomial`, `NumberedPolynomialSpace`, `NumberedRationalFunction` and `NumberedRationalFunctionSpace`
implement second scenario. `NumberedPolynomial` stores polynomials as structures of type `Map<List<UInt>, C>`.
Signatures are stored as `List<UInt>`. To prevent ambiguity signatures should not end with zeros.
3. `LabeledPolynomial`, `LabeledPolynomialSpace`, `LabeledRationalFunction` and `LabeledRationalFunctionSpace` implement
third scenario using common `Symbol` as variable type. `LabeledPolynomial` stores polynomials as structures of
type `Map<Map<Symbol, UInt>, C>`. Signatures are stored as `Map<Symbol, UInt>`. To prevent ambiguity each signature
should not map any variable to zero.
### Example: `ListPolynomial`
For example, polynomial $2 - 3x + x^2 $ (with `Int` coefficients) is represented
```kotlin
val polynomial: ListPolynomial<Int> = ListPolynomial(listOf(2, -3, 1))
// or
val polynomial: ListPolynomial<Int> = ListPolynomial(2, -3, 1)
```
All algebraic operations can be used in corresponding space:
```kotlin
val computationResult = Int.algebra.listPolynomialSpace {
ListPolynomial(2, -3, 1) + ListPolynomial(0, 6) == ListPolynomial(2, 3, 1)
}
println(computationResult) // true
```
For more see [examples](../examples/src/main/kotlin/space/kscience/kmath/functions/polynomials.kt).
### Example: `NumberedPolynomial`
For example, polynomial $3 + 5 x_1 - 7 x_0^2 x_2 $ (with `Int` coefficients) is represented
```kotlin
val polynomial: NumberedPolynomial<Int> = NumberedPolynomial(
mapOf(
listOf<UInt>() to 3,
listOf(0u, 1u) to 5,
listOf(2u, 0u, 1u) to -7,
)
)
// or
val polynomial: NumberedPolynomial<Int> = NumberedPolynomial(
listOf<UInt>() to 3,
listOf(0u, 1u) to 5,
listOf(2u, 0u, 1u) to -7,
)
```
All algebraic operations can be used in corresponding space:
```kotlin
val computationResult = Int.algebra.numberedPolynomialSpace {
NumberedPolynomial(
listOf<UInt>() to 3,
listOf(0u, 1u) to 5,
listOf(2u, 0u, 1u) to -7,
) + NumberedPolynomial(
listOf(0u, 1u) to -5,
listOf(0u, 0u, 0u, 4u) to 4,
) == NumberedPolynomial(
listOf<UInt>() to 3,
listOf(0u, 1u) to 0,
listOf(2u, 0u, 1u) to -7,
listOf(0u, 0u, 0u, 4u) to 4,
)
}
println(computationResult) // true
```
For more see [examples](../examples/src/main/kotlin/space/kscience/kmath/functions/polynomials.kt).
### Example: `LabeledPolynomial`
For example, polynomial $3 + 5 y - 7 x^2 z $ (with `Int` coefficients) is represented
```kotlin
val polynomial: LabeledPolynomial<Int> = LabeledPolynomial(
mapOf(
mapOf<Symbol, UInt>() to 3,
mapOf(y to 1u) to 5,
mapOf(x to 2u, z to 1u) to -7,
)
)
// or
val polynomial: LabeledPolynomial<Int> = LabeledPolynomial(
mapOf<Symbol, UInt>() to 3,
mapOf(y to 1u) to 5,
mapOf(x to 2u, z to 1u) to -7,
)
```
All algebraic operations can be used in corresponding space:
```kotlin
val computationResult = Int.algebra.labeledPolynomialSpace {
LabeledPolynomial(
listOf<UInt>() to 3,
listOf(0u, 1u) to 5,
listOf(2u, 0u, 1u) to -7,
) + LabeledPolynomial(
listOf(0u, 1u) to -5,
listOf(0u, 0u, 0u, 4u) to 4,
) == LabeledPolynomial(
listOf<UInt>() to 3,
listOf(0u, 1u) to 0,
listOf(2u, 0u, 1u) to -7,
listOf(0u, 0u, 0u, 4u) to 4,
)
}
println(computationResult) // true
```
For more see [examples](../examples/src/main/kotlin/space/kscience/kmath/functions/polynomials.kt).
## Abstract entities (interfaces and abstract classes)
```mermaid
classDiagram
Polynomial <|-- ListPolynomial
Polynomial <|-- NumberedPolynomial
Polynomial <|-- LabeledPolynomial
RationalFunction <|-- ListRationalFunction
RationalFunction <|-- NumberedRationalFunction
RationalFunction <|-- LabeledRationalFunction
Ring <|-- PolynomialSpace
PolynomialSpace <|-- MultivariatePolynomialSpace
PolynomialSpace <|-- PolynomialSpaceOverRing
Ring <|-- RationalFunctionSpace
RationalFunctionSpace <|-- MultivariateRationalFunctionSpace
RationalFunctionSpace <|-- RationalFunctionSpaceOverRing
RationalFunctionSpace <|-- RationalFunctionSpaceOverPolynomialSpace
RationalFunctionSpace <|-- PolynomialSpaceOfFractions
RationalFunctionSpaceOverPolynomialSpace <|-- MultivariateRationalFunctionSpaceOverMultivariatePolynomialSpace
MultivariateRationalFunctionSpace <|-- MultivariateRationalFunctionSpaceOverMultivariatePolynomialSpace
MultivariateRationalFunctionSpace <|-- MultivariatePolynomialSpaceOfFractions
PolynomialSpaceOfFractions <|-- MultivariatePolynomialSpaceOfFractions
```
There are implemented `Polynomial` and `RationalFunction` interfaces as abstractions of polynomials and rational
functions respectively (although, there is not a lot of logic in them) and `PolynomialSpace`
and `RationalFunctionSpace` (that implement `Ring` interface) as abstractions of polynomials' and rational functions'
spaces respectively. More precisely, that means they allow to declare common logic of interaction with such objects and
spaces:
- `Polynomial` does not provide any logic. It is marker interface.
- `RationalFunction` provides numerator and denominator of rational function and destructuring declaration for them.
- `PolynomialSpace` provides all possible arithmetic interactions of integers, constants (of type `C`), and
polynomials (of type `P`) like addition, subtraction, multiplication, and some others and common properties like
degree of polynomial.
- `RationalFunctionSpace` provides the same as `PolynomialSpace` but also for rational functions: all possible
arithmetic interactions of integers, constants (of type `C`), polynomials (of type `P`), and rational functions (of
type `R`) like addition, subtraction, multiplication, division (in some cases), and some others and common properties
like degree of polynomial.
Then to add abstraction of similar behaviour with variables (in multivariate case) there are
implemented `MultivariatePolynomialSpace` and `MultivariateRationalFunctionSpace`. They just include variables (of
type `V`) in the interactions of the entities.
Also, to remove boilerplates there were provided helping subinterfaces and abstract subclasses:
- `PolynomialSpaceOverRing` allows to replace implementation of interactions of integers and constants with
implementations from provided ring over constants (of type `A: Ring<C>`).
- `RationalFunctionSpaceOverRing` &mdash; the same but for `RationalFunctionSpace`.
- `RationalFunctionSpaceOverPolynomialSpace` &mdash; the same but "the inheritance" includes interactions with
polynomials from provided `PolynomialSpace`.
- `PolynomialSpaceOfFractions` is actually abstract subclass of `RationalFunctionSpace` that implements all fractions
boilerplates with provided (`protected`) constructor of rational functions by polynomial numerator and denominator.
- `MultivariateRationalFunctionSpaceOverMultivariatePolynomialSpace` and `MultivariatePolynomialSpaceOfFractions`
&mdash; the same stories of operators inheritance and fractions boilerplates respectively but in multivariate case.
## Utilities
For all kinds of polynomials there are provided (implementation details depend on kind of polynomials) such common
utilities as:
1. differentiation and anti-differentiation,
2. substitution, invocation and functional representation.

View File

@ -3,17 +3,7 @@
The Maven coordinates of this project are `${group}:${name}:${version}`. The Maven coordinates of this project are `${group}:${name}:${version}`.
**Gradle:** **Gradle:**
```gradle
repositories {
maven { url 'https://repo.kotlin.link' }
mavenCentral()
}
dependencies {
implementation '${group}:${name}:${version}'
}
```
**Gradle Kotlin DSL:**
```kotlin ```kotlin
repositories { repositories {
maven("https://repo.kotlin.link") maven("https://repo.kotlin.link")

View File

@ -1,6 +1,6 @@
[![JetBrains Research](https://jb.gg/badges/research.svg)](https://confluence.jetbrains.com/display/ALL/JetBrains+on+GitHub) [![JetBrains Research](https://jb.gg/badges/research.svg)](https://confluence.jetbrains.com/display/ALL/JetBrains+on+GitHub)
[![DOI](https://zenodo.org/badge/129486382.svg)](https://zenodo.org/badge/latestdoi/129486382) [![DOI](https://zenodo.org/badge/129486382.svg)](https://zenodo.org/badge/latestdoi/129486382)
![Gradle build](https://github.com/mipt-npm/kmath/workflows/Gradle%20build/badge.svg) ![Gradle build](https://github.com/SciProgCentre/kmath/workflows/Gradle%20build/badge.svg)
[![Maven Central](https://img.shields.io/maven-central/v/space.kscience/kmath-core.svg?label=Maven%20Central)](https://search.maven.org/search?q=g:%22space.kscience%22) [![Maven Central](https://img.shields.io/maven-central/v/space.kscience/kmath-core.svg?label=Maven%20Central)](https://search.maven.org/search?q=g:%22space.kscience%22)
[![Space](https://img.shields.io/badge/dynamic/xml?color=orange&label=Space&query=//metadata/versioning/latest&url=https%3A%2F%2Fmaven.pkg.jetbrains.space%2Fmipt-npm%2Fp%2Fsci%2Fmaven%2Fspace%2Fkscience%2Fkmath-core%2Fmaven-metadata.xml)](https://maven.pkg.jetbrains.space/mipt-npm/p/sci/maven/space/kscience/) [![Space](https://img.shields.io/badge/dynamic/xml?color=orange&label=Space&query=//metadata/versioning/latest&url=https%3A%2F%2Fmaven.pkg.jetbrains.space%2Fmipt-npm%2Fp%2Fsci%2Fmaven%2Fspace%2Fkscience%2Fkmath-core%2Fmaven-metadata.xml)](https://maven.pkg.jetbrains.space/mipt-npm/p/sci/maven/space/kscience/)
@ -11,18 +11,22 @@ analog to Python's NumPy library. Later we found that kotlin is much more flexib
architecture designs. In contrast to `numpy` and `scipy` it is modular and has a lightweight core. The `numpy`-like architecture designs. In contrast to `numpy` and `scipy` it is modular and has a lightweight core. The `numpy`-like
experience could be achieved with [kmath-for-real](/kmath-for-real) extension module. experience could be achieved with [kmath-for-real](/kmath-for-real) extension module.
[Documentation site (**WIP**)](https://mipt-npm.github.io/kmath/) [Documentation site](https://SciProgCentre.github.io/kmath/)
## Publications and talks ## Publications and talks
* [A conceptual article about context-oriented design](https://proandroiddev.com/an-introduction-context-oriented-programming-in-kotlin-2e79d316b0a2) * [A conceptual article about context-oriented design](https://proandroiddev.com/an-introduction-context-oriented-programming-in-kotlin-2e79d316b0a2)
* [Another article about context-oriented design](https://proandroiddev.com/diving-deeper-into-context-oriented-programming-in-kotlin-3ecb4ec38814) * [Another article about context-oriented design](https://proandroiddev.com/diving-deeper-into-context-oriented-programming-in-kotlin-3ecb4ec38814)
* [ACAT 2019 conference paper](https://aip.scitation.org/doi/abs/10.1063/1.5130103) * [ACAT 2019 conference paper](https://aip.scitation.org/doi/abs/10.1063/1.5130103)
* [A talk at KotlinConf 2019 about using kotlin for science](https://youtu.be/LI_5TZ7tnOE?si=4LknX41gl_YeUbIe)
* [A talk on architecture at Joker-2021 (in Russian)](https://youtu.be/1bZ2doHiRRM?si=9w953ro9yu98X_KJ)
* [The same talk in English](https://youtu.be/yP5DIc2fVwQ?si=louZzQ1dcXV6gP10)
* [A seminar on tensor API](https://youtu.be/0H99wUs0xTM?si=6c__04jrByFQtVpo)
# Goal # Goal
* Provide a flexible and powerful API to work with mathematics abstractions in Kotlin-multiplatform (JVM, JS and Native) * Provide a flexible and powerful API to work with mathematics abstractions in Kotlin-multiplatform (JVM, JS, Native and
. Wasm).
* Provide basic multiplatform implementations for those abstractions (without significant performance optimization). * Provide basic multiplatform implementations for those abstractions (without significant performance optimization).
* Provide bindings and wrappers with those abstractions for popular optimized platform libraries. * Provide bindings and wrappers with those abstractions for popular optimized platform libraries.
@ -44,67 +48,39 @@ module definitions below. The module stability could have the following levels:
* **PROTOTYPE**. On this level there are no compatibility guarantees. All methods and classes form those modules could * **PROTOTYPE**. On this level there are no compatibility guarantees. All methods and classes form those modules could
break any moment. You can still use it, but be sure to fix the specific version. break any moment. You can still use it, but be sure to fix the specific version.
* **EXPERIMENTAL**. The general API is decided, but some changes could be made. Volatile API is marked * **EXPERIMENTAL**. The general API is decided, but some changes could be made. Volatile API is marked
with `@UnstableKmathAPI` or other stability warning annotations. with `@UnstableKMathAPI` or other stability warning annotations.
* **DEVELOPMENT**. API breaking generally follows semantic versioning ideology. There could be changes in minor * **DEVELOPMENT**. API breaking generally follows semantic versioning ideology. There could be changes in minor
versions, but not in patch versions. API is protected versions, but not in patch versions. API is protected
with [binary-compatibility-validator](https://github.com/Kotlin/binary-compatibility-validator) tool. with [binary-compatibility-validator](https://github.com/Kotlin/binary-compatibility-validator) tool.
* **STABLE**. The API stabilized. Breaking changes are allowed only in major releases. * **STABLE**. The API stabilized. Breaking changes are allowed only in major releases.
<!--Current feature list is [here](/docs/features.md)-->
<!--* **Array-like structures** Full support of many-dimensional array-like structures -->
<!--including mixed arithmetic operations and function operations over arrays and numbers (with the added benefit of static type checking).-->
<!--* **Histograms** Fast multi-dimensional histograms.-->
<!--* **Streaming** Streaming operations on mathematical objects and objects buffers.-->
<!--* **Type-safe dimensions** Type-safe dimensions for matrix operations.-->
<!--* **Commons-math wrapper** It is planned to gradually wrap most parts of -->
<!--[Apache commons-math](http://commons.apache.org/proper/commons-math/) library in Kotlin code and maybe rewrite some -->
<!--parts to better suit the Kotlin programming paradigm, however there is no established roadmap for that. Feel free to -->
<!--submit a feature request if you want something to be implemented first.-->
<!-- -->
<!--## Planned features-->
<!--* **Messaging** A mathematical notation to support multi-language and multi-node communication for mathematical tasks.-->
<!--* **Array statistics** -->
<!--* **Integration** Univariate and multivariate integration framework.-->
<!--* **Probability and distributions**-->
<!--* **Fitting** Non-linear curve fitting facilities-->
## Modules ## Modules
$modules ${modules}
## Multi-platform support ## Multi-platform support
KMath is developed as a multi-platform library, which means that most of the interfaces are declared in the KMath is developed as a multi-platform library, which means that most of the interfaces are declared in the
[common source sets](/kmath-core/src/commonMain) and implemented there wherever it is possible. In some cases, features [common source sets](/kmath-core/src/commonMain) and implemented there wherever it is possible. In some cases, features
are delegated to platform-specific implementations even if they could be provided in the common module for performance are delegated to platform-specific implementations even if they could be provided in the common module for performance
reasons. Currently, the Kotlin/JVM is the primary platform, however Kotlin/Native and Kotlin/JS contributions and reasons. Currently, Kotlin/JVM is the primary platform, however, Kotlin/Native and Kotlin/JS contributions and
feedback are also welcome. feedback are also welcome.
## Performance ## Performance
Calculation performance is one of major goals of KMath in the future, but in some cases it is impossible to achieve both Calculation of performance is one of the major goals of KMath in the future, but in some cases it is impossible to
achieve both
performance and flexibility. performance and flexibility.
We expect to focus on creating convenient universal API first and then work on increasing performance for specific We expect to focus on creating a convenient universal API first and then work on increasing performance for specific
cases. We expect the worst KMath benchmarks will perform better than native Python, but worse than optimized cases. We expect the worst KMath benchmarks will perform better than native Python, but worse than optimized
native/SciPy (mostly due to boxing operations on primitive numbers). The best performance of optimized parts could be native/SciPy (mostly due to boxing operations on primitive numbers). The best performance of optimized parts could be
better than SciPy. better than SciPy.
## Requirements ## Requirements
KMath currently relies on JDK 11 for compilation and execution of Kotlin-JVM part. We recommend to use GraalVM-CE 11 for KMath currently relies on JDK 11 for compilation and execution of Kotlin-JVM part. We recommend using GraalVM-CE or
execution to get better performance. Oracle GraalVM for execution to get better performance.
### Repositories ### Repositories
@ -124,11 +100,10 @@ dependencies {
} }
``` ```
Gradle `6.0+` is required for multiplatform artifacts.
## Contributing ## Contributing
The project requires a lot of additional work. The most important thing we need is a feedback about what features are The project requires a lot of additional work. The most important thing we need is feedback about what features are
required the most. Feel free to create feature requests. We are also welcome to code contributions, especially in issues required the most. Feel free to create feature requests. We are also welcome to code contributions, especially in issues
marked with marked
[waiting for a hero](https://github.com/mipt-npm/kmath/labels/waiting%20for%20a%20hero) label. with [good first issue](hhttps://github.com/SciProgCentre/kmath/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22)
label.

4
examples/README.md Normal file
View File

@ -0,0 +1,4 @@
# Module examples

View File

@ -1,3 +1,5 @@
import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile
plugins { plugins {
kotlin("jvm") kotlin("jvm")
} }
@ -5,12 +7,7 @@ plugins {
repositories { repositories {
mavenCentral() mavenCentral()
maven("https://repo.kotlin.link") maven("https://repo.kotlin.link")
maven("https://clojars.org/repo")
maven("https://jitpack.io")
maven("https://maven.pkg.jetbrains.space/kotlin/p/kotlin/kotlin-js-wrappers") maven("https://maven.pkg.jetbrains.space/kotlin/p/kotlin/kotlin-js-wrappers")
maven("http://logicrunch.research.it.uu.se/maven") {
isAllowInsecureProtocol = true
}
} }
dependencies { dependencies {
@ -20,6 +17,8 @@ dependencies {
implementation(project(":kmath-coroutines")) implementation(project(":kmath-coroutines"))
implementation(project(":kmath-commons")) implementation(project(":kmath-commons"))
implementation(project(":kmath-complex")) implementation(project(":kmath-complex"))
implementation(project(":kmath-functions"))
implementation(project(":kmath-optimization"))
implementation(project(":kmath-stat")) implementation(project(":kmath-stat"))
implementation(project(":kmath-viktor")) implementation(project(":kmath-viktor"))
implementation(project(":kmath-dimensions")) implementation(project(":kmath-dimensions"))
@ -28,6 +27,14 @@ dependencies {
implementation(project(":kmath-tensors")) implementation(project(":kmath-tensors"))
implementation(project(":kmath-symja")) implementation(project(":kmath-symja"))
implementation(project(":kmath-for-real")) implementation(project(":kmath-for-real"))
//jafama
implementation(project(":kmath-jafama"))
//multik
implementation(project(":kmath-multik"))
implementation(libs.multik.default)
//datetime
implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.4.0")
implementation("org.nd4j:nd4j-native:1.0.0-beta7") implementation("org.nd4j:nd4j-native:1.0.0-beta7")
@ -41,28 +48,28 @@ dependencies {
// } else // } else
implementation("org.nd4j:nd4j-native-platform:1.0.0-beta7") implementation("org.nd4j:nd4j-native-platform:1.0.0-beta7")
implementation("org.slf4j:slf4j-simple:1.7.31") implementation("org.slf4j:slf4j-simple:1.7.32")
// plotting // plotting
implementation("space.kscience:plotlykt-server:0.4.2") implementation("space.kscience:plotlykt-server:0.7.0")
//jafama
implementation(project(":kmath-jafama"))
} }
kotlin.sourceSets.all { kotlin {
with(languageSettings) { jvmToolchain(11)
useExperimentalAnnotation("kotlin.contracts.ExperimentalContracts") sourceSets.all {
useExperimentalAnnotation("kotlin.ExperimentalUnsignedTypes") languageSettings {
useExperimentalAnnotation("space.kscience.kmath.misc.UnstableKMathAPI") optIn("kotlin.contracts.ExperimentalContracts")
optIn("kotlin.ExperimentalUnsignedTypes")
optIn("space.kscience.kmath.UnstableKMathAPI")
}
} }
} }
tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> { tasks.withType<KotlinJvmCompile> {
kotlinOptions{ compilerOptions {
jvmTarget = "11" freeCompilerArgs.addAll("-Xjvm-default=all", "-Xopt-in=kotlin.RequiresOptIn", "-Xlambdas=indy")
freeCompilerArgs = freeCompilerArgs + "-Xjvm-default=all" + "-Xopt-in=kotlin.RequiresOptIn"
} }
} }
readme { readme {
maturity = ru.mipt.npm.gradle.Maturity.EXPERIMENTAL maturity = space.kscience.gradle.Maturity.EXPERIMENTAL
} }

View File

@ -0,0 +1,418 @@
{
"cells": [
{
"cell_type": "code",
"source": [
"%use kmath(0.3.1-dev-5)\n",
"%use plotly(0.5.0)\n",
"@file:DependsOn(\"space.kscience:kmath-commons:0.3.1-dev-5\")"
],
"execution_count": null,
"outputs": [],
"metadata": {
"datalore": {
"node_id": "lQbSB87rNAn9lV6poArVWW",
"type": "CODE",
"hide_input_from_viewers": false,
"hide_output_from_viewers": false
}
}
},
{
"cell_type": "code",
"source": [
"//Uncomment to work in Jupyter classic or DataLore\n",
"//Plotly.jupyter.notebook()"
],
"execution_count": null,
"outputs": [],
"metadata": {
"datalore": {
"node_id": "0UP158hfccGgjQtHz0wAi6",
"type": "CODE",
"hide_input_from_viewers": false,
"hide_output_from_viewers": false
}
}
},
{
"cell_type": "markdown",
"source": [
"# The model\n",
"\n",
"Defining the input data format, the statistic abstraction and the statistic implementation based on a weighted sum of elements."
],
"metadata": {
"collapsed": false
}
},
{
"cell_type": "code",
"source": [
"class XYValues(val xValues: DoubleArray, val yValues: DoubleArray) {\n",
" init {\n",
" require(xValues.size == yValues.size)\n",
" }\n",
"}\n",
"\n",
"fun interface XYStatistic {\n",
" operator fun invoke(values: XYValues): Double\n",
"}\n",
"\n",
"class ConvolutionalXYStatistic(val weights: DoubleArray) : XYStatistic {\n",
" override fun invoke(values: XYValues): Double {\n",
" require(weights.size == values.yValues.size)\n",
" val norm = values.yValues.sum()\n",
" return values.yValues.zip(weights) { value, weight -> value * weight }.sum()/norm\n",
" }\n",
"}"
],
"execution_count": null,
"outputs": [],
"metadata": {
"datalore": {
"node_id": "Zhgz1Ui91PWz0meJiQpHol",
"type": "CODE",
"hide_input_from_viewers": false,
"hide_output_from_viewers": false
}
}
},
{
"cell_type": "markdown",
"source": [
"# Generator\n",
"Generate sample data for parabolas and hyperbolas"
],
"metadata": {
"collapsed": false
}
},
{
"cell_type": "code",
"execution_count": null,
"outputs": [],
"source": [
"fun generateParabolas(xValues: DoubleArray, a: Double, b: Double, c: Double): XYValues {\n",
" val yValues = xValues.map { x -> a * x * x + b * x + c }.toDoubleArray()\n",
" return XYValues(xValues, yValues)\n",
"}\n",
"\n",
"fun generateHyperbols(xValues: DoubleArray, gamma: Double, x0: Double, y0: Double): XYValues {\n",
" val yValues = xValues.map { x -> y0 + gamma / (x - x0) }.toDoubleArray()\n",
" return XYValues(xValues, yValues)\n",
"}"
],
"metadata": {
"collapsed": false
}
},
{
"cell_type": "code",
"source": [
"val xValues = (1.0..10.0).step(1.0).toDoubleArray()\n",
"\n",
"val xy = generateHyperbols(xValues, 1.0, 0.0, 0.0)\n",
"\n",
"Plotly.plot {\n",
" scatter {\n",
" this.x.doubles = xValues\n",
" this.y.doubles = xy.yValues\n",
" }\n",
"}"
],
"execution_count": null,
"outputs": [],
"metadata": {
"datalore": {
"node_id": "ZE2atNvFzQsCvpAF8KK4ch",
"type": "CODE",
"hide_input_from_viewers": false,
"hide_output_from_viewers": false
}
}
},
{
"cell_type": "markdown",
"source": [
"Create a default statistic with uniform weights"
],
"metadata": {
"collapsed": false
}
},
{
"cell_type": "code",
"source": [
"val statistic = ConvolutionalXYStatistic(DoubleArray(xValues.size){1.0})\n",
"statistic(xy)"
],
"execution_count": null,
"outputs": [],
"metadata": {
"datalore": {
"node_id": "EA5HaydTddRKYrtAUwd29h",
"type": "CODE",
"hide_input_from_viewers": false,
"hide_output_from_viewers": false
}
}
},
{
"cell_type": "code",
"source": [
"import kotlin.random.Random\n",
"\n",
"val random = Random(1288)\n",
"\n",
"val parabolas = buildList{\n",
" repeat(500){\n",
" add(\n",
" generateParabolas(\n",
" xValues, \n",
" random.nextDouble(), \n",
" random.nextDouble(), \n",
" random.nextDouble()\n",
" )\n",
" )\n",
" }\n",
"}\n",
"\n",
"val hyperbolas: List<XYValues> = buildList{\n",
" repeat(500){\n",
" add(\n",
" generateHyperbols(\n",
" xValues, \n",
" random.nextDouble()*10, \n",
" random.nextDouble(), \n",
" random.nextDouble()\n",
" )\n",
" )\n",
" }\n",
"}"
],
"execution_count": null,
"outputs": [],
"metadata": {
"datalore": {
"node_id": "t5t6IYmD7Q1ykeo9uijFfQ",
"type": "CODE",
"hide_input_from_viewers": false,
"hide_output_from_viewers": false
}
}
},
{
"cell_type": "code",
"source": [
"Plotly.plot { \n",
" scatter { \n",
" x.doubles = xValues\n",
" y.doubles = parabolas[257].yValues\n",
" }\n",
" scatter { \n",
" x.doubles = xValues\n",
" y.doubles = hyperbolas[252].yValues\n",
" }\n",
" }"
],
"execution_count": null,
"outputs": [],
"metadata": {
"datalore": {
"node_id": "oXB8lmju7YVYjMRXITKnhO",
"type": "CODE",
"hide_input_from_viewers": false,
"hide_output_from_viewers": false
}
}
},
{
"cell_type": "code",
"source": [
"Plotly.plot { \n",
" histogram { \n",
" name = \"parabolae\"\n",
" x.numbers = parabolas.map { statistic(it) }\n",
" }\n",
" histogram { \n",
" name = \"hyperbolae\"\n",
" x.numbers = hyperbolas.map { statistic(it) }\n",
" }\n",
"}"
],
"execution_count": null,
"outputs": [],
"metadata": {
"datalore": {
"node_id": "8EIIecUZrt2NNrOkhxG5P0",
"type": "CODE",
"hide_input_from_viewers": false,
"hide_output_from_viewers": false
}
}
},
{
"cell_type": "code",
"source": [
"val lossFunction: (XYStatistic) -> Double = { statistic ->\n",
" - abs(parabolas.sumOf { statistic(it) } - hyperbolas.sumOf { statistic(it) })\n",
"}"
],
"execution_count": null,
"outputs": [],
"metadata": {
"datalore": {
"node_id": "h7UmglJW5zXkAfKHK40oIL",
"type": "CODE",
"hide_input_from_viewers": false,
"hide_output_from_viewers": false
}
}
},
{
"cell_type": "markdown",
"source": [
"Using commons-math optimizer to optimize weights"
],
"metadata": {
"collapsed": false
}
},
{
"cell_type": "code",
"source": [
"import org.apache.commons.math3.optim.*\n",
"import org.apache.commons.math3.optim.nonlinear.scalar.*\n",
"import org.apache.commons.math3.optim.nonlinear.scalar.noderiv.*\n",
"\n",
"val optimizer = SimplexOptimizer(1e-1, Double.MAX_VALUE)\n",
"\n",
"val result = optimizer.optimize(\n",
" ObjectiveFunction { point ->\n",
" lossFunction(ConvolutionalXYStatistic(point))\n",
" },\n",
" NelderMeadSimplex(xValues.size),\n",
" InitialGuess(DoubleArray(xValues.size){ 1.0 }),\n",
" GoalType.MINIMIZE,\n",
" MaxEval(100000)\n",
")"
],
"execution_count": null,
"outputs": [],
"metadata": {
"datalore": {
"node_id": "0EG3K4aCUciMlgGQKPvJ57",
"type": "CODE",
"hide_input_from_viewers": false,
"hide_output_from_viewers": false
}
}
},
{
"cell_type": "markdown",
"source": [
"Print resulting weights of optimization"
],
"metadata": {
"collapsed": false
}
},
{
"cell_type": "code",
"source": [
"result.point"
],
"execution_count": null,
"outputs": [],
"metadata": {
"datalore": {
"node_id": "LelUlY0ZSlJEO9yC6SLk5B",
"type": "CODE",
"hide_input_from_viewers": false,
"hide_output_from_viewers": false
}
}
},
{
"cell_type": "code",
"source": [
"Plotly.plot { \n",
" scatter { \n",
" y.doubles = result.point\n",
" }\n",
"}"
],
"execution_count": null,
"outputs": [],
"metadata": {
"datalore": {
"node_id": "AuFOq5t9KpOIkGrOLsVXNf",
"type": "CODE",
"hide_input_from_viewers": false,
"hide_output_from_viewers": false
}
}
},
{
"cell_type": "markdown",
"source": [
"# The resulting statistic distribution"
],
"metadata": {
"collapsed": false
}
},
{
"cell_type": "code",
"source": [
"val resultStatistic = ConvolutionalXYStatistic(result.point)\n",
"Plotly.plot { \n",
" histogram { \n",
" name = \"parabolae\"\n",
" x.numbers = parabolas.map { resultStatistic(it) }\n",
" }\n",
" histogram { \n",
" name = \"hyperbolae\"\n",
" x.numbers = hyperbolas.map { resultStatistic(it) }\n",
" }\n",
"}"
],
"execution_count": null,
"outputs": [],
"metadata": {
"datalore": {
"node_id": "zvmq42DRdM5mZ3SpzviHwI",
"type": "CODE",
"hide_input_from_viewers": false,
"hide_output_from_viewers": false
}
}
},
{
"cell_type": "code",
"execution_count": null,
"outputs": [],
"source": [],
"metadata": {
"collapsed": false
}
}
],
"metadata": {
"kernelspec": {
"display_name": "Kotlin",
"language": "kotlin",
"name": "kotlin"
},
"datalore": {
"version": 1,
"computation_mode": "JUPYTER",
"package_manager": "pip",
"base_environment": "default",
"packages": []
}
},
"nbformat": 4,
"nbformat_minor": 4
}

View File

@ -1,6 +1,6 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2024 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
package space.kscience.kmath.ast package space.kscience.kmath.ast

View File

@ -1,22 +1,26 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2024 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
package space.kscience.kmath.ast package space.kscience.kmath.ast
import space.kscience.kmath.expressions.MstField import space.kscience.kmath.asm.compileToExpression
import space.kscience.kmath.expressions.MstExtendedField
import space.kscience.kmath.expressions.Symbol.Companion.x import space.kscience.kmath.expressions.Symbol.Companion.x
import space.kscience.kmath.expressions.interpret import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.operations.DoubleField
import space.kscience.kmath.operations.invoke import space.kscience.kmath.operations.invoke
fun main() { fun main() {
val expr = MstField { val expr = MstExtendedField {
x * 2.0 + number(2.0) / x - 16.0 x * 2.0 + number(2.0) / x - number(16.0) + asinh(x) / sin(x)
} }.compileToExpression(Float64Field)
val m = DoubleArray(expr.indexer.symbols.size)
val xIdx = expr.indexer.indexOf(x)
repeat(10000000) { repeat(10000000) {
expr.interpret(DoubleField, x to 1.0) m[xIdx] = 1.0
expr(m)
} }
} }

View File

@ -1,16 +1,16 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2024 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
package space.kscience.kmath.ast package space.kscience.kmath.ast
import space.kscience.kmath.expressions.Symbol.Companion.x
import space.kscience.kmath.expressions.derivative import space.kscience.kmath.expressions.derivative
import space.kscience.kmath.expressions.invoke import space.kscience.kmath.expressions.invoke
import space.kscience.kmath.expressions.Symbol.Companion.x
import space.kscience.kmath.expressions.toExpression import space.kscience.kmath.expressions.toExpression
import space.kscience.kmath.kotlingrad.toKotlingradExpression import space.kscience.kmath.kotlingrad.toKotlingradExpression
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Float64Field
/** /**
* In this example, *x<sup>2</sup> &minus; 4 x &minus; 44* function is differentiated with Kotlin, and the * In this example, *x<sup>2</sup> &minus; 4 x &minus; 44* function is differentiated with Kotlin, and the
@ -19,9 +19,9 @@ import space.kscience.kmath.operations.DoubleField
fun main() { fun main() {
val actualDerivative = "x^2-4*x-44" val actualDerivative = "x^2-4*x-44"
.parseMath() .parseMath()
.toKotlingradExpression(DoubleField) .toKotlingradExpression(Float64Field)
.derivative(x) .derivative(x)
val expectedDerivative = "2*x-4".parseMath().toExpression(DoubleField) val expectedDerivative = "2*x-4".parseMath().toExpression(Float64Field)
check(actualDerivative(x to 123.0) == expectedDerivative(x to 123.0)) check(actualDerivative(x to 123.0) == expectedDerivative(x to 123.0))
} }

View File

@ -1,6 +1,6 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2024 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
package space.kscience.kmath.ast package space.kscience.kmath.ast
@ -9,7 +9,7 @@ import space.kscience.kmath.expressions.Symbol.Companion.x
import space.kscience.kmath.expressions.derivative import space.kscience.kmath.expressions.derivative
import space.kscience.kmath.expressions.invoke import space.kscience.kmath.expressions.invoke
import space.kscience.kmath.expressions.toExpression import space.kscience.kmath.expressions.toExpression
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.symja.toSymjaExpression import space.kscience.kmath.symja.toSymjaExpression
/** /**
@ -19,9 +19,9 @@ import space.kscience.kmath.symja.toSymjaExpression
fun main() { fun main() {
val actualDerivative = "x^2-4*x-44" val actualDerivative = "x^2-4*x-44"
.parseMath() .parseMath()
.toSymjaExpression(DoubleField) .toSymjaExpression(Float64Field)
.derivative(x) .derivative(x)
val expectedDerivative = "2*x-4".parseMath().toExpression(DoubleField) val expectedDerivative = "2*x-4".parseMath().toExpression(Float64Field)
check(actualDerivative(x to 123.0) == expectedDerivative(x to 123.0)) check(actualDerivative(x to 123.0) == expectedDerivative(x to 123.0))
} }

View File

@ -0,0 +1,92 @@
/*
* Copyright 2018-2024 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package space.kscience.kmath.expressions
import space.kscience.kmath.UnstableKMathAPI
// Only kmath-core is needed.
// Let's declare some variables
val x by symbol
val y by symbol
val z by symbol
@OptIn(UnstableKMathAPI::class)
fun main() {
// Let's define some random expression.
val someExpression = Double.autodiff.differentiate {
// We bind variables `x` and `y` to the builder scope,
val x = bindSymbol(x)
val y = bindSymbol(y)
// Then we use the bindings to define expression `xy + x + y - 1`
x * y + x + y - 1
}
// Then we can evaluate it at any point ((-1, -1) in the case):
println(someExpression(x to -1.0, y to -1.0))
// >>> -2.0
// We can also construct its partial derivatives:
val dxExpression = someExpression.derivative(x) // ∂/∂x. Must be `y+1`
val dyExpression = someExpression.derivative(y) // ∂/∂y. Must be `x+1`
val dxdxExpression = someExpression.derivative(x, x) // ∂^2/∂x^2. Must be `0`
// We can evaluate them as well
println(dxExpression(x to 57.0, y to 6.0))
// >>> 7.0
println(dyExpression(x to -1.0, y to 179.0))
// >>> 0.0
println(dxdxExpression(x to 239.0, y to 30.0))
// >>> 0.0
// You can also provide extra arguments that obviously won't affect the result:
println(dxExpression(x to 57.0, y to 6.0, z to 42.0))
// >>> 7.0
println(dyExpression(x to -1.0, y to 179.0, z to 0.0))
// >>> 0.0
println(dxdxExpression(x to 239.0, y to 30.0, z to 100_000.0))
// >>> 0.0
// But in case you forgot to specify bound symbol's value, exception is thrown:
println(runCatching { someExpression(z to 4.0) })
// >>> Failure(java.lang.IllegalStateException: Symbol 'x' is not supported in ...)
// The reason is that the expression is evaluated lazily,
// and each `bindSymbol` operation actually substitutes the provided symbol with the corresponding value.
// For example, let there be an expression
val simpleExpression = Double.autodiff.differentiate {
val x = bindSymbol(x)
x pow 2
}
// When you evaluate it via
simpleExpression(x to 1.0, y to 57.0, z to 179.0)
// lambda above has the context of map `{x: 1.0, y: 57.0, z: 179.0}`.
// When x is bound, you can think of it as substitution `x -> 1.0`.
// Other values are unused which does not make any problem to us.
// But in the case the corresponding value is not provided,
// we cannot bind the variable. Thus, exception is thrown.
// There is also a function `bindSymbolOrNull` that fixes the problem:
val fixedExpression = Double.autodiff.differentiate {
val x = bindSymbolOrNull(x) ?: const(8.0)
x pow -2
}
println(fixedExpression())
// >>> 0.015625
// It works!
// The expression provides a bunch of operations:
// 1. Constant bindings (via `const` and `number`).
// 2. Variable bindings (via `bindVariable`, `bindVariableOrNull`).
// 3. Arithmetic operations (via `+`, `-`, `*`, and `-`).
// 4. Exponentiation (via `pow` or `power`).
// 5. `exp` and `ln`.
// 6. Trigonometrical functions (`sin`, `cos`, `tan`, `cot`).
// 7. Inverse trigonometrical functions (`asin`, `acos`, `atan`, `acot`).
// 8. Hyperbolic functions and inverse hyperbolic functions.
}

View File

@ -1,24 +1,24 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2024 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
package space.kscience.kmath.commons.fit package space.kscience.kmath.fit
import kotlinx.html.br import kotlinx.html.br
import kotlinx.html.h3 import kotlinx.html.h3
import space.kscience.kmath.commons.optimization.chiSquared import space.kscience.kmath.commons.optimization.CMOptimizer
import space.kscience.kmath.commons.optimization.minimize
import space.kscience.kmath.distributions.NormalDistribution import space.kscience.kmath.distributions.NormalDistribution
import space.kscience.kmath.expressions.autodiff
import space.kscience.kmath.expressions.symbol import space.kscience.kmath.expressions.symbol
import space.kscience.kmath.optimization.FunctionOptimization import space.kscience.kmath.operations.asIterable
import space.kscience.kmath.optimization.OptimizationResult import space.kscience.kmath.operations.toList
import space.kscience.kmath.optimization.*
import space.kscience.kmath.random.RandomGenerator
import space.kscience.kmath.real.DoubleVector import space.kscience.kmath.real.DoubleVector
import space.kscience.kmath.real.map import space.kscience.kmath.real.map
import space.kscience.kmath.real.step import space.kscience.kmath.real.step
import space.kscience.kmath.stat.RandomGenerator import space.kscience.kmath.stat.chiSquaredExpression
import space.kscience.kmath.structures.asIterable
import space.kscience.kmath.structures.toList
import space.kscience.plotly.* import space.kscience.plotly.*
import space.kscience.plotly.models.ScatterMode import space.kscience.plotly.models.ScatterMode
import space.kscience.plotly.models.TraceValues import space.kscience.plotly.models.TraceValues
@ -42,7 +42,7 @@ operator fun TraceValues.invoke(vector: DoubleVector) {
*/ */
suspend fun main() { suspend fun main() {
//A generator for a normally distributed values //A generator for a normally distributed values
val generator = NormalDistribution(2.0, 7.0) val generator = NormalDistribution(0.0, 1.0)
//A chain/flow of random values with the given seed //A chain/flow of random values with the given seed
val chain = generator.sample(RandomGenerator.default(112667)) val chain = generator.sample(RandomGenerator.default(112667))
@ -53,7 +53,7 @@ suspend fun main() {
//Perform an operation on each x value (much more effective, than numpy) //Perform an operation on each x value (much more effective, than numpy)
val y = x.map { val y = x.map { it ->
val value = it.pow(2) + it + 1 val value = it.pow(2) + it + 1
value + chain.next() * sqrt(value) value + chain.next() * sqrt(value)
} }
@ -64,17 +64,22 @@ suspend fun main() {
val yErr = y.map { sqrt(it) }//RealVector.same(x.size, sigma) val yErr = y.map { sqrt(it) }//RealVector.same(x.size, sigma)
// compute differentiable chi^2 sum for given model ax^2 + bx + c // compute differentiable chi^2 sum for given model ax^2 + bx + c
val chi2 = FunctionOptimization.chiSquared(x, y, yErr) { x1 -> val chi2 = Double.autodiff.chiSquaredExpression(x, y, yErr) { arg ->
//bind variables to autodiff context //bind variables to autodiff context
val a = bindSymbol(a) val a = bindSymbol(a)
val b = bindSymbol(b) val b = bindSymbol(b)
//Include default value for c if it is not provided as a parameter //Include default value for c if it is not provided as a parameter
val c = bindSymbolOrNull(c) ?: one val c = bindSymbolOrNull(c) ?: one
a * x1.pow(2) + b * x1 + c a * arg.pow(2) + b * arg + c
} }
//minimize the chi^2 in given starting point. Derivatives are not required, they are already included. //minimize the chi^2 in given starting point. Derivatives are not required, they are already included.
val result: OptimizationResult<Double> = chi2.minimize(a to 1.5, b to 0.9, c to 1.0) val result = chi2.optimizeWith(
CMOptimizer,
mapOf(a to 1.5, b to 0.9, c to 1.0),
) {
FunctionOptimizationTarget(OptimizationDirection.MINIMIZE)
}
//display a page with plot and numerical results //display a page with plot and numerical results
val page = Plotly.page { val page = Plotly.page {
@ -91,7 +96,7 @@ suspend fun main() {
scatter { scatter {
mode = ScatterMode.lines mode = ScatterMode.lines
x(x) x(x)
y(x.map { result.point[a]!! * it.pow(2) + result.point[b]!! * it + 1 }) y(x.map { result.result[a]!! * it.pow(2) + result.result[b]!! * it + 1 })
name = "fit" name = "fit"
} }
} }
@ -100,7 +105,7 @@ suspend fun main() {
+"Fit result: $result" +"Fit result: $result"
} }
h3 { h3 {
+"Chi2/dof = ${result.value / (x.size - 3)}" +"Chi2/dof = ${result.resultValue / (x.size - 3)}"
} }
} }

View File

@ -0,0 +1,112 @@
/*
* Copyright 2018-2024 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package space.kscience.kmath.fit
import kotlinx.html.br
import kotlinx.html.h3
import space.kscience.attributes.Attributes
import space.kscience.kmath.data.XYErrorColumnarData
import space.kscience.kmath.distributions.NormalDistribution
import space.kscience.kmath.expressions.Symbol
import space.kscience.kmath.expressions.autodiff
import space.kscience.kmath.expressions.binding
import space.kscience.kmath.expressions.symbol
import space.kscience.kmath.operations.asIterable
import space.kscience.kmath.operations.toList
import space.kscience.kmath.optimization.*
import space.kscience.kmath.random.RandomGenerator
import space.kscience.kmath.real.map
import space.kscience.kmath.real.step
import space.kscience.plotly.*
import space.kscience.plotly.models.ScatterMode
import kotlin.math.abs
import kotlin.math.pow
import kotlin.math.sqrt
// Forward declaration of symbols that will be used in expressions.
private val a by symbol
private val b by symbol
private val c by symbol
private val d by symbol
private val e by symbol
/**
* Least squares fie with auto-differentiation. Uses `kmath-commons` and `kmath-for-real` modules.
*/
suspend fun main() {
//A generator for a normally distributed values
val generator = NormalDistribution(0.0, 1.0)
//A chain/flow of random values with the given seed
val chain = generator.sample(RandomGenerator.default(112667))
//Create a uniformly distributed x values like numpy.arrange
val x = 1.0..100.0 step 1.0
//Perform an operation on each x value (much more effective, than numpy)
val y = x.map { it ->
val value = it.pow(2) + it + 1
value + chain.next() * sqrt(value)
}
// this will also work, but less effective:
// val y = x.pow(2)+ x + 1 + chain.nextDouble()
// create same errors for all xs
val yErr = y.map { sqrt(abs(it)) }
require(yErr.asIterable().all { it > 0 }) { "All errors must be strictly positive" }
val result = XYErrorColumnarData.of(x, y, yErr).fitWith(
QowOptimizer,
Double.autodiff,
mapOf(a to 0.9, b to 1.2, c to 2.0, e to 1.0, d to 1.0, e to 0.0),
attributes = Attributes(OptimizationParameters, listOf(a, b, c, d))
) { arg ->
//bind variables to autodiff context
val a by binding
val b by binding
//Include default value for c if it is not provided as a parameter
val c = bindSymbolOrNull(c) ?: one
val d by binding
val e by binding
a * arg.pow(2) + b * arg + c + d * arg.pow(3) + e / arg
}
println("Resulting chi2/dof: ${result.chiSquaredOrNull}/${result.dof}")
//display a page with plot and numerical results
val page = Plotly.page {
plot {
scatter {
mode = ScatterMode.markers
x(x)
y(y)
error_y {
array = yErr.toList()
}
name = "data"
}
scatter {
mode = ScatterMode.lines
x(x)
y(x.map { result.model(result.startPoint + result.result + (Symbol.x to it)) })
name = "fit"
}
}
br()
h3 {
+"Fit result: ${result.result}"
}
h3 {
+"Chi2/dof = ${result.chiSquaredOrNull!! / result.dof}"
}
}
page.makeFile()
}

View File

@ -1,23 +1,37 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2024 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
package space.kscience.kmath.functions package space.kscience.kmath.functions
import space.kscience.kmath.complex.Complex
import space.kscience.kmath.complex.ComplexField
import space.kscience.kmath.complex.ComplexField.div
import space.kscience.kmath.complex.ComplexField.minus
import space.kscience.kmath.complex.algebra
import space.kscience.kmath.integration.gaussIntegrator import space.kscience.kmath.integration.gaussIntegrator
import space.kscience.kmath.integration.integrate import space.kscience.kmath.integration.integrate
import space.kscience.kmath.integration.value import space.kscience.kmath.integration.value
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.structures.Float64
import kotlin.math.pow import kotlin.math.pow
fun main() { fun main() {
//Define a function //Define a function
val function: UnivariateFunction<Double> = { x -> 3 * x.pow(2) + 2 * x + 1 } val function: Function1D<Float64> = { x -> 3 * x.pow(2) + 2 * x + 1 }
//get the result of the integration //get the result of the integration
val result = DoubleField.gaussIntegrator.integrate(0.0..10.0, function = function) val result = Float64Field.gaussIntegrator.integrate(0.0..10.0, function = function)
//the value is nullable because in some cases the integration could not succeed //the value is nullable because in some cases the integration could not succeed
println(result.value) println(result.value)
repeat(100000) {
Complex.algebra.gaussIntegrator.integrate(0.0..1.0, intervals = 1000) { x: Double ->
// sin(1 / x) + i * cos(1 / x)
1 / x - ComplexField.i / x
}.value
}
} }

View File

@ -1,14 +1,14 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2024 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
package space.kscience.kmath.functions package space.kscience.kmath.functions
import space.kscience.kmath.interpolation.SplineInterpolator import space.kscience.kmath.interpolation.SplineInterpolator
import space.kscience.kmath.interpolation.interpolatePolynomials import space.kscience.kmath.interpolation.interpolatePolynomials
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.structures.DoubleBuffer import space.kscience.kmath.structures.Float64
import space.kscience.plotly.Plotly import space.kscience.plotly.Plotly
import space.kscience.plotly.UnstablePlotlyAPI import space.kscience.plotly.UnstablePlotlyAPI
import space.kscience.plotly.makeFile import space.kscience.plotly.makeFile
@ -24,11 +24,9 @@ fun main() {
x to sin(x) x to sin(x)
} }
val polynomial: PiecewisePolynomial<Double> = SplineInterpolator( val polynomial: PiecewisePolynomial<Float64> = SplineInterpolator(Float64Field).interpolatePolynomials(data)
DoubleField, ::DoubleBuffer
).interpolatePolynomials(data)
val function = polynomial.asFunction(DoubleField, 0.0) val function = polynomial.asFunction(Float64Field, 0.0)
val cmInterpolate = org.apache.commons.math3.analysis.interpolation.SplineInterpolator().interpolate( val cmInterpolate = org.apache.commons.math3.analysis.interpolation.SplineInterpolator().interpolate(
data.map { it.first }.toDoubleArray(), data.map { it.first }.toDoubleArray(),

View File

@ -1,15 +1,16 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2024 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
package space.kscience.kmath.functions package space.kscience.kmath.functions
import space.kscience.kmath.interpolation.SplineInterpolator
import space.kscience.kmath.interpolation.interpolatePolynomials import space.kscience.kmath.interpolation.interpolatePolynomials
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.interpolation.splineInterpolator
import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.real.map
import space.kscience.kmath.real.step import space.kscience.kmath.real.step
import space.kscience.kmath.structures.map import space.kscience.kmath.structures.Float64
import space.kscience.plotly.Plotly import space.kscience.plotly.Plotly
import space.kscience.plotly.UnstablePlotlyAPI import space.kscience.plotly.UnstablePlotlyAPI
import space.kscience.plotly.makeFile import space.kscience.plotly.makeFile
@ -18,7 +19,7 @@ import space.kscience.plotly.scatter
@OptIn(UnstablePlotlyAPI::class) @OptIn(UnstablePlotlyAPI::class)
fun main() { fun main() {
val function: UnivariateFunction<Double> = { x -> val function: Function1D<Float64> = { x ->
if (x in 30.0..50.0) { if (x in 30.0..50.0) {
1.0 1.0
} else { } else {
@ -28,9 +29,9 @@ fun main() {
val xs = 0.0..100.0 step 0.5 val xs = 0.0..100.0 step 0.5
val ys = xs.map(function) val ys = xs.map(function)
val polynomial: PiecewisePolynomial<Double> = SplineInterpolator.double.interpolatePolynomials(xs, ys) val polynomial: PiecewisePolynomial<Float64> = Float64Field.splineInterpolator.interpolatePolynomials(xs, ys)
val polyFunction = polynomial.asFunction(DoubleField, 0.0) val polyFunction = polynomial.asFunction(Float64Field, 0.0)
Plotly.plot { Plotly.plot {
scatter { scatter {

View File

@ -1,6 +1,6 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2024 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
package space.kscience.kmath.functions package space.kscience.kmath.functions
@ -9,25 +9,25 @@ import space.kscience.kmath.integration.gaussIntegrator
import space.kscience.kmath.integration.integrate import space.kscience.kmath.integration.integrate
import space.kscience.kmath.integration.value import space.kscience.kmath.integration.value
import space.kscience.kmath.nd.StructureND import space.kscience.kmath.nd.StructureND
import space.kscience.kmath.nd.nd import space.kscience.kmath.nd.structureND
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.nd.withNdAlgebra
import space.kscience.kmath.operations.invoke import space.kscience.kmath.operations.algebra
import space.kscience.kmath.structures.Float64
import kotlin.math.pow
fun main(): Unit = DoubleField { fun main(): Unit = Double.algebra.withNdAlgebra(2, 2) {
nd(2, 2) {
//Produce a diagonal StructureND //Produce a diagonal StructureND
fun diagonal(v: Double) = produce { (i, j) -> fun diagonal(v: Double) = structureND { (i, j) ->
if (i == j) v else 0.0 if (i == j) v else 0.0
} }
//Define a function in a nd space //Define a function in a nd space
val function: (Double) -> StructureND<Double> = { x: Double -> 3 * number(x).pow(2) + 2 * diagonal(x) + 1 } val function: (Double) -> StructureND<Float64> = { x: Double -> 3 * x.pow(2) + 2 * diagonal(x) + 1 }
//get the result of the integration //get the result of the integration
val result = gaussIntegrator.integrate(0.0..10.0, function = function) val result = gaussIntegrator.integrate(0.0..10.0, function = function)
//the value is nullable because in some cases the integration could not succeed //the value is nullable because in some cases the integration could not succeed
println(result.value) println(result.value)
}
} }

View File

@ -1,6 +1,6 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2024 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
package space.kscience.kmath.jafama package space.kscience.kmath.jafama

View File

@ -0,0 +1,31 @@
/*
* Copyright 2018-2024 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package space.kscience.kmath.linear
import kotlin.random.Random
import kotlin.time.measureTime
fun main() = with(Float64ParallelLinearSpace) {
val random = Random(12224)
val dim = 1000
//creating invertible matrix
val matrix1 = buildMatrix(dim, dim) { i, j ->
if (i <= j) random.nextDouble() else 0.0
}
val matrix2 = buildMatrix(dim, dim) { i, j ->
if (i <= j) random.nextDouble() else 0.0
}
val time = measureTime {
repeat(30) {
matrix1 dot matrix2
}
}
println(time)
}

View File

@ -0,0 +1,40 @@
/*
* Copyright 2018-2024 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package space.kscience.kmath.linear
import space.kscience.kmath.commons.linear.CMLinearSpace
import space.kscience.kmath.ejml.EjmlLinearSpaceDDRM
import space.kscience.kmath.nd.StructureND
import space.kscience.kmath.operations.algebra
import space.kscience.kmath.structures.Float64
import kotlin.random.Random
fun main() {
val dim = 46
val random = Random(123)
val u = Float64.algebra.linearSpace.buildMatrix(dim, dim) { i, j -> if (i <= j) random.nextDouble() else 0.0 }
listOf(CMLinearSpace, EjmlLinearSpaceDDRM).forEach { algebra ->
with(algebra) {
//create a simmetric matrix
val matrix = buildMatrix(dim, dim) { row, col ->
if (row >= col) u[row, col] else u[col, row]
}
val eigen = matrix.getOrComputeAttribute(EIG) ?: error("Failed to compute eigenvalue decomposition")
check(
StructureND.contentEquals(
matrix,
eigen.v dot eigen.d dot eigen.v.transposed(),
1e-4
)
) { "$algebra decomposition failed" }
println("$algebra eigenvalue decomposition complete and checked" )
}
}
}

View File

@ -1,27 +1,28 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2024 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
package space.kscience.kmath.linear package space.kscience.kmath.linear
import space.kscience.kmath.real.* import space.kscience.kmath.real.*
import space.kscience.kmath.structures.DoubleBuffer import space.kscience.kmath.structures.Float64
import space.kscience.kmath.structures.Float64Buffer
fun main() { fun main() {
val x0 = DoubleVector(0.0, 0.0, 0.0) val x0 = DoubleVector(0.0, 0.0, 0.0)
val sigma = DoubleVector(1.0, 1.0, 1.0) val sigma = DoubleVector(1.0, 1.0, 1.0)
val gaussian: (Point<Double>) -> Double = { x -> val gaussian: (Point<Float64>) -> Double = { x ->
require(x.size == x0.size) require(x.size == x0.size)
kotlin.math.exp(-((x - x0) / sigma).square().sum()) kotlin.math.exp(-((x - x0) / sigma).square().sum())
} }
fun ((Point<Double>) -> Double).grad(x: Point<Double>): Point<Double> { fun ((Point<Float64>) -> Double).grad(x: Point<Float64>): Point<Float64> {
require(x.size == x0.size) require(x.size == x0.size)
return DoubleBuffer(x.size) { i -> return Float64Buffer(x.size) { i ->
val h = sigma[i] / 5 val h = sigma[i] / 5
val dVector = DoubleBuffer(x.size) { if (it == i) h else 0.0 } val dVector = Float64Buffer(x.size) { if (it == i) h else 0.0 }
val f1 = this(x + dVector / 2) val f1 = this(x + dVector / 2)
val f0 = this(x - dVector / 2) val f0 = this(x - dVector / 2)
(f1 - f0) / h (f1 - f0) / h

View File

@ -0,0 +1,27 @@
/*
* Copyright 2018-2024 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package space.kscience.kmath.linear
import kotlin.random.Random
import kotlin.time.measureTime
fun main(): Unit = with(Float64LinearSpace) {
val random = Random(1224)
val dim = 500
//creating invertible matrix
val u = buildMatrix(dim, dim) { i, j -> if (i <= j) random.nextDouble() else 0.0 }
val l = buildMatrix(dim, dim) { i, j -> if (i >= j) random.nextDouble() else 0.0 }
val matrix = l dot u
val time = measureTime {
repeat(20) {
lupSolver().inverse(matrix)
}
}
println(time)
}

View File

@ -1,6 +1,6 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2024 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
package space.kscience.kmath.operations package space.kscience.kmath.operations

View File

@ -1,29 +0,0 @@
/*
* Copyright 2018-2021 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
*/
package space.kscience.kmath.operations
import space.kscience.kmath.complex.Complex
import space.kscience.kmath.complex.complex
import space.kscience.kmath.nd.AlgebraND
fun main() {
// 2d element
val element = AlgebraND.complex(2, 2).produce { (i, j) ->
Complex(i.toDouble() - j.toDouble(), i.toDouble() + j.toDouble())
}
println(element)
// 1d element operation
val result = with(AlgebraND.complex(8)) {
val a = produce { (it) -> i * it - it.toDouble() }
val b = 3
val c = Complex(1.0, 1.0)
(a pow b) + c
}
println(result)
}

View File

@ -0,0 +1,40 @@
/*
* Copyright 2018-2024 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package space.kscience.kmath.operations
import space.kscience.kmath.complex.Complex
import space.kscience.kmath.complex.algebra
import space.kscience.kmath.complex.ndAlgebra
import space.kscience.kmath.nd.BufferND
import space.kscience.kmath.nd.StructureND
import space.kscience.kmath.nd.structureND
fun main() = Complex.algebra {
val complex = 2 + 2 * i
println(complex * 8 - 5 * i)
//flat buffer
val buffer = with(bufferAlgebra) {
buffer(8) { Complex(it, -it) }.map { Complex(it.im, it.re) }
}
println(buffer)
// 2d element
val element: BufferND<Complex> = ndAlgebra.structureND(2, 2) { (i, j) ->
Complex(i - j, i + j)
}
println(element)
// 1d element operation
val result: StructureND<Complex> = ndAlgebra {
val a = structureND(8) { (it) -> i * it - it.toDouble() }
val b = 3
val c = Complex(1.0, 1.0)
(a pow b) + c
}
println(result)
}

View File

@ -0,0 +1,31 @@
/*
* Copyright 2018-2024 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package space.kscience.kmath.operations
import space.kscience.kmath.commons.linear.CMLinearSpace
import space.kscience.kmath.linear.matrix
import space.kscience.kmath.nd.Float64BufferND
import space.kscience.kmath.nd.Structure2D
import space.kscience.kmath.nd.mutableStructureND
import space.kscience.kmath.nd.ndAlgebra
import space.kscience.kmath.structures.Float64
import space.kscience.kmath.viktor.viktorAlgebra
import kotlin.collections.component1
import kotlin.collections.component2
fun main() {
val viktorStructure = Float64Field.viktorAlgebra.mutableStructureND(2, 2) { (i, j) ->
if (i == j) 2.0 else 0.0
}
val cmMatrix: Structure2D<Float64> = CMLinearSpace.matrix(2, 2)(0.0, 1.0, 0.0, 3.0)
val res: Float64BufferND = Float64Field.ndAlgebra {
exp(viktorStructure) + 2.0 * cmMatrix
}
println(res)
}

View File

@ -0,0 +1,17 @@
/*
* Copyright 2018-2024 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package space.kscience.kmath.series
import kotlinx.datetime.Instant
import space.kscience.kmath.operations.algebra
import space.kscience.kmath.operations.bufferAlgebra
import kotlin.time.Duration
fun SeriesAlgebra.Companion.time(zero: Instant, step: Duration) = MonotonicSeriesAlgebra(
bufferAlgebra = Double.algebra.bufferAlgebra,
offsetToLabel = { zero + step * it },
labelToOffset = { (it - zero) / step }
)

View File

@ -0,0 +1,65 @@
/*
* Copyright 2018-2024 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package space.kscience.kmath.series
import kotlinx.html.h1
import kotlinx.html.p
import space.kscience.kmath.operations.algebra
import space.kscience.kmath.operations.bufferAlgebra
import space.kscience.kmath.operations.toList
import space.kscience.kmath.stat.KMComparisonResult
import space.kscience.kmath.stat.ksComparisonStatistic
import space.kscience.kmath.structures.Buffer
import space.kscience.kmath.structures.Float64
import space.kscience.kmath.structures.slice
import space.kscience.plotly.*
import kotlin.math.PI
fun Double.Companion.seriesAlgebra() = Double.algebra.bufferAlgebra.seriesAlgebra()
fun main() = with(Double.seriesAlgebra()) {
fun Plot.plotSeries(name: String, buffer: Buffer<Float64>) {
scatter {
this.name = name
x.numbers = buffer.labels
y.numbers = buffer.toList()
}
}
val s1 = series(100) { sin(2 * PI * it / 100) + 1.0 }
val s2 = s1.slice(20..50).moveTo(40)
val s3: Buffer<Float64> = s1.zip(s2) { l, r -> l + r } //s1 + s2
val s4 = s3.map { ln(it) }
val kmTest: KMComparisonResult<Float64> = ksComparisonStatistic(s1, s2)
Plotly.page {
h1 { +"This is my plot" }
p {
+"Kolmogorov-smirnov test for s1 and s2: ${kmTest.value}"
}
plot {
plotSeries("s1", s1)
plotSeries("s2", s2)
plotSeries("s3", s3)
plotSeries("s4", s4)
layout {
xaxis {
range(0.0..100.0)
}
}
}
}.makeFile()
}

View File

@ -0,0 +1,47 @@
/*
* Copyright 2018-2023 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package space.kscience.kmath.series
import space.kscience.kmath.structures.*
import space.kscience.plotly.*
import space.kscience.plotly.models.Scatter
import space.kscience.plotly.models.ScatterMode
import kotlin.random.Random
fun main(): Unit = with(Double.seriesAlgebra()) {
val random = Random(1234)
val arrayOfRandoms = DoubleArray(20) { random.nextDouble() }
val series1: Float64Buffer = arrayOfRandoms.asBuffer()
val series2: Series<Float64> = series1.moveBy(3)
val res = series2 - series1
println(res.size)
println(res)
fun Plot.series(name: String, buffer: Buffer<Float64>, block: Scatter.() -> Unit = {}) {
scatter {
this.name = name
x.numbers = buffer.offsetIndices
y.doubles = buffer.toDoubleArray()
block()
}
}
Plotly.plot {
series("series1", series1)
series("series2", series2)
series("dif", res) {
mode = ScatterMode.lines
line.color("magenta")
}
}.makeFile(resourceLocation = ResourceLocation.REMOTE)
}

View File

@ -1,6 +1,6 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2024 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
package space.kscience.kmath.stat package space.kscience.kmath.stat
@ -10,6 +10,7 @@ import kotlinx.coroutines.async
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import org.apache.commons.rng.sampling.distribution.BoxMullerNormalizedGaussianSampler import org.apache.commons.rng.sampling.distribution.BoxMullerNormalizedGaussianSampler
import org.apache.commons.rng.simple.RandomSource import org.apache.commons.rng.simple.RandomSource
import space.kscience.kmath.random.RandomGenerator
import space.kscience.kmath.samplers.GaussianSampler import space.kscience.kmath.samplers.GaussianSampler
import java.time.Duration import java.time.Duration
import java.time.Instant import java.time.Instant
@ -35,8 +36,28 @@ private suspend fun runKMathChained(): Duration {
return Duration.between(startTime, Instant.now()) return Duration.between(startTime, Instant.now())
} }
private fun runApacheDirect(): Duration { private fun runKMathBlocking(): Duration {
val rng = RandomSource.create(RandomSource.MT, 123L) val generator = RandomGenerator.fromSource(RandomSource.MT, 123L)
val normal = GaussianSampler(7.0, 2.0)
val chain = normal.sample(generator)
val startTime = Instant.now()
var sum = 0.0
repeat(10000001) { counter ->
sum += chain.nextBlocking()
if (counter % 100000 == 0) {
val duration = Duration.between(startTime, Instant.now())
val meanValue = sum / counter
println("Chain sampler completed $counter elements in $duration: $meanValue")
}
}
return Duration.between(startTime, Instant.now())
}
private fun runCMDirect(): Duration {
val rng = RandomSource.MT.create(123L)
val sampler = CMGaussianSampler.of( val sampler = CMGaussianSampler.of(
BoxMullerNormalizedGaussianSampler.of(rng), BoxMullerNormalizedGaussianSampler.of(rng),
@ -64,8 +85,10 @@ private fun runApacheDirect(): Duration {
* Comparing chain sampling performance with direct sampling performance * Comparing chain sampling performance with direct sampling performance
*/ */
fun main(): Unit = runBlocking(Dispatchers.Default) { fun main(): Unit = runBlocking(Dispatchers.Default) {
val directJob = async { runApacheDirect() } val directJob = async { runCMDirect() }
val chainJob = async { runKMathChained() } val chainJob = async { runKMathChained() }
val blockingJob = async { runKMathBlocking() }
println("KMath Chained: ${chainJob.await()}") println("KMath Chained: ${chainJob.await()}")
println("KMath Blocking: ${blockingJob.await()}")
println("Apache Direct: ${directJob.await()}") println("Apache Direct: ${directJob.await()}")
} }

View File

@ -1,25 +1,27 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2024 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
package space.kscience.kmath.stat package space.kscience.kmath.stat
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import space.kscience.kmath.chains.Chain import space.kscience.kmath.chains.Chain
import space.kscience.kmath.chains.collectWithState import space.kscience.kmath.chains.combineWithState
import space.kscience.kmath.distributions.NormalDistribution import space.kscience.kmath.distributions.NormalDistribution
import space.kscience.kmath.random.RandomGenerator
import space.kscience.kmath.structures.Float64
private data class AveragingChainState(var num: Int = 0, var value: Double = 0.0) private data class AveragingChainState(var num: Int = 0, var value: Double = 0.0)
/** /**
* Averaging. * Averaging.
*/ */
private fun Chain<Double>.mean(): Chain<Double> = collectWithState(AveragingChainState(), { it.copy() }) { chain -> private fun Chain<Float64>.mean(): Chain<Float64> = combineWithState(AveragingChainState(), { it.copy() }) { chain ->
val next = chain.next() val next = chain.next()
num++ num++
value += next value += next
return@collectWithState value / num return@combineWithState value / num
} }

View File

@ -1,6 +1,6 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2024 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
@file:Suppress("unused") @file:Suppress("unused")
@ -8,11 +8,12 @@
package space.kscience.kmath.structures package space.kscience.kmath.structures
import space.kscience.kmath.complex.* import space.kscience.kmath.complex.*
import space.kscience.kmath.linear.transpose import space.kscience.kmath.linear.transposed
import space.kscience.kmath.nd.AlgebraND
import space.kscience.kmath.nd.StructureND import space.kscience.kmath.nd.StructureND
import space.kscience.kmath.nd.as2D import space.kscience.kmath.nd.as2D
import space.kscience.kmath.nd.real import space.kscience.kmath.nd.ndAlgebra
import space.kscience.kmath.nd.structureND
import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.operations.invoke import space.kscience.kmath.operations.invoke
import kotlin.system.measureTimeMillis import kotlin.system.measureTimeMillis
@ -20,12 +21,12 @@ fun main() {
val dim = 1000 val dim = 1000
val n = 1000 val n = 1000
val realField = AlgebraND.real(dim, dim) val realField = Float64Field.ndAlgebra(dim, dim)
val complexField: ComplexFieldND = AlgebraND.complex(dim, dim) val complexField: ComplexFieldND = ComplexField.ndAlgebra(dim, dim)
val realTime = measureTimeMillis { val realTime = measureTimeMillis {
realField { realField {
var res: StructureND<Double> = one var res: StructureND<Float64> = one
repeat(n) { repeat(n) {
res += 1.0 res += 1.0
} }
@ -49,17 +50,17 @@ fun main() {
fun complexExample() { fun complexExample() {
//Create a context for 2-d structure with complex values //Create a context for 2-d structure with complex values
ComplexField { ComplexField {
nd(4, 8) { withNdAlgebra(4, 8) {
//a constant real-valued structure //a constant real-valued structure
val x = one * 2.5 val x = one * 2.5
operator fun Number.plus(other: Complex) = Complex(this.toDouble() + other.re, other.im) operator fun Number.plus(other: Complex) = Complex(this.toDouble() + other.re, other.im)
//a structure generator specific to this context //a structure generator specific to this context
val matrix = produce { (k, l) -> k + l * i } val matrix = structureND { (k, l) -> k + l * i }
//Perform sum //Perform sum
val sum = matrix + x + 1.0 val sum = matrix + x + 1.0
//Represent the sum as 2d-structure and transpose //Represent the sum as 2d-structure and transpose
sum.as2D().transpose() sum.as2D().transposed()
} }
} }
} }

View File

@ -1,6 +1,6 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2024 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
package space.kscience.kmath.structures package space.kscience.kmath.structures
@ -9,10 +9,10 @@ import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.GlobalScope
import org.nd4j.linalg.factory.Nd4j import org.nd4j.linalg.factory.Nd4j
import space.kscience.kmath.nd.* import space.kscience.kmath.nd.*
import space.kscience.kmath.nd4j.Nd4jArrayField import space.kscience.kmath.nd4j.nd4j
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.operations.invoke import space.kscience.kmath.operations.invoke
import space.kscience.kmath.viktor.ViktorNDField import space.kscience.kmath.viktor.ViktorFieldND
import kotlin.contracts.InvocationKind import kotlin.contracts.InvocationKind
import kotlin.contracts.contract import kotlin.contracts.contract
import kotlin.system.measureTimeMillis import kotlin.system.measureTimeMillis
@ -29,64 +29,57 @@ fun main() {
Nd4j.zeros(0) Nd4j.zeros(0)
val dim = 1000 val dim = 1000
val n = 1000 val n = 1000
val shape = ShapeND(dim, dim)
// automatically build context most suited for given type.
val autoField = AlgebraND.auto(DoubleField, dim, dim)
// specialized nd-field for Double. It works as generic Double field as well. // specialized nd-field for Double. It works as generic Double field as well.
val realField = AlgebraND.real(dim, dim) val doubleField = Float64Field.ndAlgebra
//A generic boxing field. It should be used for objects, not primitives. //A generic field. It should be used for objects, not primitives.
val boxingField = AlgebraND.field(DoubleField, Buffer.Companion::boxing, dim, dim) val genericField = BufferedFieldOpsND(Float64Field)
// Nd4j specialized field. // Nd4j specialized field.
val nd4jField = Nd4jArrayField.real(dim, dim) val nd4jField = Float64Field.nd4j
//viktor field //viktor field
val viktorField = ViktorNDField(dim, dim) val viktorField = ViktorFieldND(dim, dim)
//parallel processing based on Java Streams //parallel processing based on Java Streams
val parallelField = AlgebraND.realWithStream(dim, dim) val parallelField = Float64Field.ndStreaming(dim, dim)
measureAndPrint("Boxing addition") { measureAndPrint("Boxing addition") {
boxingField { genericField {
var res: StructureND<Double> = one var res: StructureND<Float64> = one(shape)
repeat(n) { res += 1.0 } repeat(n) { res += 1.0 }
} }
} }
measureAndPrint("Specialized addition") { measureAndPrint("Specialized addition") {
realField { doubleField {
var res: StructureND<Double> = one var res: StructureND<Float64> = one(shape)
repeat(n) { res += 1.0 } repeat(n) { res += 1.0 }
} }
} }
measureAndPrint("Nd4j specialized addition") { measureAndPrint("Nd4j specialized addition") {
nd4jField { nd4jField {
var res: StructureND<Double> = one var res: StructureND<Float64> = one(shape)
repeat(n) { res += 1.0 } repeat(n) { res += 1.0 }
} }
} }
measureAndPrint("Viktor addition") { measureAndPrint("Viktor addition") {
viktorField { viktorField {
var res: StructureND<Double> = one var res: StructureND<Float64> = one
repeat(n) { res += 1.0 } repeat(n) { res += 1.0 }
} }
} }
measureAndPrint("Parallel stream addition") { measureAndPrint("Parallel stream addition") {
parallelField { parallelField {
var res: StructureND<Double> = one var res: StructureND<Float64> = one
repeat(n) { res += 1.0 }
}
}
measureAndPrint("Automatic field addition") {
autoField {
var res: StructureND<Double> = one
repeat(n) { res += 1.0 } repeat(n) { res += 1.0 }
} }
} }
measureAndPrint("Lazy addition") { measureAndPrint("Lazy addition") {
val res = realField.one.mapAsync(GlobalScope) { val res = doubleField.one(shape).mapAsync(GlobalScope) {
var c = 0.0 var c = 0.0
repeat(n) { repeat(n) {
c += 1.0 c += 1.0

View File

@ -1,14 +1,16 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2024 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
package space.kscience.kmath.structures package space.kscience.kmath.structures
import space.kscience.kmath.PerformancePitfall
import space.kscience.kmath.nd.* import space.kscience.kmath.nd.*
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.DoubleField
import space.kscience.kmath.operations.ExtendedField import space.kscience.kmath.operations.ExtendedField
import space.kscience.kmath.operations.NumbersAddOperations import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.operations.NumbersAddOps
import java.util.* import java.util.*
import java.util.stream.IntStream import java.util.stream.IntStream
@ -16,51 +18,67 @@ import java.util.stream.IntStream
* A demonstration implementation of NDField over Real using Java [java.util.stream.DoubleStream] for parallel * A demonstration implementation of NDField over Real using Java [java.util.stream.DoubleStream] for parallel
* execution. * execution.
*/ */
class StreamDoubleFieldND(override val shape: IntArray) : FieldND<Double, DoubleField>, class StreamDoubleFieldND(override val shape: ShapeND) : FieldND<Double, Float64Field>,
NumbersAddOperations<StructureND<Double>>, NumbersAddOps<StructureND<Float64>>,
ExtendedField<StructureND<Double>> { ExtendedField<StructureND<Float64>> {
private val strides = DefaultStrides(shape) private val strides = ColumnStrides(shape)
override val elementContext: DoubleField get() = DoubleField override val elementAlgebra: Float64Field get() = Float64Field
override val zero: BufferND<Double> by lazy { produce { zero } } override val zero: BufferND<Float64> by lazy { structureND(shape) { zero } }
override val one: BufferND<Double> by lazy { produce { one } } override val one: BufferND<Float64> by lazy { structureND(shape) { one } }
override fun number(value: Number): BufferND<Double> { override fun number(value: Number): BufferND<Float64> {
val d = value.toDouble() // minimize conversions val d = value.toDouble() // minimize conversions
return produce { d } return structureND(shape) { d }
} }
private val StructureND<Double>.buffer: DoubleBuffer @OptIn(PerformancePitfall::class)
private val StructureND<Float64>.buffer: Float64Buffer
get() = when { get() = when {
!shape.contentEquals(this@StreamDoubleFieldND.shape) -> throw ShapeMismatchException( shape != this@StreamDoubleFieldND.shape -> throw ShapeMismatchException(
this@StreamDoubleFieldND.shape, this@StreamDoubleFieldND.shape,
shape shape
) )
this is BufferND && this.strides == this@StreamDoubleFieldND.strides -> this.buffer as DoubleBuffer
else -> DoubleBuffer(strides.linearSize) { offset -> get(strides.index(offset)) } this is BufferND && indices == this@StreamDoubleFieldND.strides -> this.buffer as Float64Buffer
else -> Float64Buffer(strides.linearSize) { offset -> get(strides.index(offset)) }
} }
override fun produce(initializer: DoubleField.(IntArray) -> Double): BufferND<Double> { override fun structureND(shape: ShapeND, initializer: Float64Field.(IntArray) -> Double): BufferND<Float64> {
val array = IntStream.range(0, strides.linearSize).parallel().mapToDouble { offset -> val array = IntStream.range(0, strides.linearSize).parallel().mapToDouble { offset ->
val index = strides.index(offset) val index = strides.index(offset)
DoubleField.initializer(index) Float64Field.initializer(index)
}.toArray() }.toArray()
return BufferND(strides, array.asBuffer()) return BufferND(strides, array.asBuffer())
} }
override fun StructureND<Double>.map( override fun mutableStructureND(
transform: DoubleField.(Double) -> Double, shape: ShapeND,
): BufferND<Double> { initializer: DoubleField.(IntArray) -> Double,
val array = Arrays.stream(buffer.array).parallel().map { DoubleField.transform(it) }.toArray() ): MutableBufferND<Float64> {
val array = IntStream.range(0, strides.linearSize).parallel().mapToDouble { offset ->
val index = strides.index(offset)
DoubleField.initializer(index)
}.toArray()
return MutableBufferND(strides, array.asBuffer())
}
@OptIn(PerformancePitfall::class)
override fun StructureND<Float64>.map(
transform: Float64Field.(Double) -> Double,
): BufferND<Float64> {
val array = Arrays.stream(buffer.array).parallel().map { Float64Field.transform(it) }.toArray()
return BufferND(strides, array.asBuffer()) return BufferND(strides, array.asBuffer())
} }
override fun StructureND<Double>.mapIndexed( @OptIn(PerformancePitfall::class)
transform: DoubleField.(index: IntArray, Double) -> Double, override fun StructureND<Float64>.mapIndexed(
): BufferND<Double> { transform: Float64Field.(index: IntArray, Double) -> Double,
): BufferND<Float64> {
val array = IntStream.range(0, strides.linearSize).parallel().mapToDouble { offset -> val array = IntStream.range(0, strides.linearSize).parallel().mapToDouble { offset ->
DoubleField.transform( Float64Field.transform(
strides.index(offset), strides.index(offset),
buffer.array[offset] buffer.array[offset]
) )
@ -69,40 +87,41 @@ class StreamDoubleFieldND(override val shape: IntArray) : FieldND<Double, Double
return BufferND(strides, array.asBuffer()) return BufferND(strides, array.asBuffer())
} }
override fun combine( @OptIn(PerformancePitfall::class)
a: StructureND<Double>, override fun zip(
b: StructureND<Double>, left: StructureND<Float64>,
transform: DoubleField.(Double, Double) -> Double, right: StructureND<Float64>,
): BufferND<Double> { transform: Float64Field.(Double, Double) -> Double,
): BufferND<Float64> {
val array = IntStream.range(0, strides.linearSize).parallel().mapToDouble { offset -> val array = IntStream.range(0, strides.linearSize).parallel().mapToDouble { offset ->
DoubleField.transform(a.buffer.array[offset], b.buffer.array[offset]) Float64Field.transform(left.buffer.array[offset], right.buffer.array[offset])
}.toArray() }.toArray()
return BufferND(strides, array.asBuffer()) return BufferND(strides, array.asBuffer())
} }
override fun StructureND<Double>.unaryMinus(): StructureND<Double> = map { -it } override fun StructureND<Float64>.unaryMinus(): StructureND<Float64> = map { -it }
override fun scale(a: StructureND<Double>, value: Double): StructureND<Double> = a.map { it * value } override fun scale(a: StructureND<Float64>, value: Double): StructureND<Float64> = a.map { it * value }
override fun power(arg: StructureND<Double>, pow: Number): BufferND<Double> = arg.map { power(it, pow) } override fun power(arg: StructureND<Float64>, pow: Number): BufferND<Float64> = arg.map { power(it, pow) }
override fun exp(arg: StructureND<Double>): BufferND<Double> = arg.map { exp(it) } override fun exp(arg: StructureND<Float64>): BufferND<Float64> = arg.map { exp(it) }
override fun ln(arg: StructureND<Double>): BufferND<Double> = arg.map { ln(it) } override fun ln(arg: StructureND<Float64>): BufferND<Float64> = arg.map { ln(it) }
override fun sin(arg: StructureND<Double>): BufferND<Double> = arg.map { sin(it) } override fun sin(arg: StructureND<Float64>): BufferND<Float64> = arg.map { sin(it) }
override fun cos(arg: StructureND<Double>): BufferND<Double> = arg.map { cos(it) } override fun cos(arg: StructureND<Float64>): BufferND<Float64> = arg.map { cos(it) }
override fun tan(arg: StructureND<Double>): BufferND<Double> = arg.map { tan(it) } override fun tan(arg: StructureND<Float64>): BufferND<Float64> = arg.map { tan(it) }
override fun asin(arg: StructureND<Double>): BufferND<Double> = arg.map { asin(it) } override fun asin(arg: StructureND<Float64>): BufferND<Float64> = arg.map { asin(it) }
override fun acos(arg: StructureND<Double>): BufferND<Double> = arg.map { acos(it) } override fun acos(arg: StructureND<Float64>): BufferND<Float64> = arg.map { acos(it) }
override fun atan(arg: StructureND<Double>): BufferND<Double> = arg.map { atan(it) } override fun atan(arg: StructureND<Float64>): BufferND<Float64> = arg.map { atan(it) }
override fun sinh(arg: StructureND<Double>): BufferND<Double> = arg.map { sinh(it) } override fun sinh(arg: StructureND<Float64>): BufferND<Float64> = arg.map { sinh(it) }
override fun cosh(arg: StructureND<Double>): BufferND<Double> = arg.map { cosh(it) } override fun cosh(arg: StructureND<Float64>): BufferND<Float64> = arg.map { cosh(it) }
override fun tanh(arg: StructureND<Double>): BufferND<Double> = arg.map { tanh(it) } override fun tanh(arg: StructureND<Float64>): BufferND<Float64> = arg.map { tanh(it) }
override fun asinh(arg: StructureND<Double>): BufferND<Double> = arg.map { asinh(it) } override fun asinh(arg: StructureND<Float64>): BufferND<Float64> = arg.map { asinh(it) }
override fun acosh(arg: StructureND<Double>): BufferND<Double> = arg.map { acosh(it) } override fun acosh(arg: StructureND<Float64>): BufferND<Float64> = arg.map { acosh(it) }
override fun atanh(arg: StructureND<Double>): BufferND<Double> = arg.map { atanh(it) } override fun atanh(arg: StructureND<Float64>): BufferND<Float64> = arg.map { atanh(it) }
} }
fun AlgebraND.Companion.realWithStream(vararg shape: Int): StreamDoubleFieldND = StreamDoubleFieldND(shape) fun Float64Field.ndStreaming(vararg shape: Int): StreamDoubleFieldND = StreamDoubleFieldND(ShapeND(shape))

View File

@ -1,42 +1,45 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2024 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
package space.kscience.kmath.structures package space.kscience.kmath.structures
import space.kscience.kmath.PerformancePitfall
import space.kscience.kmath.nd.BufferND import space.kscience.kmath.nd.BufferND
import space.kscience.kmath.nd.DefaultStrides import space.kscience.kmath.nd.ColumnStrides
import space.kscience.kmath.nd.ShapeND
import kotlin.system.measureTimeMillis import kotlin.system.measureTimeMillis
@Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE") @Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE")
@OptIn(PerformancePitfall::class)
fun main() { fun main() {
val n = 6000 val n = 6000
val array = DoubleArray(n * n) { 1.0 } val array = DoubleArray(n * n) { 1.0 }
val buffer = DoubleBuffer(array) val buffer = Float64Buffer(array)
val strides = DefaultStrides(intArrayOf(n, n)) val strides = ColumnStrides(ShapeND(n, n))
val structure = BufferND(strides, buffer) val structure = BufferND(strides, buffer)
measureTimeMillis { measureTimeMillis {
var res = 0.0 var res = 0.0
strides.indices().forEach { res = structure[it] } strides.asSequence().forEach { res = structure[it] }
} // warmup } // warmup
val time1 = measureTimeMillis { val time1 = measureTimeMillis {
var res = 0.0 var res = 0.0
strides.indices().forEach { res = structure[it] } strides.asSequence().forEach { res = structure[it] }
} }
println("Structure reading finished in $time1 millis") println("Structure reading finished in $time1 millis")
val time2 = measureTimeMillis { val time2 = measureTimeMillis {
var res = 0.0 var res = 0.0
strides.indices().forEach { res = buffer[strides.offset(it)] } strides.asSequence().forEach { res = buffer[strides.offset(it)] }
} }
println("Buffer reading finished in $time2 millis") println("Buffer reading finished in $time2 millis")
val time3 = measureTimeMillis { val time3 = measureTimeMillis {
var res = 0.0 var res = 0.0
strides.indices().forEach { res = array[strides.offset(it)] } strides.asSequence().forEach { res = array[strides.offset(it)] }
} }
println("Array reading finished in $time3 millis") println("Array reading finished in $time3 millis")
} }

View File

@ -1,20 +1,25 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2024 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
package space.kscience.kmath.structures package space.kscience.kmath.structures
import space.kscience.kmath.nd.StructureND import space.kscience.kmath.nd.BufferND
import space.kscience.kmath.nd.mapToBuffer import space.kscience.kmath.operations.mapToBuffer
import kotlin.system.measureTimeMillis import kotlin.system.measureTimeMillis
private inline fun <T, reified R : Any> BufferND<T>.mapToBufferND(
bufferFactory: BufferFactory<R> = BufferFactory(),
crossinline block: (T) -> R,
): BufferND<R> = BufferND(indices, buffer.mapToBuffer(bufferFactory, block))
@Suppress("UNUSED_VARIABLE") @Suppress("UNUSED_VARIABLE")
fun main() { fun main() {
val n = 6000 val n = 6000
val structure = StructureND.buffered(intArrayOf(n, n), Buffer.Companion::auto) { 1.0 } val structure = BufferND(n, n) { 1.0 }
structure.mapToBuffer { it + 1 } // warm-up structure.mapToBufferND { it + 1 } // warm-up
val time1 = measureTimeMillis { val res = structure.mapToBuffer { it + 1 } } val time1 = measureTimeMillis { val res = structure.mapToBufferND { it + 1 } }
println("Structure mapping finished in $time1 millis") println("Structure mapping finished in $time1 millis")
val array = DoubleArray(n * n) { 1.0 } val array = DoubleArray(n * n) { 1.0 }
@ -25,10 +30,10 @@ fun main() {
println("Array mapping finished in $time2 millis") println("Array mapping finished in $time2 millis")
val buffer = DoubleBuffer(DoubleArray(n * n) { 1.0 }) val buffer = Float64Buffer(DoubleArray(n * n) { 1.0 })
val time3 = measureTimeMillis { val time3 = measureTimeMillis {
val target = DoubleBuffer(DoubleArray(n * n)) val target = Float64Buffer(DoubleArray(n * n))
val res = array.forEachIndexed { index, value -> val res = array.forEachIndexed { index, value ->
target[index] = value + 1 target[index] = value + 1
} }

View File

@ -0,0 +1,23 @@
/*
* Copyright 2018-2024 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package space.kscience.kmath.structures
import space.kscience.kmath.operations.Float64Field
import space.kscience.kmath.operations.buffer
import space.kscience.kmath.operations.bufferAlgebra
import space.kscience.kmath.operations.withSize
inline fun <reified R : Any> MutableBuffer.Companion.same(
n: Int,
value: R,
): MutableBuffer<R> = MutableBuffer(n) { value }
fun main() {
with(Float64Field.bufferAlgebra.withSize(5)) {
println(number(2.0) + buffer(1, 2, 3, 4, 5))
}
}

View File

@ -0,0 +1,26 @@
/*
* Copyright 2018-2023 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package space.kscience.kmath.structures
import space.kscience.kmath.PerformancePitfall
import space.kscience.kmath.nd.*
import space.kscience.kmath.operations.algebra
@OptIn(PerformancePitfall::class)
fun main(): Unit = with(Double.algebra.ndAlgebra) {
val structure: MutableStructure2D<Float64> = mutableStructureND(ShapeND(2, 2)) { (i, j) ->
i.toDouble() + j.toDouble()
}.as2D()
structure[0, 1] = -2.0
val structure2 = mutableStructureND(2, 2) { (i, j) -> i.toDouble() + j.toDouble() }.as2D()
structure2[0, 1] = 2.0
println(structure + structure2)
}

View File

@ -1,6 +1,6 @@
/* /*
* Copyright 2018-2021 KMath contributors. * Copyright 2018-2024 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
package space.kscience.kmath.structures package space.kscience.kmath.structures
@ -15,7 +15,7 @@ private fun DMatrixContext<Double, *>.simple() {
val m2 = produce<D3, D2> { i, j -> (i + j).toDouble() } val m2 = produce<D3, D2> { i, j -> (i + j).toDouble() }
//Dimension-safe addition //Dimension-safe addition
m1.transpose() + m2 m1.transposed() + m2
} }
private object D5 : Dimension { private object D5 : Dimension {

View File

@ -1,42 +0,0 @@
/*
* Copyright 2018-2021 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
*/
package space.kscience.kmath.tensors
import space.kscience.kmath.operations.invoke
import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra
// Dataset normalization
fun main() = BroadcastDoubleTensorAlgebra { // work in context with broadcast methods
// take dataset of 5-element vectors from normal distribution
val dataset = randomNormal(intArrayOf(100, 5)) * 1.5 // all elements from N(0, 1.5)
dataset += fromArray(
intArrayOf(5),
doubleArrayOf(0.0, 1.0, 1.5, 3.0, 5.0) // row means
)
// find out mean and standard deviation of each column
val mean = dataset.mean(0, false)
val std = dataset.std(0, false)
println("Mean:\n$mean")
println("Standard deviation:\n$std")
// also, we can calculate other statistic as minimum and maximum of rows
println("Minimum:\n${dataset.min(0, false)}")
println("Maximum:\n${dataset.max(0, false)}")
// now we can scale dataset with mean normalization
val datasetScaled = (dataset - mean) / std
// find out mean and std of scaled dataset
println("Mean of scaled:\n${datasetScaled.mean(0, false)}")
println("Mean of scaled:\n${datasetScaled.std(0, false)}")
}

View File

@ -0,0 +1,92 @@
/*
* Copyright 2018-2024 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package space.kscience.kmath.tensors.LevenbergMarquardt.StaticLm
import space.kscience.kmath.nd.ShapeND
import space.kscience.kmath.nd.as2D
import space.kscience.kmath.nd.component1
import space.kscience.kmath.tensors.LevenbergMarquardt.funcDifficultForLm
import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra
import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra.div
import space.kscience.kmath.tensors.core.DoubleTensorAlgebra
import space.kscience.kmath.tensors.core.LMInput
import space.kscience.kmath.tensors.core.levenbergMarquardt
import kotlin.math.roundToInt
fun main() {
val NData = 200
var t_example = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(NData, 1))).as2D()
for (i in 0 until NData) {
t_example[i, 0] = t_example[i, 0] * (i + 1) - 104
}
val Nparams = 15
var p_example = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(Nparams, 1))).as2D()
for (i in 0 until Nparams) {
p_example[i, 0] = p_example[i, 0] + i - 25
}
val exampleNumber = 1
var y_hat = funcDifficultForLm(t_example, p_example, exampleNumber)
var p_init = DoubleTensorAlgebra.zeros(ShapeND(intArrayOf(Nparams, 1))).as2D()
for (i in 0 until Nparams) {
p_init[i, 0] = (p_example[i, 0] + 0.9)
}
var t = t_example
val y_dat = y_hat
val weight = 1.0 / Nparams * 1.0 - 0.085
val dp = BroadcastDoubleTensorAlgebra.fromArray(
ShapeND(intArrayOf(1, 1)), DoubleArray(1) { -0.01 }
).as2D()
var p_min = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(Nparams, 1)))
p_min = p_min.div(1.0 / -50.0)
val p_max = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(Nparams, 1)))
p_min = p_min.div(1.0 / 50.0)
val opts = doubleArrayOf(3.0, 10000.0, 1e-6, 1e-6, 1e-6, 1e-6, 1e-2, 11.0, 9.0, 1.0)
// val opts = doubleArrayOf(3.0, 10000.0, 1e-6, 1e-6, 1e-6, 1e-6, 1e-3, 11.0, 9.0, 1.0)
val inputData = LMInput(
::funcDifficultForLm,
p_init.as2D(),
t,
y_dat,
weight,
dp,
p_min.as2D(),
p_max.as2D(),
opts[1].toInt(),
doubleArrayOf(opts[2], opts[3], opts[4], opts[5]),
doubleArrayOf(opts[6], opts[7], opts[8]),
opts[9].toInt(),
10,
1
)
val result = DoubleTensorAlgebra.levenbergMarquardt(inputData)
println("Parameters:")
for (i in 0 until result.resultParameters.shape.component1()) {
val x = (result.resultParameters[i, 0] * 10000).roundToInt() / 10000.0
print("$x ")
}
println()
println("Y true and y received:")
var y_hat_after = funcDifficultForLm(t_example, result.resultParameters, exampleNumber)
for (i in 0 until y_hat.shape.component1()) {
val x = (y_hat[i, 0] * 10000).roundToInt() / 10000.0
val y = (y_hat_after[i, 0] * 10000).roundToInt() / 10000.0
println("$x $y")
}
println("Сhi_sq:")
println(result.resultChiSq)
println("Number of iterations:")
println(result.iterations)
}

View File

@ -0,0 +1,59 @@
/*
* Copyright 2018-2024 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package space.kscience.kmath.tensors.LevenbergMarquardt.StaticLm
import space.kscience.kmath.nd.ShapeND
import space.kscience.kmath.nd.as2D
import space.kscience.kmath.nd.component1
import space.kscience.kmath.tensors.LevenbergMarquardt.funcDifficultForLm
import space.kscience.kmath.tensors.LevenbergMarquardt.funcEasyForLm
import space.kscience.kmath.tensors.LevenbergMarquardt.getStartDataForFuncEasy
import space.kscience.kmath.tensors.core.DoubleTensorAlgebra
import space.kscience.kmath.tensors.core.LMInput
import space.kscience.kmath.tensors.core.levenbergMarquardt
import kotlin.math.roundToInt
fun main() {
val startedData = getStartDataForFuncEasy()
val inputData = LMInput(
::funcEasyForLm,
DoubleTensorAlgebra.ones(ShapeND(intArrayOf(4, 1))).as2D(),
startedData.t,
startedData.y_dat,
startedData.weight,
startedData.dp,
startedData.p_min,
startedData.p_max,
startedData.opts[1].toInt(),
doubleArrayOf(startedData.opts[2], startedData.opts[3], startedData.opts[4], startedData.opts[5]),
doubleArrayOf(startedData.opts[6], startedData.opts[7], startedData.opts[8]),
startedData.opts[9].toInt(),
10,
startedData.example_number
)
val result = DoubleTensorAlgebra.levenbergMarquardt(inputData)
println("Parameters:")
for (i in 0 until result.resultParameters.shape.component1()) {
val x = (result.resultParameters[i, 0] * 10000).roundToInt() / 10000.0
print("$x ")
}
println()
println("Y true and y received:")
var y_hat_after = funcDifficultForLm(startedData.t, result.resultParameters, startedData.example_number)
for (i in 0 until startedData.y_dat.shape.component1()) {
val x = (startedData.y_dat[i, 0] * 10000).roundToInt() / 10000.0
val y = (y_hat_after[i, 0] * 10000).roundToInt() / 10000.0
println("$x $y")
}
println("Сhi_sq:")
println(result.resultChiSq)
println("Number of iterations:")
println(result.iterations)
}

View File

@ -0,0 +1,91 @@
/*
* Copyright 2018-2024 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package space.kscience.kmath.tensors.LevenbergMarquardt.StaticLm
import space.kscience.kmath.nd.ShapeND
import space.kscience.kmath.nd.as2D
import space.kscience.kmath.nd.component1
import space.kscience.kmath.tensors.LevenbergMarquardt.funcMiddleForLm
import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra
import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra.div
import space.kscience.kmath.tensors.core.DoubleTensorAlgebra
import space.kscience.kmath.tensors.core.LMInput
import space.kscience.kmath.tensors.core.levenbergMarquardt
import kotlin.math.roundToInt
fun main() {
val NData = 100
var t_example = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(NData, 1))).as2D()
for (i in 0 until NData) {
t_example[i, 0] = t_example[i, 0] * (i + 1)
}
val Nparams = 20
var p_example = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(Nparams, 1))).as2D()
for (i in 0 until Nparams) {
p_example[i, 0] = p_example[i, 0] + i - 25
}
val exampleNumber = 1
var y_hat = funcMiddleForLm(t_example, p_example, exampleNumber)
var p_init = DoubleTensorAlgebra.zeros(ShapeND(intArrayOf(Nparams, 1))).as2D()
for (i in 0 until Nparams) {
p_init[i, 0] = (p_example[i, 0] + 0.9)
}
var t = t_example
val y_dat = y_hat
val weight = 1.0
val dp = BroadcastDoubleTensorAlgebra.fromArray(
ShapeND(intArrayOf(1, 1)), DoubleArray(1) { -0.01 }
).as2D()
var p_min = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(Nparams, 1)))
p_min = p_min.div(1.0 / -50.0)
val p_max = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(Nparams, 1)))
p_min = p_min.div(1.0 / 50.0)
val opts = doubleArrayOf(3.0, 7000.0, 1e-5, 1e-5, 1e-5, 1e-5, 1e-5, 11.0, 9.0, 1.0)
val inputData = LMInput(
::funcMiddleForLm,
p_init.as2D(),
t,
y_dat,
weight,
dp,
p_min.as2D(),
p_max.as2D(),
opts[1].toInt(),
doubleArrayOf(opts[2], opts[3], opts[4], opts[5]),
doubleArrayOf(opts[6], opts[7], opts[8]),
opts[9].toInt(),
10,
1
)
val result = DoubleTensorAlgebra.levenbergMarquardt(inputData)
println("Parameters:")
for (i in 0 until result.resultParameters.shape.component1()) {
val x = (result.resultParameters[i, 0] * 10000).roundToInt() / 10000.0
print("$x ")
}
println()
var y_hat_after = funcMiddleForLm(t_example, result.resultParameters, exampleNumber)
for (i in 0 until y_hat.shape.component1()) {
val x = (y_hat[i, 0] * 10000).roundToInt() / 10000.0
val y = (y_hat_after[i, 0] * 10000).roundToInt() / 10000.0
println("$x $y")
}
println("Сhi_sq:")
println(result.resultChiSq)
println("Number of iterations:")
println(result.iterations)
}

View File

@ -0,0 +1,76 @@
/*
* Copyright 2018-2024 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package space.kscience.kmath.tensors.LevenbergMarquardt.StreamingLm
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import space.kscience.kmath.nd.MutableStructure2D
import space.kscience.kmath.nd.ShapeND
import space.kscience.kmath.nd.as2D
import space.kscience.kmath.nd.component1
import space.kscience.kmath.structures.Float64
import space.kscience.kmath.tensors.LevenbergMarquardt.StartDataLm
import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra.zeros
import space.kscience.kmath.tensors.core.DoubleTensorAlgebra
import space.kscience.kmath.tensors.core.LMInput
import space.kscience.kmath.tensors.core.levenbergMarquardt
import kotlin.random.Random
fun streamLm(
lm_func: (MutableStructure2D<Float64>, MutableStructure2D<Float64>, Int) -> (MutableStructure2D<Float64>),
startData: StartDataLm, launchFrequencyInMs: Long, numberOfLaunches: Int,
): Flow<MutableStructure2D<Float64>> = flow {
var example_number = startData.example_number
var p_init = startData.p_init
var t = startData.t
var y_dat = startData.y_dat
val weight = startData.weight
val dp = startData.dp
val p_min = startData.p_min
val p_max = startData.p_max
val opts = startData.opts
var steps = numberOfLaunches
val isEndless = (steps <= 0)
val inputData = LMInput(
lm_func,
p_init,
t,
y_dat,
weight,
dp,
p_min,
p_max,
opts[1].toInt(),
doubleArrayOf(opts[2], opts[3], opts[4], opts[5]),
doubleArrayOf(opts[6], opts[7], opts[8]),
opts[9].toInt(),
10,
example_number
)
while (isEndless || steps > 0) {
val result = DoubleTensorAlgebra.levenbergMarquardt(inputData)
emit(result.resultParameters)
delay(launchFrequencyInMs)
inputData.realValues = generateNewYDat(y_dat, 0.1)
inputData.startParameters = result.resultParameters
if (!isEndless) steps -= 1
}
}
fun generateNewYDat(y_dat: MutableStructure2D<Float64>, delta: Double): MutableStructure2D<Float64> {
val n = y_dat.shape.component1()
val y_dat_new = zeros(ShapeND(intArrayOf(n, 1))).as2D()
for (i in 0 until n) {
val randomEps = Random.nextDouble(delta + delta) - delta
y_dat_new[i, 0] = y_dat[i, 0] + randomEps
}
return y_dat_new
}

View File

@ -0,0 +1,33 @@
/*
* Copyright 2018-2024 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package space.kscience.kmath.tensors.LevenbergMarquardt.StreamingLm
import space.kscience.kmath.nd.component1
import space.kscience.kmath.tensors.LevenbergMarquardt.funcDifficultForLm
import space.kscience.kmath.tensors.LevenbergMarquardt.getStartDataForFuncDifficult
import kotlin.math.roundToInt
suspend fun main() {
val startData = getStartDataForFuncDifficult()
// Создание потока:
val lmFlow = streamLm(::funcDifficultForLm, startData, 0, 100)
var initialTime = System.currentTimeMillis()
var lastTime: Long
val launches = mutableListOf<Long>()
// Запуск потока
lmFlow.collect { parameters ->
lastTime = System.currentTimeMillis()
launches.add(lastTime - initialTime)
initialTime = lastTime
for (i in 0 until parameters.shape.component1()) {
val x = (parameters[i, 0] * 10000).roundToInt() / 10000.0
print("$x ")
if (i == parameters.shape.component1() - 1) println()
}
}
println("Average without first is: ${launches.subList(1, launches.size - 1).average()}")
}

View File

@ -0,0 +1,233 @@
/*
* Copyright 2018-2024 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package space.kscience.kmath.tensors.LevenbergMarquardt
import space.kscience.kmath.nd.MutableStructure2D
import space.kscience.kmath.nd.ShapeND
import space.kscience.kmath.nd.as2D
import space.kscience.kmath.nd.component1
import space.kscience.kmath.structures.Float64
import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra
import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra.div
import space.kscience.kmath.tensors.core.DoubleTensorAlgebra
import space.kscience.kmath.tensors.core.DoubleTensorAlgebra.Companion.max
import space.kscience.kmath.tensors.core.DoubleTensorAlgebra.Companion.plus
import space.kscience.kmath.tensors.core.DoubleTensorAlgebra.Companion.pow
import space.kscience.kmath.tensors.core.DoubleTensorAlgebra.Companion.times
import space.kscience.kmath.tensors.core.asDoubleTensor
public data class StartDataLm(
var lm_matx_y_dat: MutableStructure2D<Float64>,
var example_number: Int,
var p_init: MutableStructure2D<Float64>,
var t: MutableStructure2D<Float64>,
var y_dat: MutableStructure2D<Float64>,
var weight: Double,
var dp: MutableStructure2D<Float64>,
var p_min: MutableStructure2D<Float64>,
var p_max: MutableStructure2D<Float64>,
var consts: MutableStructure2D<Float64>,
var opts: DoubleArray,
)
fun funcEasyForLm(
t: MutableStructure2D<Float64>,
p: MutableStructure2D<Float64>,
exampleNumber: Int,
): MutableStructure2D<Float64> {
val m = t.shape.component1()
var y_hat = DoubleTensorAlgebra.zeros(ShapeND(intArrayOf(m, 1)))
if (exampleNumber == 1) {
y_hat = DoubleTensorAlgebra.exp((t.times(-1.0 / p[1, 0]))).times(p[0, 0]) + t.times(p[2, 0]).times(
DoubleTensorAlgebra.exp((t.times(-1.0 / p[3, 0])))
)
} else if (exampleNumber == 2) {
val mt = t.max()
y_hat = (t.times(1.0 / mt)).times(p[0, 0]) +
(t.times(1.0 / mt)).pow(2).times(p[1, 0]) +
(t.times(1.0 / mt)).pow(3).times(p[2, 0]) +
(t.times(1.0 / mt)).pow(4).times(p[3, 0])
} else if (exampleNumber == 3) {
y_hat = DoubleTensorAlgebra.exp((t.times(-1.0 / p[1, 0])))
.times(p[0, 0]) + DoubleTensorAlgebra.sin((t.times(1.0 / p[3, 0]))).times(p[2, 0])
}
return y_hat.as2D()
}
fun funcMiddleForLm(
t: MutableStructure2D<Float64>,
p: MutableStructure2D<Float64>,
exampleNumber: Int,
): MutableStructure2D<Float64> {
val m = t.shape.component1()
var y_hat = DoubleTensorAlgebra.zeros(ShapeND(intArrayOf(m, 1)))
val mt = t.max()
for (i in 0 until p.shape.component1()) {
y_hat += (t.times(1.0 / mt)).times(p[i, 0])
}
for (i in 0 until 5) {
y_hat = funcEasyForLm(y_hat.as2D(), p, exampleNumber).asDoubleTensor()
}
return y_hat.as2D()
}
fun funcDifficultForLm(
t: MutableStructure2D<Float64>,
p: MutableStructure2D<Float64>,
exampleNumber: Int,
): MutableStructure2D<Float64> {
val m = t.shape.component1()
var y_hat = DoubleTensorAlgebra.zeros(ShapeND(intArrayOf(m, 1)))
val mt = t.max()
for (i in 0 until p.shape.component1()) {
y_hat = y_hat.plus((t.times(1.0 / mt)).times(p[i, 0]))
}
for (i in 0 until 4) {
y_hat = funcEasyForLm((y_hat.as2D() + t).as2D(), p, exampleNumber).asDoubleTensor()
}
return y_hat.as2D()
}
fun getStartDataForFuncDifficult(): StartDataLm {
val NData = 200
var t_example = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(NData, 1))).as2D()
for (i in 0 until NData) {
t_example[i, 0] = t_example[i, 0] * (i + 1) - 104
}
val Nparams = 15
var p_example = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(Nparams, 1))).as2D()
for (i in 0 until Nparams) {
p_example[i, 0] = p_example[i, 0] + i - 25
}
val exampleNumber = 1
var y_hat = funcDifficultForLm(t_example, p_example, exampleNumber)
var p_init = DoubleTensorAlgebra.zeros(ShapeND(intArrayOf(Nparams, 1))).as2D()
for (i in 0 until Nparams) {
p_init[i, 0] = (p_example[i, 0] + 0.9)
}
var t = t_example
val y_dat = y_hat
val weight = 1.0 / Nparams * 1.0 - 0.085
val dp = BroadcastDoubleTensorAlgebra.fromArray(
ShapeND(intArrayOf(1, 1)), DoubleArray(1) { -0.01 }
).as2D()
var p_min = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(Nparams, 1)))
p_min = p_min.div(1.0 / -50.0)
val p_max = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(Nparams, 1)))
p_min = p_min.div(1.0 / 50.0)
val consts = BroadcastDoubleTensorAlgebra.fromArray(
ShapeND(intArrayOf(1, 1)), doubleArrayOf(0.0)
).as2D()
val opts = doubleArrayOf(3.0, 10000.0, 1e-2, 1e-3, 1e-2, 1e-2, 1e-2, 11.0, 9.0, 1.0)
return StartDataLm(y_dat, 1, p_init, t, y_dat, weight, dp, p_min.as2D(), p_max.as2D(), consts, opts)
}
fun getStartDataForFuncMiddle(): StartDataLm {
val NData = 100
var t_example = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(NData, 1))).as2D()
for (i in 0 until NData) {
t_example[i, 0] = t_example[i, 0] * (i + 1)
}
val Nparams = 20
var p_example = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(Nparams, 1))).as2D()
for (i in 0 until Nparams) {
p_example[i, 0] = p_example[i, 0] + i - 25
}
val exampleNumber = 1
var y_hat = funcMiddleForLm(t_example, p_example, exampleNumber)
var p_init = DoubleTensorAlgebra.zeros(ShapeND(intArrayOf(Nparams, 1))).as2D()
for (i in 0 until Nparams) {
p_init[i, 0] = (p_example[i, 0] + 10.0)
}
var t = t_example
val y_dat = y_hat
val weight = 1.0
val dp = BroadcastDoubleTensorAlgebra.fromArray(
ShapeND(intArrayOf(1, 1)), DoubleArray(1) { -0.01 }
).as2D()
var p_min = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(Nparams, 1)))
p_min = p_min.div(1.0 / -50.0)
val p_max = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(Nparams, 1)))
p_min = p_min.div(1.0 / 50.0)
val consts = BroadcastDoubleTensorAlgebra.fromArray(
ShapeND(intArrayOf(1, 1)), doubleArrayOf(0.0)
).as2D()
val opts = doubleArrayOf(3.0, 10000.0, 1e-5, 1e-5, 1e-5, 1e-5, 1e-5, 11.0, 9.0, 1.0)
var example_number = 1
return StartDataLm(y_dat, example_number, p_init, t, y_dat, weight, dp, p_min.as2D(), p_max.as2D(), consts, opts)
}
fun getStartDataForFuncEasy(): StartDataLm {
val lm_matx_y_dat = doubleArrayOf(
19.6594, 18.6096, 17.6792, 17.2747, 16.3065, 17.1458, 16.0467, 16.7023, 15.7809, 15.9807,
14.7620, 15.1128, 16.0973, 15.1934, 15.8636, 15.4763, 15.6860, 15.1895, 15.3495, 16.6054,
16.2247, 15.9854, 16.1421, 17.0960, 16.7769, 17.1997, 17.2767, 17.5882, 17.5378, 16.7894,
17.7648, 18.2512, 18.1581, 16.7037, 17.8475, 17.9081, 18.3067, 17.9632, 18.2817, 19.1427,
18.8130, 18.5658, 18.0056, 18.4607, 18.5918, 18.2544, 18.3731, 18.7511, 19.3181, 17.3066,
17.9632, 19.0513, 18.7528, 18.2928, 18.5967, 17.8567, 17.7859, 18.4016, 18.9423, 18.4959,
17.8000, 18.4251, 17.7829, 17.4645, 17.5221, 17.3517, 17.4637, 17.7563, 16.8471, 17.4558,
17.7447, 17.1487, 17.3183, 16.8312, 17.7551, 17.0942, 15.6093, 16.4163, 15.3755, 16.6725,
16.2332, 16.2316, 16.2236, 16.5361, 15.3721, 15.3347, 15.5815, 15.6319, 14.4538, 14.6044,
14.7665, 13.3718, 15.0587, 13.8320, 14.7873, 13.6824, 14.2579, 14.2154, 13.5818, 13.8157
)
var example_number = 1
val p_init = BroadcastDoubleTensorAlgebra.fromArray(
ShapeND(intArrayOf(4, 1)), doubleArrayOf(5.0, 2.0, 0.2, 10.0)
).as2D()
var t = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(100, 1))).as2D()
for (i in 0 until 100) {
t[i, 0] = t[i, 0] * (i + 1)
}
val y_dat = BroadcastDoubleTensorAlgebra.fromArray(
ShapeND(intArrayOf(100, 1)), lm_matx_y_dat
).as2D()
val weight = 4.0
val dp = BroadcastDoubleTensorAlgebra.fromArray(
ShapeND(intArrayOf(1, 1)), DoubleArray(1) { -0.01 }
).as2D()
val p_min = BroadcastDoubleTensorAlgebra.fromArray(
ShapeND(intArrayOf(4, 1)), doubleArrayOf(-50.0, -20.0, -2.0, -100.0)
).as2D()
val p_max = BroadcastDoubleTensorAlgebra.fromArray(
ShapeND(intArrayOf(4, 1)), doubleArrayOf(50.0, 20.0, 2.0, 100.0)
).as2D()
val consts = BroadcastDoubleTensorAlgebra.fromArray(
ShapeND(intArrayOf(1, 1)), doubleArrayOf(0.0)
).as2D()
val opts = doubleArrayOf(3.0, 100.0, 1e-3, 1e-3, 1e-1, 1e-1, 1e-2, 11.0, 9.0, 1.0)
return StartDataLm(y_dat, example_number, p_init, t, y_dat, weight, dp, p_min, p_max, consts, opts)
}

Some files were not shown because too many files have changed in this diff Show More