lomath
Version:
Lomath is a tensorial math library extended from lodash.
1,119 lines (789 loc) • 127 kB
HTML
<!DOCTYPE html>
<html>
<head>
<title>index.js</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, target-densitydpi=160dpi, initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">
<link rel="stylesheet" media="all" href="docco.css" />
</head>
<body>
<div id="container">
<div id="background"></div>
<ul class="sections">
<li id="title">
<div class="annotation">
<h1>index.js</h1>
</div>
</li>
<li id="section-1">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-1">¶</a>
</div>
<p>//////////
lomath //
//////////</p>
</div>
</li>
<li id="section-2">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-2">¶</a>
</div>
<p>Prepare lodash for extension and export</p>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-keyword">var</span> _ = <span class="hljs-built_in">require</span>(<span class="hljs-string">'lodash'</span>).runInContext();</pre></div></div>
</li>
<li id="section-3">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-3">¶</a>
</div>
<p>the module: lodash extended with math mixins</p>
</div>
<div class="content"><div class='highlight'><pre><span class="hljs-keyword">var</span> lomath = _.mixin({
AUTHOR: <span class="hljs-string">"kengz"</span>,
VERSION: <span class="hljs-string">"0.2.9"</span>,</pre></div></div>
</li>
<li id="section-4">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-4">¶</a>
</div>
<p>////////////////////////////
Function builder backend //
////////////////////////////</p>
</div>
</li>
<li id="section-5">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-5">¶</a>
</div>
<p>We employ clearer terminologies to distinguish the “depth” or the “dimension” of the objects. In general, we call generic array of depth-N a “N-tensor” or “rank-N tensor”. A scalar is “0-tensor”; a simple array/vector is “1-tensor”, matrix (array of arrays) is “2-tensor”, and so on.
A generic function that operates over tensor is built from an atomic function fn taking two scalar arguments.
Applying a function into depths of tensor is done via distribution, and evaluating a multi-argument function is done via associativity.
sample operation to demonstrate function composition</p>
</div>
<div class="content"><div class='highlight'><pre> op: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">x, y</span>) </span>{
<span class="hljs-keyword">return</span> x + <span class="hljs-string">'*'</span> + y;
},</pre></div></div>
</li>
<li id="section-6">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-6">¶</a>
</div>
<p>distribute a unary function over every scalar in tensor Y;</p>
</div>
<div class="content"><div class='highlight'><pre> distributeSingle: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">fn, Y</span>) </span>{
<span class="hljs-keyword">if</span> (!(Y <span class="hljs-keyword">instanceof</span> <span class="hljs-built_in">Array</span>)) <span class="hljs-keyword">return</span> fn(Y);
<span class="hljs-keyword">var</span> len = Y.length,
res = <span class="hljs-built_in">Array</span>(len);
<span class="hljs-keyword">while</span> (len--) res[len] = Y[len] <span class="hljs-keyword">instanceof</span> <span class="hljs-built_in">Array</span> ?
lomath.distributeSingle(fn, Y[len]) : fn(Y[len])
<span class="hljs-keyword">return</span> res;
},</pre></div></div>
</li>
<li id="section-7">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-7">¶</a>
</div>
<p>Distribute fn with left tensor X over right scalar y.</p>
</div>
<div class="content"><div class='highlight'><pre> distributeLeft: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">fn, X, y</span>) </span>{
<span class="hljs-keyword">var</span> len = X.length,
res = <span class="hljs-built_in">Array</span>(len);
<span class="hljs-keyword">while</span> (len--) res[len] = X[len] <span class="hljs-keyword">instanceof</span> <span class="hljs-built_in">Array</span> ?
lomath.distributeLeft(fn, X[len], y) : fn(X[len], y)
<span class="hljs-keyword">return</span> res;
},</pre></div></div>
</li>
<li id="section-8">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-8">¶</a>
</div>
<p>Distribute fn with left scalar x over right tensor Y.</p>
</div>
<div class="content"><div class='highlight'><pre> distributeRight: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">fn, x, Y</span>) </span>{
<span class="hljs-keyword">var</span> len = Y.length,
res = <span class="hljs-built_in">Array</span>(len);
<span class="hljs-keyword">while</span> (len--) res[len] = Y[len] <span class="hljs-keyword">instanceof</span> <span class="hljs-built_in">Array</span> ?
lomath.distributeRight(fn, x, Y[len]) : fn(x, Y[len])
<span class="hljs-keyword">return</span> res;
},</pre></div></div>
</li>
<li id="section-9">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-9">¶</a>
</div>
<p>Distribute fn between non-scalar tensors X, Y: pair them up term-wise and calling distribute recursively.
If at any depth X and Y have different lengths, recycle if the mod of lengths is 0.</p>
</div>
<div class="content"><div class='highlight'><pre> distributeBoth: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">fn, X, Y</span>) </span>{
<span class="hljs-keyword">var</span> Xlen = X.length,
Ylen = Y.length;
<span class="hljs-keyword">if</span> (Xlen % Ylen == <span class="hljs-number">0</span> || Ylen % Xlen == <span class="hljs-number">0</span>) {
<span class="hljs-keyword">var</span> res;
<span class="hljs-keyword">if</span> (Xlen > Ylen) {
res = <span class="hljs-built_in">Array</span>(Xlen);
<span class="hljs-keyword">while</span> (Xlen--) res[Xlen] = lomath.distribute(fn, X[Xlen], Y[Xlen % Ylen]);
} <span class="hljs-keyword">else</span> {
res = <span class="hljs-built_in">Array</span>(Ylen);
<span class="hljs-keyword">while</span> (Ylen--) res[Ylen] = lomath.distribute(fn, X[Ylen % Xlen], Y[Ylen]);
}
<span class="hljs-keyword">return</span> res;
} <span class="hljs-keyword">else</span> <span class="hljs-keyword">throw</span> <span class="hljs-string">"Cannot distribute arrays of different dimensions."</span>;
},</pre></div></div>
</li>
<li id="section-10">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-10">¶</a>
</div>
<p>Generic Distribute: Distribute fn between left tensor X and right tensor Y, while preserving the argument-ordering (vital for non-commutative functions).
lomath pairs up the tensors term-wise while descending down the depths recursively, until finding a scalar to distributeLeft/Right.
Method is at its fastest, and assuming the data depth isn’t too deep (otherwise JS will have troubles with it)</p>
</div>
<div class="content"><div class='highlight'><pre> distribute: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">fn, X, Y</span>) </span>{
<span class="hljs-keyword">if</span> (X <span class="hljs-keyword">instanceof</span> <span class="hljs-built_in">Array</span>)
<span class="hljs-keyword">return</span> Y <span class="hljs-keyword">instanceof</span> <span class="hljs-built_in">Array</span> ?
lomath.distributeBoth(fn, X, Y) : lomath.distributeLeft(fn, X, Y);
<span class="hljs-keyword">else</span>
<span class="hljs-keyword">return</span> Y <span class="hljs-keyword">instanceof</span> <span class="hljs-built_in">Array</span> ?
lomath.distributeRight(fn, X, Y) : fn(X, Y);
},</pre></div></div>
</li>
<li id="section-11">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-11">¶</a>
</div>
<p>Generic associate: take the arguments object or array and apply atomic fn (non-tensor) from left to right</p>
</div>
<div class="content"><div class='highlight'><pre> asso: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">fn, argObj</span>) </span>{
<span class="hljs-keyword">var</span> len = argObj.length,
i = <span class="hljs-number">0</span>;</pre></div></div>
</li>
<li id="section-12">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-12">¶</a>
</div>
<p>optimize arg form based on length or argObj</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> args = len < <span class="hljs-number">3</span> ? argObj : _.toArray(argObj),
res = fn(args[i++], args[i++]);
<span class="hljs-keyword">while</span> (i < len) res = fn(res, args[i++]);
<span class="hljs-keyword">return</span> res;
},</pre></div></div>
</li>
<li id="section-13">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-13">¶</a>
</div>
<p>Associate with distributivity: Similar to asso but is for tensor functions; apply atomic fn distributively from left to right.
Usage: for applying fn on tensors element-wise if they have matching dimensions.</p>
</div>
<div class="content"><div class='highlight'><pre> assodist: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">fn, argObj</span>) </span>{
<span class="hljs-keyword">var</span> len = argObj.length,
i = <span class="hljs-number">0</span>;</pre></div></div>
</li>
<li id="section-14">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-14">¶</a>
</div>
<p>optimize arg form based on length or argObj</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> args = len < <span class="hljs-number">3</span> ? argObj : _.toArray(argObj),
res = lomath.distribute(fn, args[i++], args[i++]);
<span class="hljs-keyword">while</span> (i < len) res = lomath.distribute(fn, res, args[i++]);
<span class="hljs-keyword">return</span> res;
},</pre></div></div>
</li>
<li id="section-15">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-15">¶</a>
</div>
<p>Future:
Future:
Future:
cross and wedge, need index summation too, matrix mult.</p>
</div>
</li>
<li id="section-16">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-16">¶</a>
</div>
<p>///////////////////
Basic functions //
///////////////////
Concat all arguments into single vector by _.flattenDeep</p>
</div>
<div class="content"><div class='highlight'><pre> c: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
<span class="hljs-keyword">return</span> _.flattenDeep(_.toArray(<span class="hljs-built_in">arguments</span>));
},</pre></div></div>
</li>
<li id="section-17">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-17">¶</a>
</div>
<p>atomic sum: takes in a tensor (any rank) and sum all values</p>
</div>
<div class="content"><div class='highlight'><pre> a_sum: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">T</span>) </span>{</pre></div></div>
</li>
<li id="section-18">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-18">¶</a>
</div>
<p>actual function call; recurse if need to</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> total = <span class="hljs-number">0</span>,
len = T.length;
<span class="hljs-keyword">while</span> (len--) total += (T[len] <span class="hljs-keyword">instanceof</span> <span class="hljs-built_in">Array</span> ?
lomath.a_sum(T[len], <span class="hljs-number">0</span>) : T[len])
<span class="hljs-keyword">return</span> total;
},</pre></div></div>
</li>
<li id="section-19">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-19">¶</a>
</div>
<p>sum all values in all arguments</p>
</div>
<div class="content"><div class='highlight'><pre> sum: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
<span class="hljs-keyword">var</span> res = <span class="hljs-number">0</span>;
<span class="hljs-keyword">var</span> len = <span class="hljs-built_in">arguments</span>.length;
<span class="hljs-keyword">while</span> (len--) res += (<span class="hljs-built_in">arguments</span>[len] <span class="hljs-keyword">instanceof</span> <span class="hljs-built_in">Array</span> ?
lomath.a_sum(<span class="hljs-built_in">arguments</span>[len]) : <span class="hljs-built_in">arguments</span>[len])
<span class="hljs-keyword">return</span> res;
},
fsum: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">T, fn</span>) </span>{
<span class="hljs-keyword">var</span> sum = <span class="hljs-number">0</span>;
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i = <span class="hljs-number">0</span>; i < T.length; i++)
sum += fn(T, i);
<span class="hljs-keyword">return</span> sum;
},</pre></div></div>
</li>
<li id="section-20">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-20">¶</a>
</div>
<p>atomic prod, analogue to a_sum. Multiply all values in a tensor</p>
</div>
<div class="content"><div class='highlight'><pre> a_prod: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">T</span>) </span>{</pre></div></div>
</li>
<li id="section-21">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-21">¶</a>
</div>
<p>actual function call; recurse if need to</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> total = <span class="hljs-number">1</span>,
len = T.length;
<span class="hljs-keyword">while</span> (len--) total *= (T[len] <span class="hljs-keyword">instanceof</span> <span class="hljs-built_in">Array</span> ?
lomath.a_prod(T[len], <span class="hljs-number">1</span>) : T[len])
<span class="hljs-keyword">return</span> total;
},</pre></div></div>
</li>
<li id="section-22">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-22">¶</a>
</div>
<p>product of all values in all arguments</p>
</div>
<div class="content"><div class='highlight'><pre> prod: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
<span class="hljs-keyword">var</span> res = <span class="hljs-number">1</span>,
len = <span class="hljs-built_in">arguments</span>.length;
<span class="hljs-keyword">while</span> (len--) res *= (<span class="hljs-built_in">arguments</span>[len] <span class="hljs-keyword">instanceof</span> <span class="hljs-built_in">Array</span> ?
lomath.a_prod(<span class="hljs-built_in">arguments</span>[len]) : <span class="hljs-built_in">arguments</span>[len])
<span class="hljs-keyword">return</span> res;
},</pre></div></div>
</li>
<li id="section-23">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-23">¶</a>
</div>
<p>atomic add: add two scalars x, y.</p>
</div>
<div class="content"><div class='highlight'><pre> a_add: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">x, y</span>) </span>{
<span class="hljs-keyword">return</span> x + y;
},</pre></div></div>
</li>
<li id="section-24">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-24">¶</a>
</div>
<p>add all tensor arguments element-wise/distributively and associatively</p>
</div>
<div class="content"><div class='highlight'><pre> add: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{</pre></div></div>
</li>
<li id="section-25">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-25">¶</a>
</div>
<p>sample call pattern: pass whole args</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">return</span> lomath.assodist(lomath.a_add, <span class="hljs-built_in">arguments</span>);
},</pre></div></div>
</li>
<li id="section-26">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-26">¶</a>
</div>
<p>atomic subtract</p>
</div>
<div class="content"><div class='highlight'><pre> a_subtract: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">x, y</span>) </span>{
<span class="hljs-keyword">return</span> x - y;
},</pre></div></div>
</li>
<li id="section-27">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-27">¶</a>
</div>
<p>subtract all tensor arguments element-wise/distributively and associatively</p>
</div>
<div class="content"><div class='highlight'><pre> subtract: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
<span class="hljs-keyword">return</span> lomath.assodist(lomath.a_subtract, <span class="hljs-built_in">arguments</span>);
},</pre></div></div>
</li>
<li id="section-28">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-28">¶</a>
</div>
<p>atomic multiply</p>
</div>
<div class="content"><div class='highlight'><pre> a_multiply: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">x, y</span>) </span>{
<span class="hljs-keyword">return</span> x * y;
},</pre></div></div>
</li>
<li id="section-29">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-29">¶</a>
</div>
<p>multiply all tensor arguments element-wise/distributively and associatively
Note: lomath is generic; is different from matrix multiplication</p>
</div>
<div class="content"><div class='highlight'><pre> multiply: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
<span class="hljs-keyword">return</span> lomath.assodist(lomath.a_multiply, <span class="hljs-built_in">arguments</span>);
},</pre></div></div>
</li>
<li id="section-30">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-30">¶</a>
</div>
<p>atomic divide</p>
</div>
<div class="content"><div class='highlight'><pre> a_divide: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">x, y</span>) </span>{
<span class="hljs-keyword">return</span> x / y;
},</pre></div></div>
</li>
<li id="section-31">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-31">¶</a>
</div>
<p>divide all tensor arguments element-wise/distributively and associatively</p>
</div>
<div class="content"><div class='highlight'><pre> divide: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
<span class="hljs-keyword">return</span> lomath.assodist(lomath.a_divide, <span class="hljs-built_in">arguments</span>);
},</pre></div></div>
</li>
<li id="section-32">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-32">¶</a>
</div>
<p>atomic log. Use base e by default</p>
</div>
<div class="content"><div class='highlight'><pre> a_log: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">x, base</span>) </span>{
<span class="hljs-keyword">return</span> base == <span class="hljs-literal">undefined</span> ? <span class="hljs-built_in">Math</span>.log(x) : <span class="hljs-built_in">Math</span>.log(x) / <span class="hljs-built_in">Math</span>.log(base);
},</pre></div></div>
</li>
<li id="section-33">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-33">¶</a>
</div>
<p>take the log of tensor T to the n element-wise</p>
</div>
<div class="content"><div class='highlight'><pre> log: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">T, base</span>) </span>{
<span class="hljs-keyword">return</span> lomath.distribute(lomath.a_log, T, base);
},</pre></div></div>
</li>
<li id="section-34">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-34">¶</a>
</div>
<p>atomic square</p>
</div>
<div class="content"><div class='highlight'><pre> a_square: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">x</span>) </span>{
<span class="hljs-keyword">return</span> x * x;
},
square: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">T</span>) </span>{
<span class="hljs-keyword">return</span> lomath.distributeSingle(lomath.a_square, T);
},</pre></div></div>
</li>
<li id="section-35">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-35">¶</a>
</div>
<p>atomic root</p>
</div>
<div class="content"><div class='highlight'><pre> a_root: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">x, base</span>) </span>{
<span class="hljs-keyword">var</span> n = base == <span class="hljs-literal">undefined</span> ? <span class="hljs-number">2</span> : base;
<span class="hljs-keyword">return</span> n % <span class="hljs-number">2</span> ?</pre></div></div>
</li>
<li id="section-36">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-36">¶</a>
</div>
<p>if odd power</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-built_in">Math</span>.sign(x) * <span class="hljs-built_in">Math</span>.pow(<span class="hljs-built_in">Math</span>.abs(x), <span class="hljs-number">1</span> / n) :
<span class="hljs-built_in">Math</span>.pow(x, <span class="hljs-number">1</span> / n);
},</pre></div></div>
</li>
<li id="section-37">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-37">¶</a>
</div>
<p>take the n-th root of tensor T element-wise</p>
</div>
<div class="content"><div class='highlight'><pre> root: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">T, n</span>) </span>{
<span class="hljs-keyword">return</span> lomath.distribute(lomath.a_root, T, n);
},</pre></div></div>
</li>
<li id="section-38">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-38">¶</a>
</div>
<p>atomic logistic</p>
</div>
<div class="content"><div class='highlight'><pre> a_logistic: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">z</span>) </span>{
<span class="hljs-keyword">return</span> <span class="hljs-number">1</span> / (<span class="hljs-number">1</span> + <span class="hljs-built_in">Math</span>.exp(-z))
},
logistic: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">T</span>) </span>{
<span class="hljs-keyword">return</span> lomath.distributeSingle(lomath.a_logistic, T);
},</pre></div></div>
</li>
<li id="section-39">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-39">¶</a>
</div>
<p>//////////////////
Basic checkers //
//////////////////
check if x is in range set by left, right</p>
</div>
<div class="content"><div class='highlight'><pre> inRange: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">left, right, x</span>) </span>{
<span class="hljs-keyword">return</span> left - <span class="hljs-number">1</span> < x && x < right + <span class="hljs-number">1</span>;
},</pre></div></div>
</li>
<li id="section-40">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-40">¶</a>
</div>
<p>check if x is an integer</p>
</div>
<div class="content"><div class='highlight'><pre> isInteger: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">x</span>) </span>{
<span class="hljs-keyword">return</span> x == <span class="hljs-built_in">Math</span>.floor(x);
},</pre></div></div>
</li>
<li id="section-41">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-41">¶</a>
</div>
<p>check if x is a double</p>
</div>
<div class="content"><div class='highlight'><pre> isDouble: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">x</span>) </span>{
<span class="hljs-keyword">return</span> x != <span class="hljs-built_in">Math</span>.floor(x);
},</pre></div></div>
</li>
<li id="section-42">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-42">¶</a>
</div>
<p>check if x is positive</p>
</div>
<div class="content"><div class='highlight'><pre> isPositive: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">x</span>) </span>{
<span class="hljs-keyword">return</span> x > <span class="hljs-number">0</span>;
},</pre></div></div>
</li>
<li id="section-43">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-43">¶</a>
</div>
<p>check if x less than or eq to 0</p>
</div>
<div class="content"><div class='highlight'><pre> nonPositive: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">x</span>) </span>{
<span class="hljs-keyword">return</span> !(x > <span class="hljs-number">0</span>);
},</pre></div></div>
</li>
<li id="section-44">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-44">¶</a>
</div>
<p>check if x is negative</p>
</div>
<div class="content"><div class='highlight'><pre> isNegative: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">x</span>) </span>{
<span class="hljs-keyword">return</span> x < <span class="hljs-number">0</span>;
},</pre></div></div>
</li>
<li id="section-45">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-45">¶</a>
</div>
<p>check if x greater than or eq to 0</p>
</div>
<div class="content"><div class='highlight'><pre> nonNegative: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">x</span>) </span>{
<span class="hljs-keyword">return</span> !(x < <span class="hljs-number">0</span>);
},
isZero: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">x</span>) </span>{
<span class="hljs-keyword">return</span> x == <span class="hljs-number">0</span>;
},
nonZero: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">x</span>) </span>{
<span class="hljs-keyword">return</span> x != <span class="hljs-number">0</span>;
},
parity: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">x</span>) </span>{
<span class="hljs-keyword">return</span> x % <span class="hljs-number">2</span> ? <span class="hljs-number">-1</span> : <span class="hljs-number">1</span>;
},</pre></div></div>
</li>
<li id="section-46">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-46">¶</a>
</div>
<p>check if all tensor entries are of the same sign, with the specified sign function</p>
</div>
<div class="content"><div class='highlight'><pre> sameSig: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">T, sigFn</span>) </span>{
<span class="hljs-keyword">return</span> <span class="hljs-built_in">Boolean</span>(lomath.prod(lomath.distributeSingle(sigFn, T)));
},</pre></div></div>
</li>
<li id="section-47">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-47">¶</a>
</div>
<p>check if all tensor entries are of the same sign, with the specified sign function</p>
</div>
<div class="content"><div class='highlight'><pre> deepEqual: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">T, S</span>) </span>{
<span class="hljs-keyword">if</span> (T.length != S.length) <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
<span class="hljs-keyword">var</span> Left = T,
Right = S;
<span class="hljs-keyword">if</span> (!lomath.isFlat(T)) {
Left = _.flattenDeep(T);
Right = _.flattenDeep(S);
};
<span class="hljs-keyword">var</span> Llen = Left.length,
Rlen = Right.length;
<span class="hljs-keyword">while</span> (Llen--) {
<span class="hljs-keyword">if</span> (Left[Llen] != Right[Llen]) <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
}
<span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
},</pre></div></div>
</li>
<li id="section-48">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-48">¶</a>
</div>
<p>////////////////////////////////////////
Unary functions from JS Math object, //
////////////////////////////////////////
wrapped to function with generic tensor</p>
</div>
<div class="content"><div class='highlight'><pre> abs: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">T</span>) </span>{
<span class="hljs-keyword">return</span> lomath.distributeSingle(<span class="hljs-built_in">Math</span>.abs, T);
},
acos: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">T</span>) </span>{
<span class="hljs-keyword">return</span> lomath.distributeSingle(<span class="hljs-built_in">Math</span>.acos, T);
},
acosh: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">T</span>) </span>{
<span class="hljs-keyword">return</span> lomath.distributeSingle(<span class="hljs-built_in">Math</span>.acosh, T);
},
asin: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">T</span>) </span>{
<span class="hljs-keyword">return</span> lomath.distributeSingle(<span class="hljs-built_in">Math</span>.asin, T);
},
asinh: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">T</span>) </span>{
<span class="hljs-keyword">return</span> lomath.distributeSingle(<span class="hljs-built_in">Math</span>.asinh, T);
},
atan: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">T</span>) </span>{
<span class="hljs-keyword">return</span> lomath.distributeSingle(<span class="hljs-built_in">Math</span>.atan, T);
},
atanh: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">T</span>) </span>{
<span class="hljs-keyword">return</span> lomath.distributeSingle(<span class="hljs-built_in">Math</span>.atanh, T);
},
ceil: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">T</span>) </span>{
<span class="hljs-keyword">return</span> lomath.distributeSingle(<span class="hljs-built_in">Math</span>.ceil, T);
},
cos: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">T</span>) </span>{
<span class="hljs-keyword">return</span> lomath.distributeSingle(<span class="hljs-built_in">Math</span>.cos, T);
},
cosh: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">T</span>) </span>{
<span class="hljs-keyword">return</span> lomath.distributeSingle(<span class="hljs-built_in">Math</span>.cosh, T);
},
exp: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">T</span>) </span>{
<span class="hljs-keyword">return</span> lomath.distributeSingle(<span class="hljs-built_in">Math</span>.exp, T);
},
floor: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">T</span>) </span>{
<span class="hljs-keyword">return</span> lomath.distributeSingle(<span class="hljs-built_in">Math</span>.floor, T);
},
log10: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">T</span>) </span>{
<span class="hljs-keyword">return</span> lomath.distributeSingle(<span class="hljs-built_in">Math</span>.log10, T);
},
log1p: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">T</span>) </span>{
<span class="hljs-keyword">return</span> lomath.distributeSingle(<span class="hljs-built_in">Math</span>.log1p, T);
},
log2: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">T</span>) </span>{
<span class="hljs-keyword">return</span> lomath.distributeSingle(<span class="hljs-built_in">Math</span>.log2, T);
},
round: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">T</span>) </span>{
<span class="hljs-keyword">return</span> lomath.distributeSingle(<span class="hljs-built_in">Math</span>.round, T);
},
pow: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">T, n</span>) </span>{
<span class="hljs-keyword">return</span> lomath.distribute(<span class="hljs-built_in">Math</span>.pow, T, n);
},
sign: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">T</span>) </span>{
<span class="hljs-keyword">return</span> lomath.distributeSingle(<span class="hljs-built_in">Math</span>.sign, T);
},
sin: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">T</span>) </span>{
<span class="hljs-keyword">return</span> lomath.distributeSingle(<span class="hljs-built_in">Math</span>.sin, T);
},
sinh: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">T</span>) </span>{
<span class="hljs-keyword">return</span> lomath.distributeSingle(<span class="hljs-built_in">Math</span>.sinh, T);
},
sqrt: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">T</span>) </span>{
<span class="hljs-keyword">return</span> lomath.distributeSingle(<span class="hljs-built_in">Math</span>.sqrt, T);
},
tan: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">T</span>) </span>{
<span class="hljs-keyword">return</span> lomath.distributeSingle(<span class="hljs-built_in">Math</span>.tan, T);
},
tanh: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">T</span>) </span>{
<span class="hljs-keyword">return</span> lomath.distributeSingle(<span class="hljs-built_in">Math</span>.tanh, T);
},
trunc: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">T</span>) </span>{
<span class="hljs-keyword">return</span> lomath.distributeSingle(<span class="hljs-built_in">Math</span>.trunc, T);
},</pre></div></div>
</li>
<li id="section-49">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-49">¶</a>
</div>
<p>///////////////////
Regex functions //
///////////////////
return a function that matches regex,
e.g. matchRegex(/red/)(‘red Apple’) returns true</p>
</div>
<div class="content"><div class='highlight'><pre> reMatch: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">regex</span>) </span>{
<span class="hljs-keyword">return</span> <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">str</span>) </span>{
<span class="hljs-keyword">if</span> (str != <span class="hljs-literal">undefined</span>)
<span class="hljs-keyword">return</span> str.search(regex) != <span class="hljs-number">-1</span>;
}
},</pre></div></div>
</li>
<li id="section-50">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-50">¶</a>
</div>
<p>negation of reMatch</p>
</div>
<div class="content"><div class='highlight'><pre> reNotMatch: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">regex</span>) </span>{
<span class="hljs-keyword">return</span> <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">str</span>) </span>{
<span class="hljs-keyword">if</span> (str != <span class="hljs-literal">undefined</span>)
<span class="hljs-keyword">return</span> str.search(regex) == <span class="hljs-number">-1</span>;
}
},</pre></div></div>
</li>
<li id="section-51">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-51">¶</a>
</div>
<p>return the string matched by regex</p>
</div>
<div class="content"><div class='highlight'><pre> reGet: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">regex</span>) </span>{
<span class="hljs-keyword">return</span> <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">str</span>) </span>{
<span class="hljs-keyword">if</span> (str != <span class="hljs-literal">undefined</span>) {
<span class="hljs-keyword">var</span> matched = str.match(regex);
<span class="hljs-keyword">return</span> matched == <span class="hljs-literal">null</span> ? <span class="hljs-literal">null</span> : matched[<span class="hljs-number">0</span>];
}
}
},</pre></div></div>
</li>
<li id="section-52">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-52">¶</a>
</div>
<p>wrap a regex into string for regex set operation</p>
</div>
<div class="content"><div class='highlight'><pre> reWrap: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">reg</span>) </span>{
<span class="hljs-keyword">return</span> <span class="hljs-string">'(?:'</span> + <span class="hljs-built_in">String</span>(reg).replace(<span class="hljs-regexp">/\//g</span>, <span class="hljs-string">''</span>) + <span class="hljs-string">')'</span>
},</pre></div></div>
</li>
<li id="section-53">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-53">¶</a>
</div>
<p>return a single regex as the “AND” of all arg regex’s</p>
</div>
<div class="content"><div class='highlight'><pre> reAnd: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
<span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">RegExp</span>(_.map(_.toArray(<span class="hljs-built_in">arguments</span>), lomath.reWrap).join(<span class="hljs-string">''</span>));
},</pre></div></div>
</li>
<li id="section-54">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-54">¶</a>
</div>
<p>return a function that matches all(AND) of the regexs</p>
</div>
<div class="content"><div class='highlight'><pre> reAndMatch: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
<span class="hljs-keyword">return</span> lomath.reMatch(lomath.reAnd.apply(<span class="hljs-literal">null</span>, <span class="hljs-built_in">arguments</span>));
},</pre></div></div>
</li>
<li id="section-55">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-55">¶</a>
</div>
<p>return a single regex as the “OR” of all arg regex’s</p>
</div>