├── .gitignore
├── LICENSE
├── README.md
├── build.gradle
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── src
├── main
└── kotlin
│ └── org
│ └── ojalgo
│ └── okalgo
│ ├── algebra.kt
│ ├── ann.kt
│ └── optimization.kt
└── test
└── kotlin
└── org
└── ojalgo
└── okalgo
├── LinearAlgebraTest.kt
└── OptimizationTest.kt
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | /.idea/
3 | /.gradle/
4 | /build/
5 | /out
6 | *.iml
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Thomas Nield
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # okAlgo
2 |
3 |
4 | [](https://jitpack.io/#optimatika/okAlgo)
5 |
6 | Idiomatic Kotlin extensions for ojAlgo, with some inspirations from [PuLP](https://github.com/coin-or/pulp).
7 |
8 | ## Linear Algebra DSL
9 |
10 | Below is an example of how to use the linear algebra DSL. In this particular example, we create a Markov chain to calculate the probability of 5 consecutive heads in 10 coin flips.
11 |
12 | ```kotlin
13 | import org.ojalgo.okalgo.populate
14 | import org.ojalgo.okalgo.primitivematrix
15 | import org.ojalgo.okalgo.times
16 |
17 | fun main() {
18 |
19 | val transitionMatrix = primitivematrix(rows = 6, cols = 6) {
20 | populate {row, col ->
21 | when {
22 | col == 0L -> .50
23 | row + 1L == col -> .50
24 | row == 5L && col == 5L -> 1.0
25 | else -> 0.0
26 | }
27 | }
28 | }
29 |
30 | println("\r\nTransition Matrix:")
31 | println(transitionMatrix)
32 |
33 | val toTenthPower = generateSequence(transitionMatrix) { it * transitionMatrix }.take(10).last()
34 | println("\r\nTransition Matrix Raised to 10th Power")
35 | println(toTenthPower)
36 |
37 | println("\r\nMARKOV CHAIN RESULT: ${toTenthPower[0,5]}")
38 | }
39 |
40 | // REFERENCE: https://www.quora.com/What-is-the-probability-of-getting-5-consecutive-heads-in-10-tosses-of-a-fair-coin
41 | ```
42 |
43 | **OUTPUT:**
44 |
45 | ```
46 | Transition Matrix:
47 | org.ojalgo.matrix.PrimitiveMatrix < 6 x 6 >
48 | { { 0.5, 0.5, 0.0, 0.0, 0.0, 0.0 },
49 | { 0.5, 0.0, 0.5, 0.0, 0.0, 0.0 },
50 | { 0.5, 0.0, 0.0, 0.5, 0.0, 0.0 },
51 | { 0.5, 0.0, 0.0, 0.0, 0.5, 0.0 },
52 | { 0.5, 0.0, 0.0, 0.0, 0.0, 0.5 },
53 | { 0.5, 0.0, 0.0, 0.0, 0.0, 1.0 } }
54 |
55 | Transition Matrix Raised to 10th Power
56 | org.ojalgo.matrix.PrimitiveMatrix < 6 x 6 >
57 | { { 0.5546875, 0.267578125, 0.1298828125, 0.0634765625, 0.03125, 0.109375 },
58 | { 0.6015625, 0.287109375, 0.1376953125, 0.06640625, 0.0322265625, 0.140625 },
59 | { 0.7109375, 0.333984375, 0.1572265625, 0.07421875, 0.03515625, 0.2041015625 },
60 | { 0.9609375, 0.443359375, 0.2041015625, 0.09375, 0.04296875, 0.333984375 },
61 | { 1.5244140625, 0.693359375, 0.3134765625, 0.140625, 0.0625, 0.6015625 },
62 | { 2.78125, 1.2568359375, 0.5634765625, 0.25, 0.109375, 1.15625 } }
63 |
64 | MARKOV CHAIN RESULT: 0.109375
65 | ```
66 |
67 | ## MIP Solver DSL
68 |
69 | **EXAMPLE 1**
70 |
71 | ```kotlin
72 | expressionsbasedmodel {
73 |
74 | val v1 = variable(lower = 3, upper = 6)
75 | val v2 = variable(lower = 10, upper = 12)
76 |
77 | expression(weight = 1) {
78 | set(v1, 1)
79 | set(v2, 1)
80 | }
81 |
82 | maximise()
83 |
84 | println("v1=${v1.value.toDouble()} v2=${v2.value.toDouble()}")
85 | }
86 | ```
87 |
88 | **EXAMPLE 2**
89 |
90 |
91 | ```kotlin
92 | val model = ExpressionsBasedModel()
93 |
94 | val v1 = model.variable(lower = 3, upper = 6)
95 | val v2 = model.variable(lower = 10, upper = 12)
96 |
97 | model.expression(weight=1) {
98 | set(v1, 1)
99 | set(v2, 1)
100 | }
101 |
102 | model.maximise()
103 |
104 | println("v1=${v1.value.toDouble()} v2=${v2.value.toDouble()}")
105 | ```
106 |
107 |
108 | Expression building with Kotlin extensions is also being explored:
109 |
110 |
111 | **EXAMPLE 3**
112 |
113 | ```kotlin
114 | expressionsbasedmodel {
115 |
116 | val v1 = variable(lower = 2, upper = 10, isInteger = true)
117 | val v2 = variable(lower = 2, upper = 10, isInteger = true)
118 |
119 | expression(v1 + 2*v2) {
120 | weight(1)
121 | }
122 |
123 | expression {
124 | set(v1 + v2 EQ 16)
125 | }
126 |
127 | minimise().run(::println)
128 |
129 | println("v1=${v1.value.toDouble()} v2=${v2.value.toDouble()}")
130 | }
131 | ```
132 |
133 | ## Artifact Instructions
134 |
135 | Until this gets deployed to Maven Central, you can use JitPack to import this project as a dependency.
136 |
137 | **Maven**
138 |
139 | ```xml
140 |
141 | org.ojalgo
142 | okalgo
143 | 0.0.2
144 |
145 | ```
146 |
147 | **Gradle**
148 |
149 | ```groovy
150 | compile 'org.ojalgo:okalgo:0.0.2'
151 | ```
152 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 |
2 | buildscript {
3 | ext.kotlin_version = '1.3.31'
4 |
5 | repositories {
6 | mavenCentral()
7 | }
8 |
9 | dependencies {
10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
11 | }
12 | }
13 |
14 |
15 | apply plugin: 'kotlin'
16 | apply plugin: 'maven'
17 |
18 |
19 |
20 | apply plugin: 'maven'
21 |
22 |
23 |
24 | repositories {
25 | mavenCentral()
26 | //maven { url 'https://jitpack.io' }
27 | }
28 |
29 |
30 | dependencies {
31 | compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
32 |
33 | compile 'org.ojalgo:ojalgo:47.2.0'
34 | //implementation 'com.github.optimatika:ojAlgo:develop-SNAPSHOT'
35 |
36 | compile 'junit:junit:4.12'
37 | }
38 |
39 | /*
40 | apply plugin: 'signing'
41 |
42 | task javadocJar(type: Jar) {
43 | classifier = 'javadoc'
44 | from javadoc
45 | }
46 |
47 | task sourcesJar(type: Jar) {
48 | classifier = 'sources'
49 | from sourceSets.main.allSource
50 | }
51 |
52 | artifacts {
53 | archives javadocJar, sourcesJar
54 | }
55 |
56 | signing {
57 | sign configurations.archives
58 | }
59 |
60 | group = "org.ojalgo"
61 | archivesBaseName = "okalgo"
62 | version = "0.0.2"
63 |
64 | uploadArchives {
65 | repositories {
66 | mavenDeployer {
67 | beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) }
68 |
69 | repository(url: "https://oss.sonatype.org/service/local/staging/deploy/maven2/") {
70 | authentication(userName: ossrhUsername, password: ossrhPassword)
71 | }
72 |
73 | snapshotRepository(url: "https://oss.sonatype.org/content/repositories/snapshots/") {
74 | authentication(userName: ossrhUsername, password: ossrhPassword)
75 | }
76 |
77 | pom.project {
78 | name 'okAlgo'
79 | packaging 'jar'
80 | // optionally artifactId can be defined here
81 | description 'Idiomatic Kotlin extensions for ojAlgo'
82 | url 'https://github.com/optimatika/okAlgo'
83 |
84 | scm {
85 | connection 'scm:git:git://github.com/optimatika/okAlgo.git'
86 | developerConnection 'scm:git:git@github.com:optimatika/okAlgo.git'
87 | url 'https://github.com/optimatika/okAlgo'
88 | }
89 |
90 | licenses {
91 | license {
92 | name 'MIT'
93 | url 'http://ojalgo.org/license.txt'
94 | }
95 | }
96 | developers {
97 | developer {
98 | id 'thomasnield'
99 | name 'Thomas Nield'
100 | email 'thomasnield@live.com'
101 | }
102 | }
103 | }
104 | }
105 | }
106 | }
107 |
108 | */
109 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/optimatika/okAlgo/0e62ce9f1fe9e95b41a87119116688c2a3b5a061/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | zipStoreBase=GRADLE_USER_HOME
4 | zipStorePath=wrapper/dists
5 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.3.1-bin.zip
6 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Attempt to set APP_HOME
10 | # Resolve links: $0 may be a link
11 | PRG="$0"
12 | # Need this for relative symlinks.
13 | while [ -h "$PRG" ] ; do
14 | ls=`ls -ld "$PRG"`
15 | link=`expr "$ls" : '.*-> \(.*\)$'`
16 | if expr "$link" : '/.*' > /dev/null; then
17 | PRG="$link"
18 | else
19 | PRG=`dirname "$PRG"`"/$link"
20 | fi
21 | done
22 | SAVED="`pwd`"
23 | cd "`dirname \"$PRG\"`/" >/dev/null
24 | APP_HOME="`pwd -P`"
25 | cd "$SAVED" >/dev/null
26 |
27 | APP_NAME="Gradle"
28 | APP_BASE_NAME=`basename "$0"`
29 |
30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
31 | DEFAULT_JVM_OPTS=""
32 |
33 | # Use the maximum available, or set MAX_FD != -1 to use that value.
34 | MAX_FD="maximum"
35 |
36 | warn ( ) {
37 | echo "$*"
38 | }
39 |
40 | die ( ) {
41 | echo
42 | echo "$*"
43 | echo
44 | exit 1
45 | }
46 |
47 | # OS specific support (must be 'true' or 'false').
48 | cygwin=false
49 | msys=false
50 | darwin=false
51 | nonstop=false
52 | case "`uname`" in
53 | CYGWIN* )
54 | cygwin=true
55 | ;;
56 | Darwin* )
57 | darwin=true
58 | ;;
59 | MINGW* )
60 | msys=true
61 | ;;
62 | NONSTOP* )
63 | nonstop=true
64 | ;;
65 | esac
66 |
67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
68 |
69 | # Determine the Java command to use to start the JVM.
70 | if [ -n "$JAVA_HOME" ] ; then
71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
72 | # IBM's JDK on AIX uses strange locations for the executables
73 | JAVACMD="$JAVA_HOME/jre/sh/java"
74 | else
75 | JAVACMD="$JAVA_HOME/bin/java"
76 | fi
77 | if [ ! -x "$JAVACMD" ] ; then
78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
79 |
80 | Please set the JAVA_HOME variable in your environment to match the
81 | location of your Java installation."
82 | fi
83 | else
84 | JAVACMD="java"
85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
86 |
87 | Please set the JAVA_HOME variable in your environment to match the
88 | location of your Java installation."
89 | fi
90 |
91 | # Increase the maximum file descriptors if we can.
92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
93 | MAX_FD_LIMIT=`ulimit -H -n`
94 | if [ $? -eq 0 ] ; then
95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
96 | MAX_FD="$MAX_FD_LIMIT"
97 | fi
98 | ulimit -n $MAX_FD
99 | if [ $? -ne 0 ] ; then
100 | warn "Could not set maximum file descriptor limit: $MAX_FD"
101 | fi
102 | else
103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
104 | fi
105 | fi
106 |
107 | # For Darwin, add options to specify how the application appears in the dock
108 | if $darwin; then
109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
110 | fi
111 |
112 | # For Cygwin, switch paths to Windows format before running java
113 | if $cygwin ; then
114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
116 | JAVACMD=`cygpath --unix "$JAVACMD"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Escape application args
158 | save ( ) {
159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
160 | echo " "
161 | }
162 | APP_ARGS=$(save "$@")
163 |
164 | # Collect all arguments for the java command, following the shell quoting and substitution rules
165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
166 |
167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
169 | cd "$(dirname "$0")"
170 | fi
171 |
172 | exec "$JAVACMD" "$@"
173 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/src/main/kotlin/org/ojalgo/okalgo/algebra.kt:
--------------------------------------------------------------------------------
1 | package org.ojalgo.okalgo
2 |
3 | import org.ojalgo.algebra.Operation
4 | import org.ojalgo.algebra.ScalarOperation
5 | import org.ojalgo.array.*
6 | import org.ojalgo.matrix.ComplexMatrix
7 | import org.ojalgo.matrix.PrimitiveMatrix
8 | import org.ojalgo.matrix.RationalMatrix
9 | import org.ojalgo.scalar.ComplexNumber
10 | import org.ojalgo.scalar.Quaternion
11 | import org.ojalgo.scalar.RationalNumber
12 | import java.math.BigDecimal
13 | import java.util.concurrent.atomic.AtomicBoolean
14 |
15 |
16 | fun Sequence.toPrimitiveMatrix(vararg selectors: (T) -> N): PrimitiveMatrix {
17 | val items = toList()
18 |
19 | return primitivematrix(items.count(), selectors.count()) {
20 | populate { row, col ->
21 | selectors[col.toInt()](items[row.toInt()])
22 | }
23 | }
24 | }
25 |
26 | fun Iterable.toPrimitiveMatrix(vararg selectors: (T) -> N): PrimitiveMatrix {
27 | val items = toList()
28 |
29 | return primitivematrix(items.count(), selectors.count()) {
30 | populate { row, col ->
31 | selectors[col.toInt()](items[row.toInt()])
32 | }
33 | }
34 | }
35 |
36 |
37 | fun Sequence.toComplexMatrix(vararg selectors: (T) -> N): ComplexMatrix {
38 | val items = toList()
39 |
40 | return complexmatrix(items.count(), selectors.count()) {
41 | populate { row, col ->
42 | selectors[col.toInt()](items[row.toInt()])
43 | }
44 | }
45 | }
46 | fun Iterable.toComplexMatrix(vararg selectors: (T) -> N): ComplexMatrix {
47 | val items = toList()
48 |
49 | return complexmatrix(items.count(), selectors.count()) {
50 | populate { row, col ->
51 | selectors[col.toInt()](items[row.toInt()])
52 | }
53 | }
54 | }
55 |
56 |
57 | fun Sequence.toRationalMatrix(vararg selectors: (T) -> N): RationalMatrix {
58 | val items = toList()
59 |
60 | return rationalmatrix(items.count(), selectors.count()) {
61 | populate { row, col ->
62 | selectors[col.toInt()](items[row.toInt()])
63 | }
64 | }
65 | }
66 | fun Iterable.toRationalMatrix(vararg selectors: (T) -> N): RationalMatrix {
67 | val items = toList()
68 |
69 | return rationalmatrix(items.count(), selectors.count()) {
70 | populate { row, col ->
71 | selectors[col.toInt()](items[row.toInt()])
72 | }
73 | }
74 | }
75 |
76 | fun bigArrayOf(vararg values: Double) = BigArray.FACTORY.copy(*values)
77 | fun bigArrayOf(vararg values: ComplexNumber) = BigArray.FACTORY.copy(*values)
78 | fun bigArrayOf(vararg values: BigDecimal) = BigArray.FACTORY.copy(*values)
79 |
80 | fun complexArrayOf(vararg values: ComplexNumber) = ComplexArray.FACTORY.copy(*values)
81 |
82 | fun direct32ArrayOf(vararg values: Double) = BufferArray.DIRECT32.copy(*values)
83 | fun direct64ArrayOf(vararg values: Double) = BufferArray.DIRECT64.copy(*values)
84 |
85 | fun quanternionArrayOf(vararg values: Quaternion) = Quaternion.FACTORY.newArrayInstance(values.count()).apply {
86 | values.withIndex().forEach { this[it.index] = it.value }
87 | }
88 |
89 | fun rationalArrayOf(vararg values: RationalNumber) = RationalArray.FACTORY.copy(*values)
90 |
91 |
92 |
93 | fun vectorOf(vararg values: Int) = primitivematrix(values.count(), 1) {
94 | populate { row, col -> values[row.toInt()] }
95 | }
96 |
97 | fun vectorOf(vararg values: Double) = primitivematrix(values.count(), 1) {
98 | populate { row, col -> values[row.toInt()] }
99 | }
100 |
101 | fun vectorOf(vararg values: Long) = primitivematrix(values.count(), 1) {
102 | populate { row, col -> values[row.toInt()] }
103 | }
104 |
105 | fun vectorOf(vararg values: BigDecimal) = primitivematrix(values.count(), 1) {
106 | populate { row, col -> values[row.toInt()] }
107 | }
108 |
109 | fun primitivematrix(rows: Int, cols: Int, op: (PrimitiveMatrix.DenseReceiver.() -> Unit)? = null) =
110 | PrimitiveMatrix.FACTORY.makeDense(rows,cols).also {
111 | if (op != null) op(it)
112 | }.build()
113 |
114 | fun complexmatrix(rows: Int, cols: Int, op: (ComplexMatrix.DenseReceiver.() -> Unit)? = null) =
115 | ComplexMatrix.FACTORY.makeDense(rows,cols).also {
116 | if (op != null) op(it)
117 | }.build()
118 |
119 | fun rationalmatrix(rows: Int, cols: Int, op: (RationalMatrix.DenseReceiver.() -> Unit)? = null) =
120 | RationalMatrix.FACTORY.makeDense(rows,cols).also {
121 | if (op != null) op(it)
122 | }.build()
123 |
124 | fun PrimitiveMatrix.DenseReceiver.populate(op: (Long,Long) -> Number) =
125 | loopAll { row, col -> set(row, col, op(row,col)) }
126 |
127 | fun ComplexMatrix.DenseReceiver.populate(op: (Long,Long) -> Number) =
128 | loopAll { row, col -> set(row, col, op(row,col)) }
129 |
130 | fun RationalMatrix.DenseReceiver.populate(op: (Long,Long) -> Number) =
131 | loopAll { row, col -> set(row, col, op(row,col)) }
132 |
133 | fun PrimitiveMatrix.DenseReceiver.populate(vararg values: Double) {
134 |
135 | var takeIndex = 0
136 |
137 | for (r in 0 until countRows()) {
138 | for (c in 0 until countColumns()) {
139 | set(r,c, values[takeIndex++])
140 | }
141 | }
142 | }
143 |
144 | fun PrimitiveMatrix.DenseReceiver.populate(vararg values: Number) {
145 | var takeIndex = 0
146 |
147 | for (r in 0 until countRows()) {
148 | for (c in 0 until countColumns()) {
149 | set(r,c, values[takeIndex++])
150 | }
151 | }
152 | }
153 |
154 | fun ComplexMatrix.DenseReceiver.populate(vararg values: Double) {
155 | var takeIndex = 0
156 |
157 | for (r in 0 until countRows()) {
158 | for (c in 0 until countColumns()) {
159 | set(r,c, values[takeIndex++])
160 | }
161 | }
162 | }
163 |
164 | fun ComplexMatrix.DenseReceiver.populate(vararg values: Number) {
165 | var takeIndex = 0
166 |
167 | for (r in 0 until countRows()) {
168 | for (c in 0 until countColumns()) {
169 | set(r,c, values[takeIndex++])
170 | }
171 | }
172 | }
173 |
174 |
175 | fun RationalMatrix.DenseReceiver.populate(vararg values: Double) {
176 | var takeIndex = 0
177 |
178 | for (r in 0 until countRows()) {
179 | for (c in 0 until countColumns()) {
180 | set(r,c, values[takeIndex++])
181 | }
182 | }
183 | }
184 |
185 | fun RationalMatrix.DenseReceiver.populate(vararg values: Number) {
186 | var takeIndex = 0
187 |
188 | for (r in 0 until countRows()) {
189 | for (c in 0 until countColumns()) {
190 | set(r,c, values[takeIndex++])
191 | }
192 | }
193 | }
194 |
195 |
196 |
197 |
198 |
199 | operator fun Operation.Addition.plus(t: T) = add(t)
200 | operator fun Operation.Division.div(t: T) = divide(t)
201 | operator fun Operation.Multiplication.times(t: T) = multiply(t)
202 | operator fun Operation.Subtraction.minus(t: T) = subtract(t)
203 |
204 | operator fun ScalarOperation.Addition.plus(number: N) = add(number)
205 | operator fun ScalarOperation.Division.div(number: N) = divide(number)
206 | operator fun ScalarOperation.Multiplication.times(number: N) = multiply(number)
207 | operator fun ScalarOperation.Subtraction.minus(number: N) = subtract(number)
208 |
209 | fun Double.toComplex() = ComplexNumber.FACTORY.cast(this)
210 | fun Double.toRational() = RationalNumber.FACTORY.cast(this)
211 | fun N.toComplex() = ComplexNumber.FACTORY.cast(this)
212 | fun N.toRational() = RationalNumber.FACTORY.cast(this)
213 |
214 | fun Double.toComplexScalar() = ComplexNumber.FACTORY.convert(this)
215 | fun Double.toRationalScalar() = RationalNumber.FACTORY.convert(this)
216 | fun N.toComplexScalar() = ComplexNumber.FACTORY.convert(this)
217 | fun N.toRationalScalar() = RationalNumber.FACTORY.convert(this)
218 |
--------------------------------------------------------------------------------
/src/main/kotlin/org/ojalgo/okalgo/ann.kt:
--------------------------------------------------------------------------------
1 | package org.ojalgo.okalgo
2 |
3 | import org.ojalgo.ann.ArtificialNeuralNetwork
4 | import org.ojalgo.ann.NetworkBuilder
5 |
6 | fun artificialneuralnetwork(numberOfInputNodes: Int, vararg nodesPerCalculationLayer: Int, op: NetworkBuilder.() -> Unit = {}): ArtificialNeuralNetwork? {
7 |
8 | val builder = ArtificialNeuralNetwork.builder(numberOfInputNodes, *nodesPerCalculationLayer)
9 |
10 | builder.op()
11 |
12 | return builder.get()
13 | }
--------------------------------------------------------------------------------
/src/main/kotlin/org/ojalgo/okalgo/optimization.kt:
--------------------------------------------------------------------------------
1 | package org.ojalgo.okalgo
2 |
3 | import org.ojalgo.optimisation.Expression
4 | import org.ojalgo.optimisation.ExpressionsBasedModel
5 | import org.ojalgo.optimisation.Variable
6 | import java.util.concurrent.atomic.AtomicInteger
7 |
8 |
9 | class AutoNameState {
10 | // custom DSL for expression and variable inputs, eliminate naming and adding
11 | val funcId = AtomicInteger(0)
12 | val variableId = AtomicInteger(0)
13 | fun generateVariableName() = variableId.incrementAndGet().toString().let { "Variable$it" }
14 | fun generateExpressionName() = funcId.incrementAndGet().let { "Func$it"}
15 | }
16 |
17 | val autoNameStates = mutableMapOf()
18 | fun ExpressionsBasedModel.getAutoNameState() = autoNameStates.computeIfAbsent(this) { AutoNameState() }
19 |
20 | fun expressionsbasedmodel(op: ExpressionsBasedModel.() -> Unit): ExpressionsBasedModel {
21 | val ebm = ExpressionsBasedModel()
22 | ebm.op()
23 | return ebm
24 | }
25 |
26 | fun ExpressionsBasedModel.expression(expression: ExpressionBuilder? = null,
27 | name: String? = null,
28 | lower: Number? = null,
29 | upper: Number? = null,
30 | level: Number? = null,
31 | weight: Number? = null,
32 | op: Expression.() -> Unit = {}): Expression {
33 |
34 | val expr = addExpression(name ?: getAutoNameState().generateExpressionName())
35 |
36 | expression?.also {
37 | it.items.forEach {
38 | expr.it()
39 | }
40 | }
41 |
42 | expr.op()
43 | lower?.let { expr.lower(it) }
44 | upper?.let { expr.upper(it) }
45 | level?.let { expr.level(it) }
46 | weight?.let { expr.weight(it) }
47 |
48 | return expr
49 | }
50 |
51 |
52 | fun ExpressionsBasedModel.variable(name: String? = null, lower: Number? = null, upper: Number? = null, level: Number? = null, weight: Number? = null, isBinary: Boolean? = null, isInteger: Boolean? = null, op: Variable.() -> Unit = {}): Variable {
53 |
54 | val variable = Variable(name ?: getAutoNameState().generateVariableName())
55 | variable.op()
56 | lower?.let { variable.lower(it) }
57 | upper?.let { variable.upper(it) }
58 | level?.let { variable.level(it) }
59 | weight?.let { variable.weight(it) }
60 | isBinary?.let { if (it) variable.binary() }
61 | isInteger?.let { variable.integer(it) }
62 |
63 | addVariable(variable)
64 | return variable
65 | }
66 |
67 |
68 | operator fun Variable.plus(other: Variable): ExpressionBuilder {
69 | val eb = ExpressionBuilder()
70 | eb += this
71 | eb += other
72 | return eb
73 | }
74 |
75 | operator fun Variable.minus(other: Variable): ExpressionBuilder {
76 | val eb = ExpressionBuilder()
77 | eb += this
78 | eb - other
79 | return eb
80 | }
81 |
82 | operator fun Variable.plus(expression: ExpressionBuilder): ExpressionBuilder {
83 | val eb = expression
84 | eb += this
85 | return eb
86 | }
87 |
88 |
89 | operator fun Variable.minus(expression: ExpressionBuilder): ExpressionBuilder {
90 | val eb = expression
91 | eb += this
92 | return eb
93 | }
94 |
95 |
96 | operator fun Number.times(variable: Variable): ExpressionBuilder {
97 | val eb = ExpressionBuilder()
98 | val multiplier = this
99 | eb.items += { set(variable, multiplier) }
100 | return eb
101 | }
102 |
103 | infix fun Number.LTE(variable: Variable): ExpressionBuilder {
104 | val eb = ExpressionBuilder()
105 | val lower = this
106 | eb.items += {
107 | lower(lower)
108 | set(variable, 1)
109 | }
110 | return eb
111 | }
112 |
113 | infix fun Number.GTE(variable: Variable): ExpressionBuilder {
114 | val eb = ExpressionBuilder()
115 | val upper = this
116 | eb.items += {
117 | upper(upper)
118 | set(variable, 1)
119 | }
120 | return eb
121 | }
122 |
123 | infix fun Number.EQ(variable: Variable): ExpressionBuilder {
124 | val eb = ExpressionBuilder()
125 | val upper = this
126 | eb.items += {
127 | level(upper)
128 | set(variable, 1)
129 | }
130 | return eb
131 | }
132 |
133 |
134 | infix fun Number.LTE(expression: ExpressionBuilder): ExpressionBuilder {
135 | val eb = expression
136 | val lower = this
137 | eb.items += {
138 | lower(lower)
139 | }
140 | return eb
141 | }
142 |
143 | infix fun Number.GTE(expression: ExpressionBuilder): ExpressionBuilder {
144 | val eb = expression
145 | val upper = this
146 | eb.items += {
147 | upper(upper)
148 | }
149 | return eb
150 | }
151 |
152 | infix fun Number.EQ(expression: ExpressionBuilder): ExpressionBuilder {
153 | val eb = expression
154 | val upper = this
155 | eb.items += {
156 | level(upper)
157 | }
158 | return eb
159 | }
160 |
161 | fun ExpressionsBasedModel.set(expression: ExpressionBuilder) {
162 | expression.addToModel(this)
163 | }
164 |
165 |
166 | class ExpressionBuilder {
167 | val items = mutableListOf Unit>()
168 |
169 | operator fun plusAssign(variable: Variable) {
170 | items += { set(variable, 1) }
171 | }
172 |
173 | operator fun plus(variable: Variable): ExpressionBuilder {
174 | items += { set(variable, 1) }
175 | return this
176 | }
177 |
178 | operator fun plus(expressionBuilder: ExpressionBuilder): ExpressionBuilder {
179 | items.addAll(expressionBuilder.items)
180 | return this
181 | }
182 | operator fun minus(variable: Variable): ExpressionBuilder {
183 | items += { set(variable, -1) }
184 | return this
185 | }
186 |
187 | fun weight(weight: Number): ExpressionBuilder {
188 | items += { weight(weight) }
189 | return this
190 | }
191 | infix fun EQ(number: Int): ExpressionBuilder {
192 | items += { level(number) }
193 | return this
194 | }
195 |
196 | infix fun GTE(number: Int): ExpressionBuilder {
197 | items += { lower(number) }
198 | return this
199 | }
200 |
201 | infix fun LTE(number: Int): ExpressionBuilder {
202 | items += { upper(number) }
203 | return this
204 | }
205 |
206 | fun addToModel(model: ExpressionsBasedModel, name: String? = null) {
207 |
208 | model.expression(name = name) {
209 | items.forEach {
210 | this.it()
211 | }
212 | }
213 | }
214 | }
215 |
--------------------------------------------------------------------------------
/src/test/kotlin/org/ojalgo/okalgo/LinearAlgebraTest.kt:
--------------------------------------------------------------------------------
1 | package org.ojalgo.okalgo
2 |
3 | import org.junit.Assert
4 | import org.junit.Assert.assertTrue
5 | import org.junit.Test
6 | import org.ojalgo.matrix.ComplexMatrix
7 | import org.ojalgo.matrix.PrimitiveMatrix
8 | import org.ojalgo.matrix.RationalMatrix
9 | import java.math.BigDecimal
10 |
11 | class LinearAlgebraTest {
12 |
13 | @Test
14 | fun toPrimitiveMatrixTestList() {
15 |
16 | val matrix = listOf(1,2,3).toPrimitiveMatrix(
17 | {it},
18 | {it * 10},
19 | {it * 100}
20 | )
21 |
22 | val shouldMatch = PrimitiveMatrix.FACTORY.makeDense(3,3).also {
23 | it.set(0L,0L,1)
24 | it.set(0L,1L,10)
25 | it.set(0L,2L,100)
26 |
27 | it.set(1L,0L,2)
28 | it.set(1L,1L,20)
29 | it.set(1L,2L,200)
30 |
31 | it.set(2L,0L,3)
32 | it.set(2L,1L,30)
33 | it.set(2L,2L,300)
34 | }.build()
35 |
36 | assertTrue(matrix == shouldMatch)
37 | }
38 |
39 | @Test
40 | fun toPrimitiveMatrixTestSequence() {
41 |
42 | val matrix = sequenceOf(1,2,3).toPrimitiveMatrix(
43 | {it},
44 | {it * 10},
45 | {it * 100}
46 | )
47 |
48 | val shouldMatch = PrimitiveMatrix.FACTORY.makeDense(3,3).also {
49 | it.set(0L,0L,1)
50 | it.set(0L,1L,10)
51 | it.set(0L,2L,100)
52 |
53 | it.set(1L,0L,2)
54 | it.set(1L,1L,20)
55 | it.set(1L,2L,200)
56 |
57 | it.set(2L,0L,3)
58 | it.set(2L,1L,30)
59 | it.set(2L,2L,300)
60 | }.build()
61 |
62 | assertTrue(matrix == shouldMatch)
63 | }
64 |
65 | @Test
66 | fun toComplexMatrixTestList() {
67 |
68 | val matrix = listOf(1,2,3).toComplexMatrix(
69 | {it},
70 | {it * 10},
71 | {it * 100}
72 | )
73 |
74 | val shouldMatch = ComplexMatrix.FACTORY.makeDense(3,3).also {
75 | it.set(0L,0L,1)
76 | it.set(0L,1L,10)
77 | it.set(0L,2L,100)
78 |
79 | it.set(1L,0L,2)
80 | it.set(1L,1L,20)
81 | it.set(1L,2L,200)
82 |
83 | it.set(2L,0L,3)
84 | it.set(2L,1L,30)
85 | it.set(2L,2L,300)
86 | }.build()
87 |
88 | assertTrue(matrix == shouldMatch)
89 | }
90 |
91 | @Test
92 | fun toComplexMatrixTestSequence() {
93 |
94 | val matrix = sequenceOf(1,2,3).toComplexMatrix(
95 | {it},
96 | {it * 10},
97 | {it * 100}
98 | )
99 |
100 | val shouldMatch = ComplexMatrix.FACTORY.makeDense(3,3).also {
101 | it.set(0L,0L,1)
102 | it.set(0L,1L,10)
103 | it.set(0L,2L,100)
104 |
105 | it.set(1L,0L,2)
106 | it.set(1L,1L,20)
107 | it.set(1L,2L,200)
108 |
109 | it.set(2L,0L,3)
110 | it.set(2L,1L,30)
111 | it.set(2L,2L,300)
112 | }.build()
113 |
114 | assertTrue(matrix == shouldMatch)
115 | }
116 |
117 | @Test
118 | fun toRationalMatrixTestList() {
119 |
120 | val matrix = listOf(1,2,3).toRationalMatrix(
121 | {it},
122 | {it * 10},
123 | {it * 100}
124 | )
125 |
126 | val shouldMatch = RationalMatrix.FACTORY.makeDense(3,3).also {
127 | it.set(0L,0L,1)
128 | it.set(0L,1L,10)
129 | it.set(0L,2L,100)
130 |
131 | it.set(1L,0L,2)
132 | it.set(1L,1L,20)
133 | it.set(1L,2L,200)
134 |
135 | it.set(2L,0L,3)
136 | it.set(2L,1L,30)
137 | it.set(2L,2L,300)
138 | }.build()
139 |
140 | assertTrue(matrix == shouldMatch)
141 | }
142 |
143 | @Test
144 | fun toRationalMatrixTestSequence() {
145 |
146 | val matrix = sequenceOf(1,2,3).toRationalMatrix(
147 | {it},
148 | {it * 10},
149 | {it * 100}
150 | )
151 |
152 | val shouldMatch = RationalMatrix.FACTORY.makeDense(3,3).also {
153 | it.set(0L,0L,1)
154 | it.set(0L,1L,10)
155 | it.set(0L,2L,100)
156 |
157 | it.set(1L,0L,2)
158 | it.set(1L,1L,20)
159 | it.set(1L,2L,200)
160 |
161 | it.set(2L,0L,3)
162 | it.set(2L,1L,30)
163 | it.set(2L,2L,300)
164 | }.build()
165 |
166 | assertTrue(matrix == shouldMatch)
167 | }
168 |
169 | @Test
170 | fun populatePrimitiveMatrixTest() {
171 |
172 | val matrix = primitivematrix(rows=3,cols=3) {
173 | populate { row, col ->
174 | row * col
175 | }
176 | }
177 | val shouldMatch = PrimitiveMatrix.FACTORY.makeDense(3,3).also {
178 | it.set(0L,0L,0)
179 | it.set(0L,1L,0)
180 | it.set(0L,2L,0)
181 |
182 | it.set(1L,0L,0)
183 | it.set(1L,1L,1)
184 | it.set(1L,2L,2)
185 |
186 | it.set(2L,0L,0)
187 | it.set(2L,1L,2)
188 | it.set(2L,2L,4)
189 | }.build()
190 |
191 | assertTrue(matrix == shouldMatch)
192 | }
193 |
194 | @Test
195 | fun populateComplexMatrixTest() {
196 |
197 | val matrix = complexmatrix(rows=3,cols=3) {
198 | populate { row, col ->
199 | row * col
200 | }
201 | }
202 | val shouldMatch = ComplexMatrix.FACTORY.makeDense(3,3).also {
203 | it.set(0L,0L,0)
204 | it.set(0L,1L,0)
205 | it.set(0L,2L,0)
206 |
207 | it.set(1L,0L,0)
208 | it.set(1L,1L,1)
209 | it.set(1L,2L,2)
210 |
211 | it.set(2L,0L,0)
212 | it.set(2L,1L,2)
213 | it.set(2L,2L,4)
214 | }.build()
215 |
216 | assertTrue(matrix == shouldMatch)
217 | }
218 |
219 | @Test
220 | fun populateRationalMatrixTest() {
221 |
222 | val matrix = rationalmatrix(rows=3,cols=3) {
223 | populate { row, col ->
224 | row * col
225 | }
226 | }
227 | val shouldMatch = RationalMatrix.FACTORY.makeDense(3,3).also {
228 | it.set(0L,0L,0)
229 | it.set(0L,1L,0)
230 | it.set(0L,2L,0)
231 |
232 | it.set(1L,0L,0)
233 | it.set(1L,1L,1)
234 | it.set(1L,2L,2)
235 |
236 | it.set(2L,0L,0)
237 | it.set(2L,1L,2)
238 | it.set(2L,2L,4)
239 | }.build()
240 |
241 | assertTrue(matrix == shouldMatch)
242 | }
243 |
244 | @Test
245 | fun populateVarargPrimitiveMatrixTest() {
246 |
247 | val matrix = primitivematrix(rows=3,cols=3) {
248 | populate(0,0,0,0,1,2,0,2,4)
249 | }
250 | val shouldMatch = PrimitiveMatrix.FACTORY.makeDense(3,3).also {
251 | it.set(0L,0L,0)
252 | it.set(0L,1L,0)
253 | it.set(0L,2L,0)
254 |
255 | it.set(1L,0L,0)
256 | it.set(1L,1L,1)
257 | it.set(1L,2L,2)
258 |
259 | it.set(2L,0L,0)
260 | it.set(2L,1L,2)
261 | it.set(2L,2L,4)
262 | }.build()
263 |
264 | assertTrue(matrix == shouldMatch)
265 | }
266 |
267 | @Test
268 | fun populateVarargComplexMatrixTest() {
269 |
270 | val matrix = complexmatrix(rows=3,cols=3) {
271 | populate(0,0,0,0,1,2,0,2,4)
272 | }
273 | val shouldMatch = ComplexMatrix.FACTORY.makeDense(3,3).also {
274 | it.set(0L,0L,0)
275 | it.set(0L,1L,0)
276 | it.set(0L,2L,0)
277 |
278 | it.set(1L,0L,0)
279 | it.set(1L,1L,1)
280 | it.set(1L,2L,2)
281 |
282 | it.set(2L,0L,0)
283 | it.set(2L,1L,2)
284 | it.set(2L,2L,4)
285 | }.build()
286 |
287 | assertTrue(matrix == shouldMatch)
288 | }
289 |
290 | @Test
291 | fun populateVarargRationalMatrixTest() {
292 |
293 | val matrix = rationalmatrix(rows=3,cols=3) {
294 | populate(0,0,0,0,1,2,0,2,4)
295 | }
296 | val shouldMatch = RationalMatrix.FACTORY.makeDense(3,3).also {
297 | it.set(0L,0L,0)
298 | it.set(0L,1L,0)
299 | it.set(0L,2L,0)
300 |
301 | it.set(1L,0L,0)
302 | it.set(1L,1L,1)
303 | it.set(1L,2L,2)
304 |
305 | it.set(2L,0L,0)
306 | it.set(2L,1L,2)
307 | it.set(2L,2L,4)
308 | }.build()
309 |
310 | assertTrue(matrix == shouldMatch)
311 | }
312 |
313 | @Test
314 | fun vectorOfIntTest() {
315 | val v = vectorOf(1,2,3).transpose()
316 | val shouldMatch = PrimitiveMatrix.FACTORY.makeDense(1,3).also {
317 | it.set(0L,0L,1)
318 | it.set(0L,1L,2)
319 | it.set(0L,2L,3)
320 | }.build()
321 |
322 | assertTrue(v == shouldMatch)
323 | }
324 |
325 |
326 | @Test
327 | fun vectorOfDoubleTest() {
328 | val v = vectorOf(1.0,2.0,3.0).transpose()
329 | val shouldMatch = PrimitiveMatrix.FACTORY.makeDense(1,3).also {
330 | it.set(0L,0L,1)
331 | it.set(0L,1L,2)
332 | it.set(0L,2L,3)
333 | }.build()
334 |
335 | assertTrue(v == shouldMatch)
336 | }
337 |
338 | @Test
339 | fun vectorOfLongTest() {
340 | val v = vectorOf(1L,2L,3L).transpose()
341 | val shouldMatch = PrimitiveMatrix.FACTORY.makeDense(1,3).also {
342 | it.set(0L,0L,1)
343 | it.set(0L,1L,2)
344 | it.set(0L,2L,3)
345 | }.build()
346 |
347 | assertTrue(v == shouldMatch)
348 | }
349 |
350 | @Test
351 | fun vectorOfBigDecimalTest() {
352 | val v = vectorOf(BigDecimal.valueOf(1), BigDecimal.valueOf(2), BigDecimal.valueOf(3)).transpose()
353 | val shouldMatch = PrimitiveMatrix.FACTORY.makeDense(1,3).also {
354 | it.set(0L,0L,1)
355 | it.set(0L,1L,2)
356 | it.set(0L,2L,3)
357 | }.build()
358 |
359 | assertTrue(v == shouldMatch)
360 | }
361 | }
--------------------------------------------------------------------------------
/src/test/kotlin/org/ojalgo/okalgo/OptimizationTest.kt:
--------------------------------------------------------------------------------
1 | package org.ojalgo.okalgo
2 |
3 | import org.junit.Test
4 |
5 |
6 | class OptimizationTest {
7 |
8 | @Test
9 | fun expressionsBasedModelDSL() {
10 |
11 | expressionsbasedmodel {
12 |
13 | val v1 = variable(lower = 3, upper = 6)
14 | val v2 = variable(lower = 10, upper = 12)
15 |
16 | expression(weight = 1) {
17 | set(v1, 1)
18 | set(v2, 1)
19 | }
20 |
21 | maximise()
22 |
23 | println("v1=${v1.value.toDouble()} v2=${v2.value.toDouble()}")
24 | }
25 |
26 | }
27 |
28 | @Test
29 | fun expressionBuilderTest1() {
30 |
31 | expressionsbasedmodel {
32 |
33 | val v1 = variable(lower = 3, upper = 10)
34 | val v2 = variable(lower = 10, upper = 12)
35 |
36 | expression(
37 | expression = (.3 * v1) + (.2 * v2) GTE 4
38 | )
39 |
40 | maximise().run(::println)
41 |
42 | println("v1=${v1.value.toDouble()} v2=${v2.value.toDouble()}")
43 | }
44 |
45 | }
46 |
47 | @Test
48 | fun expressionBuilderTest2() {
49 |
50 | expressionsbasedmodel {
51 |
52 | val v1 = variable(lower = 2, upper = 10, isInteger = true)
53 | val v2 = variable(lower = 2, upper = 10, isInteger = true)
54 |
55 | expression(v1 + 2 * v2) {
56 | weight(1)
57 | }
58 |
59 | expression {
60 | set(v1 + v2 EQ 16)
61 | }
62 |
63 | minimise().run(::println)
64 |
65 | println("v1=${v1.value.toDouble()} v2=${v2.value.toDouble()}")
66 |
67 |
68 | }
69 |
70 | }
71 | }
72 |
--------------------------------------------------------------------------------