• Stars
    star
    118
  • Rank 299,923 (Top 6 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created over 11 years ago
  • Updated over 4 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Component-wise operations for ndarrays

cwise

This library can be used to generate cache efficient map/reduce operations for ndarrays.

build status

Examples

For brevity, we will assume the following precedes each example:

//Import libraries
var cwise = require("cwise")
  , ndarray = require("ndarray")

Adding two arrays

The array equivalent of +=:

//Create operation
var addeq = cwise({
    args: ["array", "array"],
    body: function(a, b) {
      a += b
    }
  })

//Create two 2D arrays
var X = ndarray(new Float32Array(128*128), [128,128])
var Y = ndarray(new Float32Array(128*128), [128,128])

//Add them together
addeq(X, Y)

Formally, you can think of addeq(X,Y) as being something like the following for-loop, except optimized with respect to the dimension and order of X and Y:

for(var i=0; i<X.shape[0]; ++i) {
  for(var j=0; j<X.shape[1]; ++j) {
    X.set(i,j, X.get(i,j) + Y.get(i,j))
  }
}

Multiply an array with a scalar

var muls = cwise({
  args: ["array", "scalar"],
  body: function(a, s) {
    a *= s
  }
})

//Example usage:
muls(array, 2.0)

Initialize an array with a grid with the first index

var mgrid = cwise({
  args: ["index", "array"],
  body: function(i, a) {
    a = i[0]
  }
})

//Example usage:
var X = mgrid(ndarray(new Float32Array(128)))

Compute 2D vector norms using blocks

var norm2D = cwise({
  args: ["array", {blockIndices: -1}],
  body: function(o, i) {
    o = Math.sqrt(i[0]*i[0] + i[1]*i[1])
  }
})

//Example usage:
var o = ndarray([0, 0, 0], [3])
norm2D(o, ndarray([1, 2, 3, 4, 5, 6], [3,2]))
// o.data == [ 2.23606797749979, 5, 7.810249675906654 ]

Note that in the above, i is not an actual Array, the indexing notation is just syntactic sugar.

Apply a stencil to an array

var laplacian = cwise({
  args:["array", "array", {offset:[0,1], array:1}, {offset:[0,-1], array:1}, {offset:[1,0], array:1}, {offset:[-1,0], array:1}],
  body:function(a, c, n, s, e, w) {
    a = 0.25 * (n + s + e + w) - c
  }
})

laplacian(next, prev)

Compute the sum of all the elements in an array

var sum = cwise({
  args: ["array"],
  pre: function() {
    this.sum = 0
  },
  body: function(a) {
    this.sum += a
  },
  post: function() {
    return this.sum
  }
})
  
//Usage:
s = sum(array)

Note that variables stored in this are common to all three code blocks. Also note that one should not treat this as an actual object (for example, one should not attempt to return this).

Check if any element is set

var any = cwise({
  args: ["array"],
  body: function(a) {
    if(a) {
      return true
    }
  },
  post: function() {
    return false
  }
})

//Usage
if(any(array)) {
  // ...
}

Compute the index of the maximum element of an array:

var argmin = cwise({
  args: ["index", "array"],
  pre: function(index) {
    this.min_v = Number.POSITIVE_INFINITY
    this.min_index = index.slice(0)
  },
  body: function(index, a) {
    if(a < this.min_v) {
      this.min_v = a
      for(var i=0; i<index.length; ++i) {
        this.min_index[i] = index[i]
      }
    }
  },
  post: function() {
    return this.min_index
  }
})

//Usage:
argmin(X)

Install

Install using npm:

npm install cwise

API

require("cwise")(user_args)

To use the library, you pass it an object with the following fields:

  • args: (Required) An array describing the type of the arguments passed to the body. These may be one of the following:
    • "array": An ndarray-type argument
    • "scalar": A globally broadcasted scalar argument
    • "index": (Hidden) An array representing the current index of the element being processed. Initially [0,0,...] in the pre block and set to some undefined value in the post block.
    • "shape": (Hidden) An array representing the shape of the arrays being processed
    • An object representing a "blocked" array (for example a colour image, an array of matrices, etc.):
      • blockIndices The number of indices (from the front of the array shape) to expose in the body (rather than iterating over them). Negative integers take indices from the back of the array shape.
    • (Hidden) An object containing two properties representing an offset pointer from an array argument. Note that cwise does not implement any boundary conditions.
      • offset An array representing the relative offset of the object
      • array The index of an array parameter
  • pre: A function to be executed before starting the loop
  • body: (Required) A function that gets applied to each element of the input arrays
  • post: Executed when loop completes
  • printCode: If this flag is set, then log all generated code
  • blockSize: The size of a block (default 32)
  • funcName: The name to give to the generated procedure for debugging/profiling purposes. (Default is body.name||"cwise")

The result is a procedure that you can call which executes these methods along the following lines:

function(a0, a1, ...) {
  pre()
  for(var i=0; i<a0.shape[0]; ++i) {
    for(var j=0; j<a0.shape[1]; ++j) {
      ...
      
          body(a0[i,j,...], a1[i,j,...], ... )
    }
  }
  post()
}

Notes

  • To pass variables between the pre/body/post, use this.*
  • The order in which variables get visited depends on the stride ordering if the input arrays. In general it is not safe to assume that elements get visited (co)lexicographically.
  • If no return statement is specified, the first ndarray argument is returned
  • All input arrays must have the same shape. If not, then the library will throw an error

As a browserify transform

If bundle size is an issue for you, it is possible to use cwise as a browserify transform, thus avoiding the potentially large parser dependencies. To do this, add the following lines to your package.json:

//Contents of package.json
{
    // ...

    "browserify": {
      "transform": [ "cwise" ]
    }

    // ...
}

Then when you use the module with browserify, only the cwise-compile submodule will get loaded into your script instead of all of esprima. Note that this step is optional and the library will still work in the browser even if you don't use a transform.

FAQ

Is it fast?

Yes

How does it work?

You can think of cwise as a type of macro language on top of JavaScript. Internally, cwise uses node-falafel to parse the functions you give it and sanitize their arguments. At run time, code for each array operation is generated lazily depending on the ordering and stride of the input arrays so that you get optimal cache performance. These compiled functions are then memoized for future calls to the same function. As a result, you should reuse array operations as much as possible to avoid wasting time and memory regenerating common functions.

License

(c) 2013 Mikola Lysenko. MIT License

More Repositories

1

ndarray

📈 Multidimensional arrays for JavaScript
JavaScript
1,165
star
2

get-pixels

Reads an image into an ndarray
JavaScript
540
star
3

fourier-transform

Minimalistic and efficient FFT implementation
JavaScript
167
star
4

save-pixels

Saves an ndarray as an image
JavaScript
89
star
5

ndarray-ops

ndarray operations
JavaScript
66
star
6

window-function

Collection of window functions
JavaScript
58
star
7

periodic-function

List of periodic functions normalized to 0..1 range
JavaScript
55
star
8

ndarray-fft

FFT for ndarrays
JavaScript
48
star
9

distance-transform

Distance transforms for ndarrays
JavaScript
36
star
10

almost-equal

Test if two floats are nearly equal
JavaScript
28
star
11

ndarray-resample

Downsample by a factor of two using sinc interpolation
JavaScript
26
star
12

newton-raphson-method

Find zeros of a function using the Newton-Raphson method
JavaScript
25
star
13

ode-rk4

Integrate a system of ODEs using the Fourth Order Runge-Kutta (RK-4) method
JavaScript
24
star
14

durand-kerner

Finds roots of polynomials by Weierstrauss' method
JavaScript
24
star
15

ode45-cash-karp

Integrate a system of Ordinary Differential Equations using the Fifth Order Adaptive Cash-Karp method
JavaScript
24
star
16

integrate-adaptive-simpson

Compute a definite integral using Simpson's Rule with adaptive quadrature
JavaScript
23
star
17

ndarray-show

display an ndarray
JavaScript
22
star
18

ndarray-fill

Fills an ndarray with a function
JavaScript
21
star
19

splines

Convenient and efficient B-splines.
JavaScript
20
star
20

nrrd-js

Handling of NRRD files in Javascript.
JavaScript
20
star
21

ndarray-linear-solve

solve a linear system with LU decomposition
JavaScript
19
star
22

nextafter

JS implementation of C stdlib nextafter
JavaScript
18
star
23

poly-roots

Find all roots of a polynomial using the Jenkins-Traub method
JavaScript
18
star
24

scijs-ndarray-for-matlab-users

Common scijs/ndarray operations for people familar with MATLAB (or at least not familiar with scijs)
18
star
25

ndarray-gemm

General matrix multiplication for ndarrays
JavaScript
18
star
26

ndarray-proxy

Turn functions into ndarrays
JavaScript
16
star
27

ndarray-linear-interpolate

Multilinear interpolation for ndarrays
JavaScript
16
star
28

cholesky-solve

[WIP] This module solves sparse symmetric positive definite linear systems by using the Cholesky decomposition
JavaScript
16
star
29

minimize-golden-section-1d

Minimize a function of a single variable using golden section search
JavaScript
14
star
30

ndarray-warp

Warps an ndarray
JavaScript
14
star
31

phase-align

Aligns a pair of ndarrays up to translation
JavaScript
14
star
32

zeros

Initialize an ndarray with zeros
JavaScript
13
star
33

ode-euler

Integrate a system of ODEs using the Euler method
JavaScript
13
star
34

gauss-random

Sample standard normal distribution
JavaScript
12
star
35

isndarray

Returns boolean whether the argument is a ndarray
JavaScript
11
star
36

ndarray-convolve

Convolutions and cross correlations for ndarrays
JavaScript
11
star
37

ndarray-blas-level1

BLAS Level 1 operations for ndarrays
JavaScript
11
star
38

ndarray-scratch

Pooled memory for ndarrays
JavaScript
11
star
39

ndarray-crout-decomposition

LU decomposition using the crout algorithm
JavaScript
11
star
40

contributing

Contribution guide lines
10
star
41

nifti-js

NIfTI support for Javascript
JavaScript
10
star
42

ndarray-sort

Sorts ndarrays in place
JavaScript
10
star
43

ndarray-pack

Packs an array-of-arrays into an ndarray
JavaScript
10
star
44

spiral-2d

Math for spirals
JavaScript
10
star
45

ndarray-imshow

Displays an ndarray as an image
JavaScript
10
star
46

ndarray-gaussian-filter

Gaussian blur for ndarrays
JavaScript
10
star
47

image-rotate

Rotates a 2D ndarray
JavaScript
10
star
48

ndarray-householder-qr

Householder triangularization for QR Factorization of ndarrays
JavaScript
10
star
49

ndarray-gram-schmidt-qr

Modified Gram-Schmidt Algorithm for QR Factorization of ndarrays
JavaScript
10
star
50

logo

logo for scijs
9
star
51

sphere-random

Sample a random point on a hypersphere
JavaScript
9
star
52

complex-deriv-fornberg

Compute the derivative of a complex analytic function using the method of Fornberg
JavaScript
9
star
53

tensor-decomposition

Higher order tensor decomposition
JavaScript
9
star
54

ndarray-bit

ndarrays of bits
JavaScript
9
star
55

baboon-image

The baboon test image
JavaScript
9
star
56

ndarray-blas-level2

BLAS Level 2 operations for ndarrays
JavaScript
9
star
57

ndarray-blas-level1-complex

BLAS Level 1 operations for complex ndarrays
JavaScript
9
star
58

pyramids

Various kinds of (image) pyramids for ndarrays of arbitrary dimension.
JavaScript
9
star
59

iota-array

Generates arrays of sequential integers
JavaScript
8
star
60

cwise-compiler

Just the compiler from cwise. No esprima dependencies
JavaScript
8
star
61

ndarray-select

Quick select algorithm for ndarrays
JavaScript
8
star
62

gauss-quadrature

Gauss-Legendre quadrature rules
JavaScript
8
star
63

ndarray-tests

Test numerical properties of ndarrays
JavaScript
8
star
64

complex-sqrt

Floating point complex square root
JavaScript
8
star
65

complex-division

Floating point complex division
JavaScript
8
star
66

poly-mult-fft

Multiplies polynomials together using an FFT
JavaScript
8
star
67

qr-solve

[WIP] This module solves sparse linear systems by using the QR-decomposition
JavaScript
8
star
68

finite-difference-stencil

Compute the coefficients of explicit or implicit finite difference schemes
JavaScript
8
star
69

gsl-const

physical constants for JS via GNU Scientific Library
JavaScript
8
star
70

cwise-parser

Parser for cwise
JavaScript
8
star
71

deriv

numerical derivatives of one-variable functions
JavaScript
7
star
72

ndarray-linspace

Fill an ndarray with equally spaced values
JavaScript
7
star
73

ndarray-distance

Lp distance between ndarrays
JavaScript
7
star
74

random-permutation

Generates a random permutation
JavaScript
7
star
75

ndarray-lup-factorization

LU factorization with pivoting for ndarrays
JavaScript
7
star
76

ndarray-translate-fft

Translate ndarrays with sinc interpolation
JavaScript
7
star
77

permutation-rank

Ranks and unranks permutations
JavaScript
7
star
78

ndarray-extract-contour

Generic contour/isosurface extraction code generator for ndarrays
JavaScript
7
star
79

ndarray-lup-solve

Solve ndarray Ax=b via LU factorization with pivoting
JavaScript
7
star
80

ndarray-blas-trsv

BLAS Level 2 TRSV (triangular solve) for ndarrays
JavaScript
7
star
81

ndarray-translate

Translate/shift ndarrays
JavaScript
7
star
82

ndarray-ldl-factorization

LDL Factorization for ndarrays
JavaScript
7
star
83

modified-newton-raphson

Find zeros a function using the Modified Newton-Raphson method
JavaScript
7
star
84

ndarray-determinant

Computes the determinant of an ndarray
JavaScript
7
star
85

richardson-extrapolation

Use Richardson Extrapolation sequence acceleration to compute the order of convergence and exact value of a sequence
JavaScript
7
star
86

ndarray-cholesky-factorization

Cholesky Factorization of ndarrays
JavaScript
6
star
87

dirichlet

Dirichlet/aliased sinc function
JavaScript
6
star
88

ndarray-moments

Statistical moments of ndarrays
JavaScript
6
star
89

integrate-simpson

Integrate a function of one variable using Simpson's Rule
JavaScript
6
star
90

quadratic-roots

Compute the real roots of a quadratic equation in a numerically stable manner
JavaScript
6
star
91

ndarray-vandermonde

Construct Vandermonde matrices with ndarrays
JavaScript
6
star
92

scijs.github.io

Web site for SciJS
6
star
93

ndarray-blas-gemv

BLAS Level 2 GEMV (Matrix-Vector multiply) for ndarrays
JavaScript
6
star
94

ndarray-function-basis

onstruct an ndarray basis given a sequence of points and functions
JavaScript
6
star
95

ndarray-band

Create a view of a band of an ndarray
JavaScript
5
star
96

ndarray-string

Creates an ndarray view of a string
JavaScript
5
star
97

ndarray-blas-trsv-complex

BLAS Level 2 TRSV (triangular solve) for complex ndarrays
JavaScript
5
star
98

ndarray-complex

Component-wise complex operations on ndarrays
JavaScript
5
star
99

companion-roots

Computes roots of polynomials by solving an eigenvalue problem
JavaScript
5
star
100

ndarray-normalize

Normalizes an ndarray to zero mean and unit variance
JavaScript
5
star