Skip to content

Commit

Permalink
added optimized code for mergePoint, applyPoint
Browse files Browse the repository at this point in the history
  • Loading branch information
mikolalysenko committed Feb 4, 2013
1 parent d0431c9 commit e8e09a0
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 79 deletions.
34 changes: 18 additions & 16 deletions README.md
Expand Up @@ -15,28 +15,30 @@ Or else just include rle-all which has it as a subcomponent:
Usage
=====

`apply(volume, stencil, update_func)`
------------------------------
This applies a function to the volume pointwise. Useful for implementing cellular automata and other local differential equations.

* `volume`: The volume we are applying the stencil operator to.
* `stencil`: The neighborhood stencil that we are using on the volume.
* `update_func(phases, distances, retval)`: A function that takes three arguments:
`merge(volumes, stencil, merge_func)`
----------------------------
This merges a collection of volumes together. This acts like a generalized boolean operation amongst the volumes. It is a very flexible, and very general function

* `phases`: An array of length `stencil.length` of material phases.
* `distances`: An array of length `stencil.length` of distances to the material boundary
* `volumes`: An array of volumes
* `stencil`: A stencil
* `merge_func(phases, distances, retval)`: A function that takes 3 arguments:
* `phases`: An array of length `volumes.length * stencil.length` of material phases.
* `distances`: An array of length `volumes.length * stencil.length` of distances to the material boundary
* `retval`: A length two array for the return value of the function. The first item is the new phase and the second item is the distance to the phase boundary.

Returns: A new run length encoded volume, which is the result of applying `update_func` at every point in the volume.
Returns: A new volume which is the result of calling merge_func at every point in the volumes.

`merge(volumes, merge_func)`
----------------------------
This merges a collection of volumes together. This acts like a generalized boolean operation amongst the volumes.
`mergePoint(volumes, merge_func)`
---------------------------------
This is an optimized version of merge where the stencil is a single point.

* `volumes`: An array of volumes:
* `merge_func(phases, distances, retval)`
`apply(volume, stencil, merge_func)`
------------------------------
This is an optimized version of `merge` that takes only a single volume as input, instead of an array. Useful for implementing cellular automata and other local differential equations.

Returns: The result of calling merge_func at every point in the volumes.
`applyPoint(volume, merge_func)`
---------------------------------
Optimized version `apply` that assumes `stencil` is a single point.


Credits
Expand Down
78 changes: 76 additions & 2 deletions index.js
@@ -1,2 +1,76 @@
exports.apply = require("./lib/apply.js");
exports.merge = require("./lib/merge.js");
"use strict"; "use restrict";

var core = require("rle-core");
var removeDuplicates = require("rle-repair").removeDuplicates;

//Most general function: Performs a k-way merge on a collection of volumes
exports.merge = function(volumes, stencil, merge_func) {
var result = new core.DynamicVolume()
, iter = core.beginMulti(volumes, stencil)
, ptrs = iter.ptrs
, stencil_len = iter.stencil_len
, coord = iter.coord
, phases = new Int32Array(ptrs.length)
, distances = new Float64Array(ptrs.length)
, retval = [0, 1.0];
while(iter.hasNext()) {
for(var i=0, idx=0; i<volumes.length; ++i) {
var vphases = volumes[i].phases
, vdistances = volumes[i].distances;
for(var j=0; j<stencil_len; ++j, ++idx) {
var p = ptrs[idx];
phases[idx] = vphases[p];
distances[idx] = vdistances[p];
}
}
merge_func(phases, distances, retval);
result.push(coord[0], coord[1], coord[2], retval[1], retval[0]);
iter.next();
}
return removeDuplicates(result);
}

//Optimization: merge for a trivial stencil
exports.mergePoint = function(volumes, merge_func) {
return exports.merge(volumes, new Int32Array(3), merge_func);
}

//Optimization: merge for a sungle volume
exports.apply = function(volume, stencil, func) {
var vdistances = volume.distances
, vphases = volume.phases
, stencil_len = (stencil.length / 3) | 0
, distances = new Float64Array(stencil_len)
, phases = new Int32Array(stencil_len)
, nvolume = new core.DynamicVolume()
, retval = [ 0, 1.0 ]
, iter = core.beginStencil(volume, stencil)
, ptrs = iter.ptrs
, c = iter.coord;
nvolume.pop()
while(iter.hasNext()) {
for(var i=0; i<stencil_len; ++i) {
var p = ptrs[i];
distances[i] = vdistances[p];
phases[i] = vphases[p];
}
func(phases, distances, retval);
nvolume.push(c[0], c[1], c[2], retval[1], retval[0]);
iter.next();
}
return removeDuplicates(nvolume);
}

//Optimization merge for a pointwise function
exports.applyPoint = function(volume, func) {
var nvolume = volume.clone()
, nruns = volume.length()
, retval = [0,1.0]
for(var i=0; i<nruns; ++i) {
func(nvolume.phases[i], nvolume.distances[i], retval)
nvolume.phases[i] = retval[0];
nvolume.distances[i] = retval[1];
}
return removeDuplicates(nvolume);
}

30 changes: 0 additions & 30 deletions lib/apply.js

This file was deleted.

31 changes: 0 additions & 31 deletions lib/merge.js

This file was deleted.

0 comments on commit e8e09a0

Please sign in to comment.