Pass arrays from JS by reference for WASM to edit? - assemblyscript

What's the best way to pass and return arrays of floats in AssemblyScript?
Can I pass an array form JS (by reference) for WASM to edit?
export function nBodyForces(data: f64[], result: f64[]): void {}
Below is what I have now. Ignore the implementation details, and it's returning 2000, then incrementing it to 8000ish.
What's the best way to return an array of new values?
export function nBodyForces(data: f64[]): f64[] {
// Each body has x,y,z,m passed in.
if (data.length % bodySize !== 0) return new Array<f64>(10);
const numBodies: i32 = data.length / bodySize;
// return a 3-force x,y,z vector for each body
let ret: f64[] = new Array<f64>(numBodies * forceSize);
/**
* Calculate the 3-vector each unique pair of bodies applies to each other.
*
* 0 1 2 3 4 5
* 0 x x x x x
* 1 x x x x
* 2 x x x
* 3 x x
* 4 x
* 5
*
* Sum those forces together into an array of 3-vector x,y,z forces
*/
// For all bodies:
for (let i: i32 = 0; i < numBodies; i++) {
// Given body i: pair with every body[j] where j > i
for (let j: i32 = i + 1; i < numBodies; j++) {
// Calculate the force the bodies apply to one another
const bI: i32 = i * 4
const bJ: i32 = j * 4
let f: f64[] = twoBodyForces(
// b0
data[bI], data[bI+1], data[bI+2], data[bI+3], // x,y,z,m
// b1
data[bJ], data[bJ+1], data[bJ+2], data[bJ+3], // x,y,z,m
);
// Add this pair's force on one another to their total forces applied x,y,z
// body0
ret[bI] = ret[bI] + f[0];
ret[bI+1] = ret[bI+1] + f[1];
ret[bI+2] = ret[bI+2] + f[2];
// body1
ret[bJ] = ret[bJ] + f[0];
ret[bJ+1] = ret[bJ+1] + f[1];
ret[bJ+2] = ret[bJ+2] + f[2];
}
}
// For each body, return the summ of forces all other bodies applied to it.
return ret;
}

For faster interop with JS I recommend use typed arrays if this possible
export const FLOAT64ARRAY_ID = idof<Float64Array>();
export function nBodyForces(data: Float64Array): Float64Array { ... }
And later on JavaScript side:
const loader = require("assemblyscript/lib/loader");
const imports = {};
const wasm = await loader.instantiateStreaming(fetch("optimized.wasm"), imports);
const dataArray = [... your data ...]
const dataRef = wasm.__retain(wasm.__allocArray(wasm.FLOAT64ARRAY_ID, dataArray));
const resultRef = wasm.nBodyForces(dataRef);
const resultArray = wasm.__getFloat64Array(resultRef);
// release ARC resources
wasm.__release(dataRef);
wasm.__release(resultRef);
console.log("result: " + resultArray);

Related

About SBC function rstan::sbc

