MathCortex is a open source numerical computing environment and a lightweight programming language.
It is written in JavaScript and works on web browsers.
All the operations are done on browser for fast and server independent computing. The code is first compiled to a simple JavaScript intermediate code. The generated JavaScript code is evaluated and runs very fast on the browser.
Language is still being developed.
The compiler code is distributed under GPL license. MathCortex on Github
The virtual machine code(cortex_asm_vm.js) and cortex run time library(cortex_runtime.js) is under MIT license.
In single processor environment with using the spectralnorm example at: http://benchmarksgame.alioth.debian.org/u64q/performance.php?test=spectralnorm , there is only x2 difference between MathCortex and native C application and when multi processor is enabled(openmp) there is x5.2 speed difference with native C application.
Compared to Python, MathCortex runs nearly 50 times faster for spectralnorm example.
C | MathCortex | Python | JavaScript | |
---|---|---|---|---|
5500 (single) | 4.0 s | 8.8 s | 8.4 s | |
10000 (single) | 13.6 s | 27.5 s | 27.2 s | |
5500 (multi) | 1.7 s | 8.8 s | 437 s | 8.4 s |
10000 (multi) | 4.5 s | 27.5 s | 1415 s | 27.2 s |
Tests are done using Firefox 38.0.1, Visual Studio 2010, Python 3.4.3
Syntax is heavily influenced by JavaScript and C.
Statements are seperated by semicolumn ;.The last statement of a script need not to end with semicolumn.
Assignment operator is =.
Function call operator is (..).
s = sin(pi/5);
[..] is matrix creation if it does not follow a matrix variable. ; is used to seperate rows. , is not required to seperate columns but adviced. ( [1 2] is ok but [1 -2] will be [-1] which may cause confusion)
m1 = [1,2;5,6]; m2 = [ 1 2; 2 4]; m3 = @[-1 -2; 2 -3]; // verbatim mode. (without @ m3 would be [-3; -1])
[..,..] is matrix indexing operator if it follows a matrix variable. , is used to seperate row and column index.
m = [1,2;5,6]; m21 = m[1, 0]; // indices are zero based m[1, 1] = 66;
m = [1,2,3; 4,5,6; 7,8,9]; m1 = m[0, :]; // m1 will be [1,2,3] m2 = m[1, 0:1]; // m2 will be [4,5] m3 = m[:, 1:-1]; // m3 will be [2,3; 5,6; 8,9] m[1:2, 0:1] = eye(2); // m will be [1,2,3; 1,0,6; 0,1,9];
Type system is static with full type inference so that no explicit declarations required.
Currently supported types are:
r = -3.14; m = eye(3); b1 = true; b2 = (1 == 2); s1 = "hello"; s2 = " world : "; s = s1 + s2 + r;
Note that declarations are implicit. But once a variable is declared as one type, its type can not change
Currently implemented operators are (from lowest to highest precedence):
Name | Operator | Description |
---|---|---|
Assignment | =, =/, =*, =+, =- | Logical OR | || | bool only |
Logical AND | && | bool only |
Relation | ==, !=, <, >, <=, >= | Reals supports all operators Matrices and strings support ==, != only. |
Colon | : | a = 1:3, 1:2:10, 10:-2: 4 |
Addition / Subtraction | +, - | Supported for reals and matrices. String only support + |
Multiply / Division / Elementwise | *, /, .*, ./, % | Matrices support *, .*, ./, % Reals support *, /, % |
Logical NOT | ! | bool only |
Matrix Transpose | ' | Matrices |
Prefix | ++, -- | Reals and matrices |
Postfix | ++, -- | Reals and matrices |
Function call / Array subscripting/ Member and method access | (), [], . | |
Parenthesis | ( .. ) | Ordering expressions (3+4)*3 |
Matrix to matrix operations : +, -, *, ==, !=
Elementwise matrix multiply and divide : .*, ./
Matrix to scalar operations : +, -, *, /
Currently loop, loop0, while, if/else, for can be used for control and loop statements.
Syntax for while, for, if/else is just like JavaScript and C. break, continue is supported like C. { } can be used(optional) to define blocks
These are simplifed version of for loop. loop0(i, count) iterates i from 0 to count-1. loop(i, start, end) iterates i from start to end-1.
x = 0.5; if( x < 0) { disp("x is negative"); } else // { } is optional disp("x is positive"); loop0(i, 10) disp(i); // prints 0 to 9 loop(i, 2, 5) disp(i); // prints 2 to 4 for(i = 0; i < 10; i++) disp(i); // prints 0 to 9 i = 10; while(i > 6) { disp(i); // prints 10 to 6 i--; }
Functions are defined without giving any type information with support to local varibles.
function add(a, b) { return a+b; } r = add(5, 6); // 11 m = add([5, 2], [6, -1]); // [11, 1] s = add([5, 2], 3); // [8, 5]
Because of parameters are declared implicitly and mathcortex is static typed, they are generic types (like templates in C++). Three different machine code will be generated for the example above.
Variables defined inside a function scope will be local and will not be visible anywhere. Global and local usage is similiar to Python: global keywords should be used to create or write to a global variable. 'global' keyword is not required to read from global variable. Global variables are declared at top most scope, outside of any function code.
MathCortex has support for full type inference with implicit typing and also it supports generic programming.
// first class function example: functions can be used as a variable or parameter // f, g, h are some functions function f(x) { return x; } function h(x) { return x+2; } function g(x) { return x+1; } d1 = g; // d1 is a function variable d1 = f; // function variables can change value d2 = h; // d2 is another function variable d3 = d2; // function variables can be assigned to one other r = d1(1); m1 = d2([2]); // these all functions also support generic types(like templates) m2 = d2("hello "); s = d3("world "); d4 = f(h); // function variables can be passed as argument
You can make powerfull yet simple statements with type inference and generic programming without any runtime costs.
//type inference and generics example function add(a,b) { return a+b; } r = add(3, 5); // r will be 7 m = add([1,2;4,5], [1,-1;-2,-4]); // m will be [ 2, 1; 2, 1 ] s = add( "hello" , 3); // s will be 'hello3' //type inference and generics works with first class functions. //type resolution will be done in compile to so there is no runtime cost. function f(x) => x+1; function g(x) => x-1; function m(x) { if (x == 1) return f; else return g; } r = m(1)(3); // m(1) returns function f, f(3) return 4 so r is 4 A = m(2)( eye(3)); // m(2) returns function g, g((eye(3)) returns matrix: 0, -1, -1; -1, 0, -1; -1, -1, 0
MathCortex supports lambda/anonymous first class functions
// Lambda syntax allows shorter anonymous function definitions f1 = function (a,b) => a + b; f2 = (a,b) => a + b; f3 = () => 5; f4 = (a) => a + 5; // also name can be given for non anonymous version function f(x) => x+1;
Functions with more than one return value can be defined like the following example
//user multi return functions: function [a,b] = mf(x,y,z) { a = x + z; b = y + z; } [a b ] = mf(3,5,6);
// class definition is like function definition and also constructor // all local varibles becomes members. 'var' keyword should be used for local variables class Point3d(a,b,c) { // x, y, z are members x = a; y = -b; z = rand(4, 4); // l is a local variable var l; l = 3; } a1 = Point3d(0, 2, 5); a2 = Point3d("str", 6, 220); a3 = Point3d(110, 2, 5); bb = Point3d(0, 0, [2]);
p1 = class Point3{ p1 : 2, p2 : 3, p4 : "aa"}; p2 = Point3(4, [6], "aaa"); // anonymous class without type name p3 = class { p1 : 2, p2 : 3, p4 : "aa"}; // anonymous class with anonymous member p4 = class { p1 : 2, p2 : 3, p4 : "aa", m1 : (a, b) => a + b };
class C1() { a = 4; function m2(x, y, z) { return x + y * z; } function m3() => m2(1, 2, 3) + a; } a1 = C1(); d1 = a1.m3(); class C2() { a=4; function m2() => a++; function m3(x) => x + m2(); } a1 = C2(); d1 = a1.m3(-2); d2 = a1.m3(-2);
C and JavaScript style comments are supported.
/* Multi line comment */ x = 5; // this is a single line comment
Matrix eye numcols numrows linspace ones rand randn zeros
Matrix Algebra cholesky det eig fft inv linsolve lu svd
Stats diff mean std sum variance
Elementary abs acos asin atan atan2 ceil cos exp floor fmod
Elementary log min max pow random round sqrt sin tan
Utility clear clc close error tic toc typeof
Animation anim animdraw animstop animsize
Y = inv(X)
d = det(X)
disp(X)
Y = trans(X)
X = eye(n)
X = zeros(n)
X = zeros(m,n)
X = ones(n)
X = ones(m,n)
X = rand(n)
X = rand(m,n)
X = randn(n)
X = randn(m,n)
abs(x), acos(x), asin(x), atan(x), atan2(y,x), ceil(x), cos(x), exp(x), floor(x), log(x), max(x,y,z,...,n), min(x,y,z,...,n), pow(x,y), random(), round(x), sin(x), sqrt(x), tan(x)
s = sum(X)
m = mean(X)
s = std(X), v = variance(X)
Y = diff(X)
y = linspace(a,b)
y = linspace(a,b,n)
[d p] = lu(A)
x = linsolve(A,b)
X = svd(X)
[U S V] = svd(X)
L = eig(X)
[L V] = eig(M)
Re= fft(X)
[Re Im] = fft(X)
L = cholesky(X)
plot(X)
plot(X,Y)
plot(X,Y,opts)
plot(X1,Y1,X2,Y2)
plot(X1,Y1,opts1,X2,Y2,opts2)
Line Colors:
|
Point symbols:
|
tic() ... toc()
clear X
clear all
clc
h = plot([1,2,5]);
close(h);
close all;
error("invalid data")
typeof([0] + 3);
c = numcols(X); r = numrows(X);
preload { "url" };
...
[r g b] = imread("url");
imshow(I)
imshow(R, G, B)
title("sine of x")
title(h, "sine of x")
function update(id) { animdraw( id, 255 * ones(100,100) ); } anim(update, 60);
animdraw(id, R, G, B)
animdraw(id, G)
animstop
animsize(width,height)
Let's Build a Compiler, by Jack Crenshaw
Flot - JavaScript plotting library
My name is Gorkem Gencay. I have started programming nearly 20 years ago. I am working as a professional programmer for more than 12 years. I mostly used C/C++ for work.
I have started this project mainly for fun. Than I thought that I can use it for simple scripting which has support for built-in matrix and numerical computations.
I also wanted that it can be easily accessed and integrated. By doing stuff on web browser, it will be platform independent, no installation or setup, can be accessed from everywhere.
It is my first web application. My first JavaScript, HTML and CSS experience.