QUINNDO Logo QUINNDO Documentation

QUINNDO is a language designed for linear optimization and statistical analysis.

Basic Data Types

Number (num)

num a = 5 5
num a = 5.5 5.5
num a = 5.5e6 5,500,000 These syntaxes are why no symbol can be named "e"
num a = 1e-3 0.001
num a = 1_000_000 1,000,000 Numbers can use underscores as a thousands separator

Variable (var)

var a
var a,b More than one variable can be declared per line

Alias (alias)

Aliases are linear combinations of variables and numbers used in linear programming models.

alias a = 2b + 5
alias a = b Numbers and variables are castable to aliases
alias a = 5

Number Vector (nvec)

nvec v = [2,a]
nvec v = [2i for i=1 to 5] => [2,4,6,8,10]
nvec v = [2i for i=1 until 7 step 2] => [2,6,10]
nvec v = [2i for i in [6,9] ] => [12,18]

Variable Vector (vvec)

vvec v = [a,b]
vvec v = [x{i} for i=1 to 5] => [x1,x2,x3,x4,x5]

Alias Vector (avec)

avec v = [a,b]

Number Matrix (nmtx)

nmtx A = [ [1,2] , [3,4] ]
nmtx A = ntmx( [1,2,3,4] )

Variable Matrix (vmtx)

vmtx A = [ [a,b] , [c,d] ]
vmtx A = vtmx( [a,b,c,d] )

Boolean (bool)

bool b = true

Boolean Vector (bvec)

bvec v = [true,b]

String (str)

str s = "Hello World!"

String Vector (svec)

svec v = ["a",s]

Advanced Data Types

Number Matrix (nmtx)

nmtx( values:nvec , nrow?:num , ncol?:num , byrow?:bool=true )
values nvec The values to insert into the number matrix
nrow? num The number of rows the matrix should have If neither option is provided, the most square matrix will be built
nrow? num The number of columns of the matrix should have
byrow? bool Whether values should be inserted row first

Variable Matrix (vmtx)

vmtx( values:vvec , nrow?:num , ncol?:num , byrow?:bool=true )
values vvec The values to insert into the variable matrix
nrow? num The number of rows the matrix should have If neither option is provided, the most square matrix will be built
nrow? num The number of columns of the matrix should have
byrow? bool Whether values should be inserted row first

Model (model)

A Model is used to represent an optimization problem.

model( obj:alias )
obj alias The objective value to optimize

Network (ntwk)

A Network is used with its appended Nodes and Edges.

ntwk( bi?:bool=false )
bi? bool Whether to make the network bidirectional

Node (node)

A Node is used to represent a node/vertex in a Network.

node( id:str|num , source?:bool=false , sink?:bool=false )
id str|num The id of the node
source? bool Whether to make the node a source node
sink? bool Whether to make the node a sink node

Edge (edge)

A Node is used to represent an edge/arc in a Network.

edge( start:str|num|node , end:str|num|node , weight?:num=1 )
start str|num|node The starting node or the id of the starting node If no matching node is present in the network, a matching node will be created and added
end str|num|node The ending node or the id of the ending node
weight? num The weight assigned to this edge

Date (date)

If no values are provided, date() returns the current data and time in the user's time zone.

date(
  year?:num , month?:num , day?:num ,
  hour?:num , minute?:num , second?:num
)
year? num The year in the Gregorian calendar
month? num The month in the Gregorian calendar (Jan=1,Feb=2,...,Dec=12) Note: Throws if present without year
day? num The day in the month Note: Throws if present without month
hour? num The hour of the day in 24-hour format [0-23]
minute? num The minute of the hour [0-59] Note: Throws if present without hour
second? num The second of the minute [0-59] Note: Throws if present without minute

Date Vector (dvec)

A Date Vector is an enumerated vector of Date values.

Date Offset (offset)

A Date Offset is used to add or subtract period of time from a date.