Here I use the notations from the following example codes of SBC.
I have two questions about rstan:sbc.
Is it possible to extract the samples y described in y = binomial_rng(N, pi_); in the transformed data block ?
Is it possible to plot the rank statistics of user specified parameters only?.
If multiple parameter such as;
parameters {
real<lower = 0, upper = 1> pi;
real<lower = 0, upper = 1> ppi;
real<lower = 0, upper = 1> pppi;
}
then I want to plot the rank statistics specified parameter only.
E.g., the following manner
plot(output, pars =c("pi","ppi"))
where output is an return value of rstan::sbc.
Example of SBC
data {
int<lower = 1> N;
real<lower = 0> a;
real<lower = 0> b;
}
transformed data { // these adhere to the conventions above
real pi_ = beta_rng(a, b);
int y = binomial_rng(N, pi_);
}
parameters {
real<lower = 0, upper = 1> pi;
}
model {
target += beta_lpdf(pi | a, b);
target += binomial_lpmf(y | N, pi);
}
generated quantities { // these adhere to the conventions above
int y_ = y;
vector[1] pars_;
int ranks_[1] = {pi > pi_};
vector[N] log_lik;
pars_[1] = pi_;
for (n in 1:y) log_lik[n] = bernoulli_lpmf(1 | pi);
for (n in (y + 1):N) log_lik[n] = bernoulli_lpmf(0 | pi);
}
Edit for comments
Let output be a return value of rstan::sbc, then
output$Y is the following:
:
:
:
[[496]]
named numeric(0)
[[497]]
named numeric(0)
[[498]]
named numeric(0)
[[499]]
named numeric(0)
[[500]]
named numeric(0)
Edit for comments 2
Let stanmodel be an object of class stanmodel for the following .stan file. Then the following object output$Y is not functional.
output <- rstan::sbc(stanmodel,
data = list(
ww=-0.81,www =0.001,
mm=0.65,mmm=0.001,
vv=5.31,vvv=0.001,
zz= 1.55,zzz=0.001,
NL = 259, NI = 57,C=3,c=3:1,N=3
), M = 500, refresh = 0)
Stan file
data{ // SBC
//This is not prior truth data, but somedata to run
int <lower=0>N; //This is exactly same as C
int <lower=0>NL; //Number of Binomial trials
int <lower=0>NI; //This is redandunt
int <lower=0>C; // Number of Confidence level
int <lower=0>c[N]; //Each component means confidence level
//Prior which shold be specified
real www;
real mmm;
real vvv;
real zzz;
real zz;
real ww;
real vv;
real mm;
}
transformed data {
int h[C];
int f[C];
real w_ ;
real <lower=0>dz_[C-1] ;
real m_;
real <lower =0> v_;
real <lower=0,upper=1>p_[C];
real <lower=0>l_[C];
real <lower=0>dl_[C];
real z_[C];
real a_;
real <lower=0>b_;
w_ = normal_rng (ww,www);
for(cd in 1:C-1) dz_[cd] = normal_rng (zz,zzz);
m_ = normal_rng (mm,mmm);
v_ = normal_rng (vv,vvv);
a_=m_/v_;
b_=1/v_;
for(cd in 1 : C-1) { z_[1]=w_;
z_[cd+1] =z_[cd] +dz_[cd];
}
for(cd in 1 : C) { if (cd==C) {
p_[cd] = 1 - Phi((z_[cd] - m_)/v_);
}else{
p_[cd] = Phi((z_[cd+1] - m_)/v_)- Phi( (z_[cd] -m_)/v_);
}
}
for(cd in 1 : C) {l_[cd] = (-1)*log(Phi(z_[cd])); }
for(cd in 1:C){
if (cd==C) {dl_[cd]=fabs(l_[cd]-0);
}else{
dl_[cd]=fabs(l_[cd]-l_[cd+1]);
}
}
for(n in 1:N) {
h[n] = binomial_rng(NL, p_[c[n]]);
// fff[n] ~ poisson( l[c[n]]*NL);//Non-Chakraborty's model
f[n] = poisson_rng (dl_[c[n]]*NI);//Chakraborty's model //<-------very very very coution, not n but c[n] 2019 Jun 21
// fff[n] ~ poisson( l[c[n]]*NI);//Non-Chakraborty's model
}
}
parameters{
real w;
real <lower =0>dz[C-1];
real m;
real <lower=0>v;
}
transformed parameters {
real <lower=0,upper=1>p[C];
real <lower=0>l[C];
real <lower=0>dl[C];
real z[C];
real a;
real b;
a=m/v;
b=1/v;
for(cd in 1 : C-1) { z[1] = w;
z[cd+1] = z[cd] +dz[cd];
}
for(cd in 1 : C) {
if (cd==C) { p[cd] = 1 - Phi((z[cd] -m)/v);
}else{
p[cd] = Phi((z[cd+1] -m)/v)- Phi((z[cd] -m)/v);
}
}
for(cd in 1 : C) { l[cd] = (-1)*log(Phi(z[cd])); }
for(cd in 1:C){
if (cd==C) {dl[cd] = fabs(l[cd]-0);
}else{
dl[cd] = fabs(l[cd]-l[cd+1]);
}
}
}
model{
for(n in 1:N) {
h[n] ~ binomial(NL, p[c[n]]);
// fff[n] ~ poisson( l[c[n]]*NL);//Non-Chakraborty's model
f[n] ~ poisson(dl[c[n]]*NI);//Chakraborty's model //<-------very very very coution, not n but c[n] 2019 Jun 21
// fff[n] ~ poisson( l[c[n]]*NI);//Non-Chakraborty's model
}
// priors
w ~ normal(ww,www);
for(cd in 1:C-1) dz[cd] ~ normal(zz,zzz);
m ~ normal(mm,mmm);
v ~ normal(vv,vvv);
}
generated quantities { // these adhere to the conventions above
int h_[C];
int f_[C];
vector [3 + C - 1] pars_;
int ranks_[3 + C - 1];
ranks_[1] = w > w_;
ranks_[2] = m > m_;
ranks_[3] = v > v_;
for (cd in 1:(C - 1)) ranks_[cd+3] = dz[cd] > dz_[cd];
pars_[1] = w_;
pars_[2] = m_;
pars_[3] = v_;
for (cd in 1:(C - 1)) pars_[cd+3] = dz_[cd];
// Here I copy the prior predictive realizations to y_ , and now it is denoted by h_ or f_
h_ = h;
f_ = f;
}
The list produced by sbc has an element called Y that holds realizations of the prior predictive distribution. There is no option (yet) to plot a subset of parameters, but you could make your own plot fairly easily based on the original code
https://github.com/stan-dev/rstan/blob/develop/rstan/rstan/R/SBC.R#L96

