Git Product home page Git Product logo

koma's Introduction

GitHub issues License Bintray Travis AppVeyor

Koma

Koma is a scientific computing environment for Kotlin.

Project goals:

  • Create a scientific programming environment that is similar in style to NumPy or MATLAB
  • Enable writing numerical applications which can be deployed on JVM, JS, and native platforms
  • Support using said applications from Python, MATLAB, Java, and other pre-existing codebases
  • Use pluggable back-ends to enable optimized computation via pre-existing platform libraries

Project documentation

For more information on using Koma, please see the documentation

Building

To build from source, use one of the following commands:

# Java
./gradlew buildJvm
# Javascript
./gradlew buildJs
# Native (example executable, see examples/native/main.kt)
./gradlew buildNative

Output artifacts are left in the ./build folder. For more information see building from source.

Related Projects

Koma has backends that wrap several other numerical projects on the JVM:

For a data analysis library similar to pandas, check out https://github.com/holgerbrandl/kplyr

For Kotlin statistical methods, check out https://github.com/thomasnield/kotlin-statistics

koma's People

Contributors

cbruegg avatar drmoose avatar josephcatrambone avatar kyonifer avatar peastman avatar satchitananda avatar thomasnield avatar venabled avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

koma's Issues

Make NDArray's map function generic

NDArray's map is defined as fun map(f: (T) -> T): NDArray<T>. It would be more useful if map were a generic, in the sense of fun map<R>(f: (T) -> R): NDArray<R>.

Here's some sample code which I'd like to compile, but can't:

var counter = 0
val ints: NDArray<Int> = DefaultNDArray(3, 4, 5) { ++counter }
val doubles: NDArray<Double> = ints.map { it.toDouble() }

Currently I'm using the following hacky workaround, which is dangerous and insane but seems to work.

fun <TIn, TOut> NDArray<TIn>.crazyMapWorkaround(fn: (TIn) -> TOut) = 
    toIterable().iterator().let { itr ->
        DefaultNDArray(*(shape().toIntArray())) { fn(itr.next()) }
    }

Unable to build native on Mac - Missing cblas.h

I got the following error trying to build for Kotlin Native:

Exception in thread "main" java.lang.Error: /var/folders/y7/qnnjc1q143q39hwttm_rs4gm0000gn/T/tmp7387811828594230022.c:1:10: fatal error: 'cblas.h' file not found
        at org.jetbrains.kotlin.native.interop.indexer.UtilsKt.ensureNoCompileErrors(Utils.kt:137)
        at org.jetbrains.kotlin.native.interop.indexer.IndexerKt.indexDeclarations(Indexer.kt:898)
        at org.jetbrains.kotlin.native.interop.indexer.IndexerKt.buildNativeIndexImpl(Indexer.kt:888)
        at org.jetbrains.kotlin.native.interop.indexer.NativeIndexKt.buildNativeIndex(NativeIndex.kt:56)
        at org.jetbrains.kotlin.native.interop.gen.jvm.MainKt.processCLib(main.kt:307)
        at org.jetbrains.kotlin.native.interop.gen.jvm.MainKt.interop(main.kt:38)
        at org.jetbrains.kotlin.cli.utilities.InteropCompilerKt.invokeInterop(InteropCompiler.kt:100)
        at org.jetbrains.kotlin.cli.utilities.MainKt.main(main.kt:29)

I installed openblas but it didn't help.

Investigate options for emscripten blas generators and node-only solutions

For the js side, we may end up needing two backends: one for node (which calls out to optimized blas, see e.g. Vectorious) and one for everything else (browser, etc). One route that might enable us to get the "everything else" bin implementing all of our ops could be the automatic emscripten blas generators that are out there.

Multiplatform test coverage

Currently koma only tests itself on the jvm. It needs to instead switch to kotlin-test and test on all 3 backends, as well as extend test coverage.

Update docs to match the new build system

After switching to a unified build system using multiplatform, the build docs also need to be updated. The new build steps are buildNative, buildJvm, and buildJs, with build running all of them.

Cleanup workaround code for crossplatform K/Native K/Js K/Java that is no longer necessary

Hi, I saw you redefined PI an E here.
But doing so is pointless since the val you defined (could have been a const val BTW) is of type Double, which doesn't have as much precision as the digits you wrote.
Kotlin's 1.2 math package already includes these constants (which forwards to JVM constants that already have the max precision achievable for type Double).

To prove what I'm saying, here's a snippet that runs without Exception. You can try it on try.kotl.in

typealias BlaBla = Array<String>

fun main(argsBlaBla: BlaBla) {
    
    val tooLongPiForDouble = 3.1415926535897932384626433832795028841971693993751058209749445923078164062
    check(tooLongPiForDouble == 3.14159265358979323846)
    check(tooLongPiForDouble == Math.PI)
    check(Math.PI == kotlin.math.PI)
    check(kotlin.math.PI == 3.14159265358979323846)
    println(tooLongPiForDouble)
    println(kotlin.math.PI)
}

