Unity DGMS is an open-source JSONiq analytics run-time environment for building model-driven decision guidance applications.
- Website (and documentation): https://www.dgms.io/
- Source: https://github.com/nachawati/unity
- Bug reports: https://github.com/nachawati/unity/issues
The primary way to install Unity DGMS is through the pre-built Docker image dgms/dgms
that is hosted on DockerHub. To simplify the use of the Docker image with local files, it is recommended to install the dgms
package from the npm registry, which adds the system command dgms
for running Unity DGMS from the terminal.
Please make sure that you have Docker and Node.js installed on your system.
To install Unity DGMS, pull the pre-built Docker image dgms/dgms
:
docker pull dgms/dgms:0.1.0-SNAPSHOT
To install the dgms
system command, using the Node.js package manager npm
or yarn
run:
npm install dgms --global
You can test the installation by running:
dgms run --query 1+1
If successful, this should write 2
to the standard output.
The pre-built Docker image provides a variety of open source solvers for LP, MILP, NLP, MINLP problems, as well as a large number metaheuristic algorithms for black-box, multi-objective and stochastic optimization. If these solvers do not fit your needs, Unity DGMS also supports a large number of non-free solvers via CasADi and Pyomo.
To use additional solvers with Unity DGMS, simply add the path of the directory containing the solver binaries to the DGMS_BIN
environmental variable. If a solver depends on any shared libraries, also add the path of the directory containing those shared libraries to the DGMS_LIB
environmental variable.
Compact queries can be run directly from the terminal using the dgms run
command, for example:
dgms run --query let $input := { text: "Hello World" } return $input.text
This should write Hello World
to the standard output.
Unity DGMS integrates with Project Jupyter to provide out-of-the-box support for interactive computing with JSONiq.
To start a Jupyter console session with Unity DGMS, run the following command from the terminal:
dgms console
To start a Jupyter notebook session with Unity DGMS, run the following command from the terminal:
dgms notebook
To start a Jupyter lab session with Unity DGMS, run the following command from the terminal:
dgms lab
Files containing longer scripts and queries can also be run from the terminal using the dgms run
command. For example, to run the module expenditure.jq
:
jsoniq version "1.0";
import module namespace n = "http://dgms.io/modules/numerics";
import module namespace plt = "http://dgms.io/modules/plot";
variable $t := n:linspace(0, 10);
variable $c := n:square($t);
variable $ax := plt:subplot();
$ax.plot($t, $c);
$ax.set({xlabel: "time (s)", ylabel: "spending ($)", title: "Expenditure"});
$ax.grid();
plt:show();
from the terminal, navigate to the directory containing the expenditure.jq
file and run the following command:
dgms run expenditure.jq
This should generate the plot shown below:
The following example module optimization.jq
shows how Unity DGMS can be used for optimization:
jsoniq version "1.0";
import module namespace a = "http://dgms.io/modules/analytics";
declare function local:model($input)
{
let $x := $input.x
let $y := $input.y
let $cost := 10 * $x + 15 * $y
return {
cost: $cost,
constraints: [
$x div 7 + $y div 9 <= 40
]
}
};
let $input := {
x: a:variable({ bounds: [175, 250], domain: "integer" }),
y: a:variable({ bounds: [50, 400], domain: "integer" })
}
return a:maximize({
model: local:model#1,
input: $input,
objective: function($output) {
$output.cost
},
constraints: function($output) {
$output.constraints
},
options: {
solver: "cbc"
}
})
To optimize, run the following command in the directory containing optimization.jq
:
dgms run optimization.jq -r result.json
This should write the following to the file result.json
:
{
"solution" : {
"x": 175,
"y": 135
},
"solver" : {
"name" : "cbc",
"time" : 0.0832550525665283,
"termination-condition" : "optimal",
"status" : "ok"
}
}
The following example module calibration.jq
shows how Unity DGMS can be used for calibrating analytical models:
jsoniq version "1.0";
import module namespace a = "http://dgms.io/modules/analytics";
declare function local:model($input)
{
let $X := $input.X
let $W := $input.W
let $b := $input.b
return {
cost: $X * $W + $b
}
};
let $X := a:placeholder()
let $Y := a:placeholder()
return
a:calibrate({
model: local:model#1,
input: {
X: $X,
W: a:parameter(),
b: a:parameter()
},
output: {
cost: $Y
},
loss: function($observed, $predicted, $batch-size) {
n:reduce-sum(n:pow($observed.cost - $predicted.cost, 2)) div (2 * $batch-size)
},
bindings: {
$X: n:asarray([...]),
$Y: n:asarray([...])
}
})
To optimize, run the following command in the directory containing calibration.jq
:
dgms run calibration.jq -r result.json
Unity DGMS adopts the CommonJS package format for the modular development, configuration, and distribution of DG applications and libraries, which can then be published to or installed from the npm registry or any Git repository.
To initialize a new package for Unity DGMS, simply use npm init
or yarn init
-
From the terminal, set the current working directory to the directory that will serve as the root directory of the package.
cd /path/to/package
-
Run the following command:
npm init
This will generate a package.json
file in the root directory of the package, similar to the following:
{
"name": "<name>",
"version": "<version>",
"description": "<description>",
"main": "<main>",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "<author>",
"license": "<license>"
}
To install a dependency from the npm registry, in the root directory of the package, run the following command, replacing <dependency>
with the name of the dependency from the npm registry to install:
npm install <dependency>
To publish a package to the npm registry, run the following command from the root directory of the package:
npm publish
Unity DGMS resolves references to external JSONiq modules and JSON documents within a single package based on the standard Zorba URI resolution scheme. For example, the following URL:
http://dgms.io/modules/mymodule
is transformed into the package-relative path:
lib/io/dgms/modules/mymodule.jq
If no file exists at that location in the main package, Unity DGMS will systematically look for a file that matches the package-relative path in the closure of all dependencies of the main package.
Unity DGMS supports executing C++ code directly from JSONiq queries based on the default Zorba external function interface.
A clean build of Unity DGMS is performed in two steps:
Step 1: Clean project and build dependencies
./mvnw clean install -P dependencies-linux-gcc-amd64
Step 2: Build project
./mvnw install
This will build a binary distribution of Unity DGMS with all core dependencies inside the ./target/linux-gcc-amd64
folder. You can test the build by running:
cd ./target/linux-gcc-amd64
java -Xrs -Xms1024m -jar ./lib/unity-cli-<VERSION>.jar run 1+1
If you find Unity DGMS useful in your work, please cite our ICEIS 2017 paper: "Unity Decision Guidance Management System: Analytics Engine and Reusable Model Repository" (pdf):
@inproceedings{NachawatiBrodskyLuo2017,
author = {Mohamad Omar Nachawati and Alexander Brodsky and Juan Luo},
title = {Unity Decision Guidance Management System: Analytics Engine and Reusable Model Repository},
booktitle = {Proceedings of the 19th International Conference on Enterprise Information Systems (ICEIS 2017)},
volume = {1},
pages = {312-323},
year = {2017},
doi = {10.5220/0006338703120323},
}