Export class from files other than index.ts

I made a file called assembly/Vec3.ts with this content:
/**
* #constructor
* #name pc.Vec3
* #classdesc A 3-dimensional vector.
* #description Creates a new Vec3 object.
* #param {Number} [x] The x value. If x is an array of length 3, the array will be used to populate all components.
* #param {Number} [y] The y value.
* #param {Number} [z] The z value.
* #example
* var v = new pc.Vec3(1, 2, 3);
*/
export class Vec3 {
x: number;
y: number;
z: number;
// AS is more strict than TS... need to replace all occuranves of this in PlayCanvasTS at some point
//constructor(x?: any, y?: number, z?: number)
constructor(x: number, y: number, z: number)
{
//if (x && x.length === 3) {
// this.x = x[0];
// this.y = x[1];
// this.z = x[2];
//} else {
// this.x = x || 0;
// this.y = y || 0;
// this.z = z || 0;
//}
this.x = x;
this.y = y;
this.z = z;
}
/**
* #function
* #name pc.Vec3#add
* #description Adds a 3-dimensional vector to another in place.
* #param {pc.Vec3} rhs The vector to add to the specified vector.
* #returns {pc.Vec3} Self for chaining.
* #example
* var a = new pc.Vec3(10, 10, 10);
* var b = new pc.Vec3(20, 20, 20);
*
* a.add(b);
*
* // Should output [30, 30, 30]
* console.log("The result of the addition is: " + a.toString());
*/
add(rhs: Vec3): Vec3 {
this.x += rhs.x;
this.y += rhs.y;
this.z += rhs.z;
return this;
}
/**
* #function
* #name pc.Vec3#add2
* #description Adds two 3-dimensional vectors together and returns the result.
* #param {pc.Vec3} lhs The first vector operand for the addition.
* #param {pc.Vec3} rhs The second vector operand for the addition.
* #returns {pc.Vec3} Self for chaining.
* #example
* var a = new pc.Vec3(10, 10, 10);
* var b = new pc.Vec3(20, 20, 20);
* var r = new pc.Vec3();
*
* r.add2(a, b);
* // Should output [30, 30, 30]
*
* console.log("The result of the addition is: " + r.toString());
*/
add2(lhs: Vec3, rhs: Vec3): Vec3 {
this.x = lhs.x + rhs.x;
this.y = lhs.y + rhs.y;
this.z = lhs.z + rhs.z;
return this;
}
}
Then building it via npm run asbuild
But the file is just ignored and not included inside the untouched.wasm.
Is it possible to export classes from all files?
Currently AssemblyScript support global export only from entry file (index.ts). So you should reexport all your entities to this file. But this may improve in future. See this discussion: https://github.com/AssemblyScript/assemblyscript/issues/464
Currently I solved it by adding the Vec3.ts to asc in doit.sh:
# print the commands via -x/+y
set -x
npx asc assembly/index.ts assembly/Vec3.ts -b build/untouched.wasm -t build/untouched.wat --sourceMap --validate --debug
npx asc assembly/index.ts assembly/Vec3.ts -b build/optimized.wasm -t build/optimized.wat --sourceMap --validate --optimize
set +x