offset(
  year?:num=0 , month?:num=0 , day?:num=0 ,
  hour?:num=0 , minute?:num=0 , second?:num=0
)
year? num The number of years to offset
month? num The number of months to offset
day? num The number of days to offset
hour? num The number of hours to offset
minute? num The number of minutes to offset
second? num The number of seconds to offset

Date Offset Vector (ovec)

A Date Offset Vector is an enumerated vector of Date Offset values.

Measurement (meas)

A Measurement value is a scalar with associated units.

meas( value:num , units:str )
value num The scalar of the measurement
units str The units of the measurement

Measurement Vector (mvec)

A Measurement Vector is an enumerated vector of Measurement values.

Plot (plot)

A plot is used to render visualization of objects.

plot()
This Inator takes no arguments.

Statistic Test Result (test)

A test object is used to hold the result of a statistical test.

test
This type cannot be created, only returned from another function.

Operators

Assignment (=)

The assignment operator is used to store values and to establish equality constraints in conjunction with a model object.

Addition (+)

Subtraction (-)

Mutliplication (*)

Division (/)

Percent (%)

The percent operator is used to divide a value by 100. For example, 5% is the same as 0.05.

Exponentiation (^)

Modulus (mod)

Factorial (!)

Transpose (')

The transpose operator only works on matrices.

Pointwise Addition (addeach)

Pointwise Subtraction (subeach)

Pointwise Mutliplication (multeach)

Pointwise Division (diveach)

Not (~)

And (&)

Or (|)

Exclusive Or (xor)

Not Or (nor)

Equality (==)

Not Equal (~=)

This symbol is typed as a tilde "~" followed by an equal sign "=".

Strict Equality (===)

When comparing numbers, equality returns true if two numbers are within 10-8 of each other to avoid floating point errors. However, when comparing numbers, strict equality only returns true if two values are exactly equal. Also applies to inner values within a vector.

Strict Not Equal (~==)

Same difference as Equality versus Strict Equality, but negated. This symbol is typed as a tilde "~" followed by two equal signs "==".

Conditional Ternary (?:)

The conditional ternary operator switches between two values based on the value of a boolean expression. For example, b?1:0 evaluates to 1 if b is true and 0 if b is false.

If-Then (=>)

See description of If-And-Only-If.

If-And-Only-If (<=>)

If-Then and If-And-Only-If are used in constraints when appending to a model object. If-Then and If-And-Only-If are written as "=",">" and "<","=",">", respectively.

Append (<|)

Appends an object to another object. All object that can have values appended to them are the same color. Written as "<" followed by "|".

Piping (|>)

Pipes the previous result into the following function. By default, the piped value will be passed as the first parameter in the following function. This can be changed with the result keyword. Written as "|" followed by ">".

Spread (...)

Spreads the values of a list over the parameters of a function or values of a vector. For example, range(1,10,3) and range(...[1,10,3]) are equivalent. Similarly, [ 0 , 1 , 2 , 3 ] and [ 0 , ...[ 1 , 2 ] , 3 ] are equivalent.

Vector Syntax

Vector Indexes

Vector indexes in QUINNDO are indexed from 1. Negative indexes count from the end. Non-integer indexes are not allowed.

nvec a = [4,5,6]
assert a[1] == 4
assert a[-1] == 6
assert a[0] == none # Error: No value at index 0
assert a[1.5] == none # Error: Non-integer index

Vector Slicing

Vectors can be sliced with the [start?:end?:step?] syntax. If not provided, the default value of start, end, and step is 1, the end of the vector, and 1, respectively. The sliced vector will include the end index.

nvec a = [4,5,6,7,8]
assert a[1:3] == [4,5,6]
assert a[:3] == [4,5,6]
assert a[2::2] == [5,7]

Vector Filtering

Vectors can be filtered by using the val keyword in the vector index with a filtering condition.

nvec a = [5,6,7,8,9]
assert a[val>6] == [7,8,9]
assert a[val>=6] == [6,7,8,9]
assert a[val mod 2==0] == [6,8]
list b = [6,true,none,8,a,10]
assert b[val is num] == [6,8,10]

Matrix Indexes

Similar to vector indexes, matrix rows can by retrieved with [index]. Matrix columns can be retrieved with {index}. Matrix rows and columns have the same abilities and restrictions as vector indexes.

Useful Keywords

in

in is used to check if a value is present in a vector.

nvec a = [6,7.5,9]
bool b = 6 in a # true
bool c = 8 in a # false
num d = 6
bool f = d in a # true

keyof

keyof is used to check if a given object has a given property.

test a = ttest( [1,2] , ~= , 5 )
bool b = "rejected" keyof a # true
bool c = "abcdef" keyof a # false

is and can

is and can are used to check the data-type of a value. is returns true if the data type exactly matches, while can returns true if a value can be casted to a given data type.

list a = [6,7.5,9]
bool b = a is list # true
bool c = a is nvec # false because a is a list
bool d = a can nvec # true because a contains only numbers

fa and fo

fa and fo make up QUINNDO's try...catch syntax. Use these statements to provide a fallback value if code encounters an error.

num a = 1 / 0 # Throws error
num b = fa 1 / 0 fo 5 # b=5
num c = fa 1 / 2 fo 5 # b=1/2

stfu

stfu ("Suppress This Faulty Utterance") is used to disable warnings and recommendations on a line-by-line basis. stfu must the last command on its line.

num a = 4 mod -3 # Raises warning because one parameter is negative
num b = 4 mod -3 stfu # Warning is suppressed
num c = 4 mod -3 stfu * 8 # Throws error because stfu is not at end of line

assert

assert evaluates a condition and throws an error if the condition is false.

assert 5 == 3 + 2
assert 6 == 3 + 2 # Throws error because assertion failed

Macros

Macros are special functions that handle larger operations and do not return a value.

Model Maximizer (maximize)

maximize( lp:model , thres?:num=1 )
lp model The model to be maximized
thres? num The solver tolerance for problem that contain integer constraints

Model Minimizer (minimize)

minimize( lp:model , thres?:num=1 )
lp model The model to be minimized
thres? num The solver tolerance for problem that contain integer constraints

Convert to LINDO (lindoize)

Converts a QUINNDO Model object to a LINDO program.

lindoize( lp:model , type:str )
lp model The model to be converted to LINDO
type str Must be one of "max" or "min"

Shortest Path Finder (min_path)

min_path( net:ntwk , anchor:str|num|node , render?:bool=false )
net ntwk The network in which to find the shortest path
anchor str|num|node The point from which to find the shortest path
render? bool Whether to print the model to the console on completion

Renderer (render)

render is used to draw plots in the console.

render( obj:plot )
obj plot The plot to draw in the console

Print (print)

print is used to print objects to the console.

print( obj:any )
obj any The object to print to the console

Math Operations

Sign (sign)

Returns 1 if a number is greater than 0, -1 if a number is less than 0, and 0 if the number is 0.

Natural Logarithm (log)

Base-2 Logarithm (log2)

Base-10 Logarithm (log10)

Exponential (exp)

Absolute Value (abs)

Floor (floor)

Round (round)

Ceiling (ceil)

Square Root (sqrt)

Cube Root (cbrt)

Cosine (cos)

Arc-Cosine (acos)

Sine (sin)

Arc-Sine (asin)

Tangent (tan)

Arc-Tangent (atan)

Statistical Summaries

Sum (sum)

Mean (mean)

Median (median)

Mode (mode)

List Maximum (max)

List Minimum (min)

Sample Standard Deviation (samsd)

Sample Variance (samvar)

Population Standard Deviation (popsd)

Population Variance (popvar)

R-Squared (rsq)

Least Squares Linear Regression (lsr)

lsr( x:nvec|nmtx , y:nvec , int?:bool=true ): nvec
x nvec|nmtx A vector containing x values for single-variate regression or a matrix with entries in rows and variables in columns for multivariate regression
y nvec The expected output values
int? bool Whether to include the intercept in the regression - ignored for single-variate regressions

Statistical Tests

One-Sample Z-Test (ztest)

ztest does a one-sample z-test.

ztest( sample:nvec , alt:operator , val:num , sigma:num , alpha?:num=5% ): test
sample nvec The sample data
alt operator The sign of the alternative hypothesis - must be one of ~=, >, or <
val num The threshold value of the alternative hypothesis
sigma num The population standard deviation
alpha? num The significance level of the test

Two-Sample Z-Test (ztest2)

ztest2 does a two-sample z-test.

ztest2(
  sample1:nvec , sample2:nvec , sigma1:num , sigma2:num ,
  alt?:operator= ~= , val?:num=0 , alpha?:num=5%
): test
sample1 nvec The sample data from the first sample
sample2 nvec The sample data from the second sample
sigma1 num The population standard deviation for sample1
sigma2 num The population standard deviation for sample2
alt? operator The sign of the alternative hypothesis - must be one of ~=, >, or <
val? num The threshold value of the alternative hypothesis
alpha? num The significance level of the test

One-Sample T-Test (ttest)

ttest does a one-sample t-test.

ttest( sample:nvec , alt:operator , val:num , alpha?:num=5% ): test
sample nvec The sample data
alt operator The sign of the alternative hypothesis - must be one of ~=, >, or <
val num The threshold value of the alternative hypothesis
alpha? num The significance level of the test

Two-Sample T-Test (ttest2)

ttest2 does a two-sample t-test.

ttest2(
  sample1:nvec , sample2:nvec ,
  alt?:operator= ~= , val?:num=0 , alpha?:num=5% , type?:num=0
): test
sample1 nvec The sample data from the first sample
sample2 nvec The sample data from the second sample
alt? operator The sign of the alternative hypothesis - must be one of ~=, >, or <
val? num The threshold value of the alternative hypothesis
alpha? num The significance level of the test
type? num The type of t-test to run (0=Welch's,1=Pooled,2=Student's)

F-Test (ftest)

ftest does an F-test.

ftest( sample1:nvec , sample2:nvec , alt?:operator= ~= , alpha?:num=5% ): test
sample1 nvec The sample data from the first sample
sample2 nvec The sample data from the second sample
alt? operator The sign of the alternative hypothesis - must be one of ~=, >, or <
alpha? num The significance level of the test

ANOVA (anova)

anova does an ANOVA.

anova( samples:nmtx , alpha?:num=5% ): test
samples nmtx The data for the ANOVA - each factor must be a row
alpha? num The significance level of the test

Goodness of Fit Test (goftest)

goftest does a Χ2 goodness of fit test.

goftest( observed:nvec , expected:nvec , alpha?:num=5% ): test
observed nvec The observed values
expected nvec The expected values to compare against
alpha? num The significance level of the test

Χ2 Test for Independence (indtest)

indtest does a Χ2 test for independence.

indtest( values:nmtx , alpha?:num=5% ): test
values nmtx The data for the independence test
alpha? num The significance level of the test

Vector & Matrix Functions

Vector Range Builder (range)

range( start?:num=1 , end:num , step?:num=1 ): nvec
start? num The start value of the final array
end num The end value of the final array, which will be included
step? num The step between values

Vector Size (size)

size( x:list|str ): num
x list|str The value of which to find the size

Matrix Row Count (nrow)

An alias of size for matrices.

nrow( x:nmtx|vmtx ): num
x nmtx|vmtx The matrix from which to find the number of rows

Matrix Column Count (ncol)

Gets the number of column from a rectangular matrix.

ncol( x:nmtx|vmtx ): num
x nmtx|vmtx The matrix from which to find the number of columns

Matrix Max Column Count (maxcol)

Gets the number of elements in the longest row of a matrix.

maxcol( x:nmtx|vmtx ): num
x nmtx|vmtx The matrix from which to find the max row length

Matrix Min Column Count (mincol)

Gets the number of elements in the shortest row of a matrix.

mincol( x:nmtx|vmtx ): num
x nmtx|vmtx The matrix from which to find the min row length

Unit Vector Normalizer (unit)

Returns a vector normalized to a magnitude of 1.

unit( v:nvec ): nvec
v nvec The vector to normalize

Probability Normalizer (prob)

Returns a vector normalized to a valid probability distribution.

prob( v:nvec ): nvec
v nvec The vector to convert to a probability distribution

Z-Score Normalizer (norm)

Returns a vector normalized to a mean of 0 and a sample standard deviation of 1.

norm( v:nvec ): nvec
v nvec The vector to normalize

Vector Sorter (sort)

sort( v:nvec|svec , reverse?:bool=false ): nvec
v nvec|svec The vector to sort
reverse? bool The direction in which to sort the list - ascending if false, descending if true

Matrix Trace (trace)

trace( m:nmtx ): num
m nmtx The matrix of which to find the trace

Matrix Determinant (deter)

deter( m:nmtx ): num
m nmtx The matrix of which to find the determinant

Matrix Diagonal Elements (diag)

diag( values:nmtx ): nvec
values nmtx The matrix of which to find the diagonal elements

Identity Matrix (identity)

identity( n:num ): nmtx
n num The dimension of the identity matrix

Matrix Inversion (inv)

inv( m:nmtx ): nmtx
m nmtx The matrix to invert

Unique Elements (unique)

Returns a copy of a list with duplicates removed.

unique( x:list ): list
x list The list from which to remove duplicates

Common Elements (union)

Returns a list with values common to two lists.

union( list1:list , list2:list ): list
list1 list The first list
list2 list The second list

Miscellaneous Functions

String Vector Joiner (join)

Joins a String Vector into a String with a given string.

join( v:svec , sep?:str=" " ): str
v svec The string vector to join
sep? str The string with which to join the vector

String Splitter (split)

Splits a String into a String Vector with a given string.

split( s:str , sep?:str=" " ): svec
s str The string to split
sep? str The string with which to split the string

Examples

Scatter Plot

nvec x = range(5) # [1,2,3,4,5]
nvec y = range( 5 , 13 , 2 ) # [5,7,9,11,13]
plot p = plot.scatter( x , y )
render(p)

Student's 2-Sample T-Test

nvec s1 = [7,2,4]
nvec s2 = range(3) # [1,2,3]
test t = ttest2( s1 , s2 , type=ttest2.student )

Integer Programming

The Lotus Point Condo Project will contain both homes and apartments. The site can accommodate up to 10,000 dwelling units. The project must contain a recreation project: either a swimming-tennis complex or a sailboat marina, but not both. If a marina is built, then the number of homes in the project must be at least triple the number of apartments in the project. A marina will cost $1.2 million, and a swimming-tennis complex will cost $2.8 million. The developers believe that each apartment will yield revenues with an NPV of $48,000, and each home will yield revenues with an NPV of $46,000. Each home (or apartment) costs $40,000 to build. Formulate an IP to help Lotus Point maximize profits.

Problem From: Winston, W. L., & Goldberg, J. B. (2004). Operations research: Applications and Algorithms. Brooks/Cole. var a,h,m,t # apartments, homes, marina, tennis complex
model p = model( 8a + 6h - 1200m - 2800t )
p <| a + h <= 10_000 # building constraint
p <| m = 1 xor t = 1 # either marina or tennis/swimming
p <| m = 1 => h >= 3a # marina building type constraint
p <| a,h is int # integer constraint
p <| m,t is bin # binary constraint
maximize(p)

Shortest Path

ntwk n = ntwk()
n <| edge( 1 , 2 , 1 ) # start,end,weight
n <| edge( 1 , 3 , 2 )
n <| edge( 2 , 3 , 3 )
n <| edge( 3 , 2 , 1 )
n <| edge( 2 , 4 , 3 )
n <| edge( 3 , 4 , 2 )
min_path( n , 1 ) # Get shortest path to all other nodes from node 1