EJML matrix decomp failing

Attempting to use something like eye(2).QR() always seems to result in empty matrices being returned for QR when using EJML backend (not tested on others). It appears that a call to

decomp.decompose(this.storage.matrix)

after this line may help following docs for getQ() here.

Remove already-satisfied constraints from validation narrative

          Matrix           Required Actual 
========================== ======== ====== 
measurementMatrix             NxM     2x1  
measurementNoiseCovariance    NxN     2x2  
measurement                   Nx1     1x2  
xhat                          Mx1     2x1  
P                             MxM     2x2  
measurementMatrix must have the same number of rows as measurementNoiseCovariance has rows
measurementMatrix must have the same number of rows as measurementNoiseCovariance has columns
measurementMatrix must have the same number of rows as measurement has rows
measurement must have exactly 1 columns (has 2)

In the above example, the first two lines of the narrative should not appear because those constraints are already satisfied.

Implement N-D container

Should be a supertype of 2D, without the 2D only operations (will require specific backend support, since none of our 2D backends work with N atm).

Add an overload of equals

This program:

import koma.eye

fun main(args: Array<String>)
{
    val a = eye(3)
    val b = eye(3)
    println(a == b)
}

Produces false, because it just compares whether a and b refer to the same Kotlin object.

It would be very useful to have an overload that would compare matrices in the mathematical sense. That is, two matrices are the same if they have the same dimensions and each element of one matrix is equal to the element in the other matrix in the same column and row.

Add numbers-by-matrices multiplication

Currently the Matrix interface has times() operator for multiplying by both other matrices and numbers.
Hence, this code is correct:
var mulMatByTwo = ones(1) * 2.0

But as times() operator is not extended in the Int and Double classes, such code is incorrect:
var mulTwoByMat = 2.0 * ones(1)
which means multiplication is not commutative.

For the sake of consistency, we can create an extension in the Number class:
operator fun <M : Number> Number.times(other: Matrix<M>): Matrix<Double> { return other * this }

Update validation to work with equality changes

In #43 equality was changed to be elementwise. This currently causes matrix validation to break in some cases. For example:

val x = zeros(3,2)
val y = zeros(3,2)
validate {
    x("x"){'N' x 1}
    y("y"){'N' x 'M'}
}

This should fail (because x must have 1 column) but doesn't.

The issue is that DimensionValidator constructs a dimensions hashmap from matrices to possible dimensions. Because y and x are equal under elementwise equality they hash to the same bin in DimensionValidator.dimensions. Thus x's dimension list is clobbered by y's and x survives the dimension check.

Its probably enough to change the validator hashes to use a referential equality wrapper.

Switch to kotlin uint / inline class based complex

Now that uint will be a builtin kotlin feature, we should deprecate our uint support entirely. In addition, inline classes leave us an avenue to support complex matrices without boxing, and consequently complex algorithms (such as ffts).

Add saving for plots

Need the ability to save plots to disk. Also maybe add an option to run the plots headless, e.g. plt.show() on matplotlib.

Eliminate boxing from get/set methods

Currently on the JVM target, val a =zeros(3,3); a[1,1] will yield a boxed number because .get(...) has return type T, which forces Matrix<Double> to return java.lang.Double instead of double. This is inconvenient for performance reasons if calling get or set in a loop.

.setCol unexpected behavior

You can set columns (and I'd guess rows, I haven't checked) with an arbitrary Matrix that has fewer than the expected number of elements in the dimension to be set, and the fill data is taken from the rows of the matrix passed in up to the number of cols available:

val m = zeros(3, 2)
val fillVal = ones(2, 1000).fill{r, c -> c + 1.0} // 2 x 2 works also
m.setCol(0, fillVal) 
// The transpose still fails on size check
// m.setCol(0, fillVal.T) 

// Now m.getCol(0) returns
mat[ 1.00 end
     2.00 end
     0.00 ]

Default to TimeStandard OTHER in Time constructor

Rather than arbitrarily assigning one of the current 'hard' standards (WALL) in the Time constructor, TimeStandard should default to OTHER. This matches better with the current practice of only checking TimeStandards if each time has been explicitly linked to a standard.

Investigate the applicability of inline classes to koma

Now that inline classes look slated for kotlin mainline (experimental in 1.3-M2), it would be very useful to implement Matrix<T> with inline classes to eliminate any overhead using koma might have had over using the underlying libs on each platform. It appears the feature currently supports a single wrapped property and interfaces (but not abstract bases), which could work for Matrix. There are some backends where a single thing isnt enough currently (e.g. native wants both a pointer to memory and a length) but we can probably refactor a bit to make every implementation wrap a single object.