realm react-native: how to query correctly an array of strings

can someone show me how to query an array of strings with realm in react-native?
assume i have an array like the following:
const preferences = ["automatic","suv","blue",eco]
What I want is to get realm results where ALL strings in the attribute "specifications" of Cars is in "preferences".
E.g.: If an instance of Cars.specifications contains ["automatic","suv"]
a result should be returned.
But if an instance of Cars.specifications contained ["automatic,"suv","green"] this instance shouldn't be returned.
The length of preferences can vary.
Thank you very much.
Update:
What i tried is the following:
const query = realm.objects("Cars").filtered('specifications = preferences[0] OR specifications = preferences[1]')
As you see it is an OR operator which is surely wrong and it is hardcoded. Looping with realm really confuses me.
This code will work!
const collection = realm.objects('Cars');
const preferences = ["automatic","suv","blue","eco"];
let queryString = 'ANY ';
for (let i = 0; i < preferences.length; i++) {
if (i === 0) {
queryString += `specifications CONTAINS '${preferences[i]}'`;
}
if (i !== 0 && i + 1 <= preferences.length) {
queryString += ` OR specifications CONTAINS '${preferences[i]}'`;
}
}
const matchedResult = collection.filtered(queryString);
example of function to test if a word is inside an array of word
function inArray(word, array) {
var lgth = array.length;
word = word.toLowerCase();
for (var i = 0; i < lgth; i++) {
array[i] = (array[i]).toLowerCase();
if (array[i] == word) return true;
}
return false;
}
const preferences = ["automatic","suv","blue","eco"];
const specifications = ["automatic","suv"] ;
const specifications2 = ["automatic","suv", "boat"] ;
function test(spec,pref){
for (var i in spec){
if(!inArray(spec[i],pref)){
return false ;
}
}
return true;
}
console.log(test(specifications,preferences));
console.log(test(specifications2,preferences));
https://jsfiddle.net/y1dz2gvu/

Createjs function

I am trying to convert an old simulation from Flash to createjs with animate cc. The only code you have is to rotate a piece but I can not get it to work. This code not work:
function spinit()
{
var ang = myangle * Math.PI / 180;
this.pin1.x = disk1.x + R * Math.cos(ang);
this.pin1.y = disk1.y + R * Math.sin(ang);
this.yoke1.x = pin1.x;
this.disk1.rotate = myangle;
this.myangle = myangle + 1;
if (myangle > 360)
{
myangle = 0;
}
}
var myangle = 0;
var R = 90;
setInterval(spinit, 5);
Chances are good this is a scope issue. Your spinit method is being called anonymously, so it won't have access to any of your frame content referenced with this. You can get around this by scoping your method, and binding your setInterval call.
this.spinit = function() // 1. scope the function
{
var ang = myangle * Math.PI / 180;
this.pin1.x = disk1.x + R * Math.cos(ang);
// etc
setInterval(spinit.bind(this), 5); // 2. bind this so it calls in the right scope.
}
Make sure to call this.spinit().
Hope that helps!

apply bind pose to a kinect skeleton

I want to normalize a skeleton in order to make it invariant to the size of the person
in front of the kinect; in the same way as the aveteering example.
But I don't want to animate a 3D model using XNA, the only thing I need is to normalize an
skeleton.
So in order to do this task, I have divided it in two functions:
(a) apply a bind pose to an skeleton in order to see how to work this matrix. Obviously this is not what i want to do, but it is a first step in order to
know how to work whit matrix, and so on.
(b) apply any arbitrary pose to a normalized-size-skeleton
First of all, I want to apply a bind pose to an skeleton (a).
First, I have to load the matrix that describe the bone length/ offset between bones and store it in
List BindPose.
Due to I have no idea how to do it, I modified the Aveteering example and write in a file all the Matrix that define
the BindPose, InverseBindPose and SkeletonHierarchy of the dude. I only need BindPose to this first task, but I have the
code prepared in order to do the second task (b)
The file looks like this:
1,331581E-06;-5,551115E-17;1;0;1;-4,16881E-11;-1,331581E-06;0;4,16881E-11;1;8,153579E-23;0;0,03756338;37,46099;2,230549;1
1,110223E-16;-4,435054E-22;1;0;1;1,426127E-06;-2,220446E-16;0;-1,426127E-06;1;-7,654181E-22;0;-0,9558675;-4,079016E-08;-6,266987E-12;1
0,9954988;-0,09477358;1,501821E-06;0;0,09477358;0,9954988;-4,019565E-06;0;-1,114112E-06;4,143805E-06;1;0;3,786007;-0,003599779;5,107028E-06;1
0,9948416;-0,101441;-3,23556E-07;0;0,101441;0,9948416;-2,266755E-08;0;3,241862E-07;-1,027114E-08;1;0;4,543321;-0,00359975;-1,33061E-07;1
0,9950595;0,09927933;2,388133E-07;0;-0,09927933;0,9950595;-2,333792E-08;0;-2,399506E-07;-4,86646E-10;1;0;4,544049;-0,003599948;6,324596E-08;1
0,9992647;0,02747673;0,02674458;0;-0,02928042;0,9971476;0,06956656;0;-0,02475683;-0,07029849;0,9972187;0;4,543965;-0,004398902;2,258555E-07;1
0,9154034;0,4025377;1,107153E-06;0;-0,4025377;0,9154033;-2,437432E-07;0;-1,109319E-06;-2,115673E-07;1;0;5,536249;-0,00288291;1,332601E-07;1
0,9812952;-0,1925096;-4,732622E-07;0;0,1925095;0,9812951;-3,00921E-08;0;4,697166E-07;-5,889972E-08;1;0;3,953898;1,702301E-07;4,88653E-08;1
.......
So each line is a 4X4 matrix defining the BindPose.
To generate this file, the code is like this:
private void ViewSkinningData(SkinningData data)
{
string nameFile = "bind_pose_transformations";
bool append = false;
// The using statement automatically closes the stream and calls IDisposable.Dispose on the stream object.
using (System.IO.StreamWriter file = new System.IO.StreamWriter(#nameFile, append))
{
for (int i = 0; i < data.BindPose.Count; i++)
{
Matrix m = data.BindPose[i];
string matrixString = MatrixToString(m);
file.WriteLine(matrixString);
}
for (int i = 0; i < data.InverseBindPose.Count; i++)
{
Matrix m = data.InverseBindPose[i];
string matrixString = MatrixToString(m);
file.WriteLine(matrixString);
}
for (int i = 0; i < data.SkeletonHierarchy.Count; i++)
{
file.Write(data.SkeletonHierarchy[i] + ";");
}
}
}
string MatrixToString(Matrix m)
{
string result;
result = m.M11 + ";" + m.M12 + ";" + m.M13 + ";" + m.M14 + ";" + m.M21 + ";" + m.M22 + ";" + m.M23 + ";" + m.M24 + ";" + m.M31 + ";" + m.M32 + ";" + m.M33 + ";" + m.M34 + ";" + m.M41 + ";" + m.M42 + ";" + m.M43 + ";" + m.M44;
return result;
}
Next step is to load all this Skinning data in my program:
private void InitializeSkinningDataFromFile()
{
string filename = "bind_pose_transformations";
int number_avatar_joints = 58;
List<Matrix> binpose = new System.Collections.Generic.List<Matrix>();
List<Matrix> inversebindpose = new System.Collections.Generic.List<Matrix>();
List<int> skeletonhierarchy = new System.Collections.Generic.List<int>();
// The using statement automatically closes the stream and calls IDisposable.Dispose on the stream object.
using (System.IO.StreamReader file = new System.IO.StreamReader(filename))
{
string s;
int count = 0;
while (!String.IsNullOrEmpty(s = file.ReadLine()))
{
string[] values = s.Split(';');
Matrix m = BuildMatrix(values);
binpose.Add(m);
count++;
if (count == number_avatar_joints)
{
break;
}
}
count = 0;
while (!String.IsNullOrEmpty(s = file.ReadLine()))
{
string[] values = s.Split(';');
Matrix m = BuildMatrix(values);
inversebindpose.Add(m);
count++;
if (count == number_avatar_joints)
{
break;
}
}
string[] skeletonHierarchy = file.ReadLine().Split(';'); //lee un caracter de separacion al final...
//for (int i = 0; i < skeletonHierarchy.Count(); i++)
for (int i = 0; i < number_avatar_joints; i++)
{
skeletonhierarchy.Add(int.Parse(skeletonHierarchy[i]));
}
}
skinningDataValue = new SkinningData(binpose, inversebindpose, skeletonhierarchy);
}
After, I have to construct boneTransforms structure:
// Bone matrices for the "dude" model
this.boneTransforms = new Matrix[skinningDataValue.BindPose.Count];
this.skinningDataValue.BindPose.CopyTo(this.boneTransforms, 0);
Now boneTransforms have the transformation for my skeleton. So now, i have to apply these trasnformations to an skeleton
Skeleton skeleton = new Skeleton();
foreach (Joint joint in skeleton.Joints)
{
int indexMatrix = AvatarBoneToNuiJointIndex(joint.JointType);
Matrix transform;
if (indexMatrix >= 0)
{
transform = this.boneTransforms[indexMatrix];
}
else
{
transform = Matrix.Identity;
}
Joint aux = ApplyMatrixTransformationToJoint(joint, transform);
normalizeSkel.Joints[joint.JointType] = aux;
}
This is a helper function AvatarBoneToNuiJointIndex:
public int AvatarBoneToNuiJointIndex(JointType jointType)
{
switch (jointType)
{
case JointType.HipCenter:
return 1;
case JointType.Spine:
return 4;
case JointType.ShoulderCenter:
return 6;
case JointType.Head:
return 7;
case JointType.ShoulderLeft:
return 12;
case JointType.ElbowLeft:
return 13;
case JointType.WristLeft:
return 14;
case JointType.HandLeft:
return 15;
case JointType.ShoulderRight:
return 31;
case JointType.ElbowRight:
return 32;
case JointType.WristRight:
return 33;
case JointType.HandRight:
return 34;
case JointType.KneeLeft:
return 50;
case JointType.AnkleLeft:
return 51;
case JointType.FootLeft:
return 52;
case JointType.KneeRight:
return 54;
case JointType.AnkleRight:
return 55;
case JointType.FootRight:
return 56;
default: return -1;
}
}
This is a helper function ApplyMatrixTransformationToJoint:
public Joint ApplyMatrixTransformationToJoint(Joint skeletonJoint, Matrix tranformations)
{
Vector3 pos = SkeletonPointToVector3(skeletonJoint.Position);
Vector3 result = ApplyMatrixTransformationToVector(pos, tranformations);
SkeletonPoint newPosition = new SkeletonPoint()
{
X = result.X,
Y = result.Y,
Z = result.Z
};
skeletonJoint.Position = newPosition;
return skeletonJoint;
}
This is the code for ApplyMatrixTransformationToVector:
static Vector3 ApplyMatrixTransformationToVector(Vector3 v, Matrix m)
{
return Vector3.Transform(v, m);
}
But the problem is that I can't see anything.
I don't know if this approach is correct.
Any help would be fantastic.
Many thanks!