Unexpected RNG behavior w/seed

val seed : Long = 1

// Seeding java produces matches
val r = Random()
r.setSeed(seed)
val firstJava = r.nextGaussian()
r.setSeed(seed)
assert(r.nextGaussian() == firstJava)

// So does EJML directly
r.setSeed(seed)
val firstEJML = SimpleMatrix.random(1, 1, 0.0, 1.0, r)
r.setSeed(seed)
val secEJML = SimpleMatrix.random(1, 1, 0.0, 1.0, r)
assert(secEJML.isIdentical(firstEJML, 1e-20))

// koma w/ EJML backend behaves differently
assertMatrixEquals(randn(1, 1, seed), randn(1, 1, seed))  // fails

Inconsistent bounds checking errors on slice assignment

Say I have a 4x4 matrix called x:

val x = zeros(4, 4)

If I try to populate a column with a vector oriented the wrong way, I expect an IndexOutOfBoundsException but I get an IllegalArgumentException :

>>> x[0..end, 1] = mat[1, 2, 3, 4]
java.lang.IllegalArgumentException: Specified element is out of bounds: 1 0
	at org.ejml.data.DMatrixRMaj.get(DMatrixRMaj.java:262)
	at org.ejml.simple.SimpleBase.get(SimpleBase.java:654)
	at koma.matrix.ejml.EJMLMatrix.getDouble(EJMLMatrix.kt:43)
	at koma.extensions.MatrixExtensions__Extensions_matrix_DoubleKt.get(extensions_matrix_Double.kt:152)
	at koma.extensions.MatrixExtensions.get(Unknown Source)
	at koma.extensions.MatrixExtensions__Extensions_matrix_DoubleKt.setRangesDouble(extensions_matrix_Double.kt:224)
	at koma.extensions.MatrixExtensions.setRangesDouble(Unknown Source)
	at koma.extensions.MatrixExtensions__Extensions_matrix_DoubleKt.setRowRangeDouble(extensions_matrix_Double.kt:269)
	at koma.extensions.MatrixExtensions.setRowRangeDouble(Unknown Source)

Even worse, if I provide more data than is needed to fill the space in the correct direction, there is no error, allowing me to write this off-by-one code by accident:

>>> x[0 until end, 1] = mat[1,2,3,4].T
>>> x
mat[ 0.00,  1.00,  0.00,  0.00 end
     0.00,  2.00,  0.00,  0.00 end
     0.00,  3.00,  0.00,  0.00 end
     0.00,  0.00,  0.00,  0.00 ]

'cblas.h' not found when building in Mac Os x

Command ./gradlew build produces this error on mac

Task :koma-core-cblas:compileKonanCblasMacbook FAILED
Exception in thread "main" java.lang.Error: /var/folders/wz/xhlg5g6n1c785tsbryqp0yyh0000gn/T/tmp7098207755916076298.c:1:10: fatal error: 'cblas.h' file not found
        at org.jetbrains.kotlin.native.interop.indexer.UtilsKt.ensureNoCompileErrors(Utils.kt:137)
        at org.jetbrains.kotlin.native.interop.indexer.IndexerKt.indexDeclarations(Indexer.kt:898)
        at org.jetbrains.kotlin.native.interop.indexer.IndexerKt.buildNativeIndexImpl(Indexer.kt:888)
        at org.jetbrains.kotlin.native.interop.indexer.NativeIndexKt.buildNativeIndex(NativeIndex.kt:56)
        at org.jetbrains.kotlin.native.interop.gen.jvm.MainKt.processCLib(main.kt:307)
        at org.jetbrains.kotlin.native.interop.gen.jvm.MainKt.interop(main.kt:38)
        at org.jetbrains.kotlin.cli.utilities.InteropCompilerKt.invokeInterop(InteropCompiler.kt:100)
        at org.jetbrains.kotlin.cli.utilities.MainKt.main(main.kt:29)

I try to modify
buildscripts/cblas.def into

headers=cblas.h
compilerOpts = -I/usr/include/x86_64-linux-gnu -I/usr/local/opt/openblas/include
linkerOpts = -L/usr/lib -L/usr/lib/x86_64-linux-gnu -L/usr/local/opt/openblas/lib -lblas

and
buildscripts/lapacke.def into

headers=lapacke.h
compilerOpts = -I/usr/local/opt/lapack/include
linkerOpts = -L/usr/lib -L/usr/lib/x86_64-linux-gnu -L/usr/local/opt/lapack/lib -llapacke

but no result, any idea?

can not add repository

On adding the repository in the Gradle I am getting the following error.

Java: file not found Exception
Resource nexus-maven-repository-index-properties does not exist

img_20170720_031330

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.