Is there a JavaScript equivalent to numpy.linalg.pinv? - javascript

I'm trying to solve a linear system of equations that is overdetermined (Ax = B) given a matrix A generated by user input on a website with Javascript. In python I could just use numpy.linalg.pinv(A) to find the pseudoinverse of A and multiply that pseudo inverse with B to solve the system -- is there a JavaScript equivalent (library and/or piece of code) that could do this?
I tried using math.js; although it doesn't seem to have a pseudo inverse function, it has other matrix operations. I tried using
math.multiply(math.inv(math.multiply(math.transpose(A), A)), math.transpose(A))
to find the pseudo inverse but the matrix I got from multiplying the transpose of A with A was not invertible because the columns of A are apparently linearly dependent (I'm not very experienced with linear algebra but that's what I've gathered from some research online). However, numpy can still find a pseudo inverse even when the matrix A has linearly dependent columns (I tested the system with numpy) so that brings me back to the question of whether there's a way to replicate numpy's pseudo inverse function. And if not, is there some other solution to this problem?

Q : And if not, is there some other solution to this problem?
Yes, there is a way.
Implement distributed-processing workflow. Let JavaScript do its part and let numpy side do the work it is so smart at. Similar concept is common for many use-cases, where specialised tools solve parts of the problem and some workflow integration mediator "glues" the distributed parts together.
So, make JavaScript part equipped with ZeroMQ/zmq or nanomsg, communicate the A, B over the interconnect to a python-side, there numpy will make its best for the smart, vectorised number-crunching, and let the received results pass back to whatever next stage of the processing workflow.
ZeroMQ has for years smart tooling for very fast and efficient protocol-less { ipc:// | vmci:// } localhost interconnects, plus has similarly smart, yet non-local protocols for { tcp:// | udp:// | ... } datacentre interconnects, if your localhost resources would become prohibitively small for larger matrix sizes.
There are similar tools ready from nanomsg, yet you have to check for availability of JavaScript-side usable ports / wrappers.
The rest is just about squeezing out the maximum performance for any given volume of data and a requested cadence of the front-end / back-end transactions running.
Having used this architecture for a turn-around-time under ~ 80 [ms] just your imagination is your limit. Having also done some multi-TB linear algebra processing as fast as possible, more care will be necessary there, but the performance-motivated principles are the same.

I know it's been some time since this question was asked, but there are a few libraries for doing linear algebra in JS available now (2021), which I'll leave here for reference:
ml-matrix
eigen
linear-algebra-js
emlapack
linalg.js
Just to name a few. From your question it seems like you are trying to solve a least squares estimator:
If this is the case, most (all?) of the above libraries provide more robust / performant solutions compared to computing the pseudo-inverse, namely using LU/QR/SVD decompositions:
// Using ml-matrix
const { Matrix, solve } = require('ml-matrix');
var X = new Matrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]]);
var y = Matrix.columnVector([8, 20, 32]);
var b = solve(X, y, (useSVD = true));
// Using linear algebra js
const { SparseMatrix, DenseMatrix } = require('linear-algebra');
// solve the linear system Ax = b, where A is a square sparse matrix
var X = SparseMatrix.identity(5, 5);
var y = DenseMatrix.ones(5, 1);
var lu = X.lu();
var b = lu.solveSquare(y);
However, if you really require calculating the pseudo-inverse, ml-matrix is the only library which supports this (as far as I know). In principle, Eigen supports this as well, but I haven't seen any JS port actually exposing this functionality yet.

Related

Non-linear regression with errors in variables in JavaScript

I need a robust curve-fitting algorithm that would work in a browser. Namely I need it to be able to fit polynomial and trigonometric (and ideally all custom) functions, and it also has to account for errors in both variables.
I would like to use an existing library or rewrite an implementation written in a different but understandable language (pseudocode, Python, C#, C without much memory magic, etc.). Alternatively I could use a transpliter to JavaScript if it were possible. However I've searched for hours and haven't found any suitable JavaScript library, nor a straightforward implementation that I could crib.
I have found two pieces of software that can do what I want.
The first one is Gnuplot which is a utility written in C. It's open-source, but I found the code somewhat convoluted and the curve-fitting part was quite inter-dependent with other parts of the program, so I didn't manage to port it to JavaScript.
The second one is SciPy, a math library for Python. That would be an easy victory if the relevant part were actually written in Python. Which, sadly, is not the case, as instead it's a piece of old Fortran code modified, so that it can communicate with Python. The code was too difficult and archaic for me and Fortran-to-Javascript transpliters didn't work because of the Python-specific stuff in the code.
Do you know any project I could use? I know it's not going to be a “solve-all answer” but I will appreciate anything that will get me closer to the finish.
gnuplot can be transcoded via Emscripten to run as javascript in a browser. See live demonstration site gnuplot + emscripten.
The resulting javascript variant is not currently supported by the gnuplot project but the proof-of-principle demonstration is impressive.
Alglib.js will allow you to fit data data to an arbitrary function.
Go here for a complete example https://pterodactylus.github.io/Alglib.js/curve_fitting.html
<script type="module">
import {Alglib} from 'https://cdn.jsdelivr.net/gh/Pterodactylus/Alglib.js#master/Alglib-v1.1.0.js'
//import {Alglib} from '../Alglib-v1.1.0.js'
var f = function(a_n, x){
return a_n[3]*Math.pow(x, 3)+a_n[2]*Math.pow(x, 2)+a_n[1]*Math.pow(x, 1)+a_n[0];
}
let data = [[-3, 8], [1,3], [5,3], [9,8], [10,16]]
var fn1 = function(a){
let sum = 0
for (let i = 0; i < data.length; ++i) {
sum = sum + Math.pow(data[i][1] - f(a, data[i][0]), 2)
}
let sse = Math.sqrt(sum)
return sse
}
let solver = new Alglib()
solver.add_function(fn1) //Add the first equation to the solver.
solver.promise.then(function(result) {
var x_guess = [1,1,1,1] //Guess the initial values of the solution.
var s = solver.solve("min", x_guess) //Solve the equation
let x = solver.get_report()
solver.remove() //required to free the memory in C++
})
</script>

Multiplayer Game - Client Interpolation Calculation?

I am creating a Multiplayer game using socket io in javascript. The game works perfectly at the moment aside from the client interpolation. Right now, when I get a packet from the server, I simply set the clients position to the position sent by the server. Here is what I have tried to do:
getServerInfo(packet) {
var otherPlayer = players[packet.id]; // GET PLAYER
otherPlayer.setTarget(packet.x, packet.y); // SET TARGET TO MOVE TO
...
}
So I set the players Target position. And then in the Players Update method I simply did this:
var update = function(delta) {
if (x != target.x || y != target.y){
var direction = Math.atan2((target.y - y), (target.x - x));
x += (delta* speed) * Math.cos(direction);
y += (delta* speed) * Math.sin(direction);
var dist = Math.sqrt((x - target.x) * (x - target.x) + (y - target.y)
* (y - target.y));
if (dist < treshhold){
x = target.x;
y = target.y;
}
}
}
This basically moves the player in the direction of the target at a fixed speed. The issue is that the player arrives at the target either before or after the next information arrives from the server.
Edit: I have just read Gabriel Bambettas Article on this subject, and he mentions this:
Say you receive position data at t = 1000. You already had received data at t = 900, so you know where the player was at t = 900 and t = 1000. So, from t = 1000 and t = 1100, you show what the other player did from t = 900 to t = 1000. This way you’re always showing the user actual movement data, except you’re showing it 100 ms “late”.
This again assumed that it is exactly 100ms late. If your ping varies a lot, this will not work.
Would you be able to provide some pseudo code so I can get an Idea of how to do this?
I have found this question online here. But none of the answers provide an example of how to do it, only suggestions.
I'm completely fresh to multiplayer game client/server architecture and algorithms, however in reading this question the first thing that came to mind was implementing second-order (or higher) Kalman filters on the relevant variables for each player.
Specifically, the Kalman prediction steps which are much better than simple dead-reckoning. Also the fact that Kalman prediction and update steps work somewhat as weighted or optimal interpolators. And futhermore, the dynamics of players could be encoded directly rather than playing around with abstracted parameterizations used in other methods.
Meanwhile, a quick search led me to this:
An improvement of dead reckoning algorithm using kalman filter for minimizing network traffic of 3d on-line games
The abstract:
Online 3D games require efficient and fast user interaction support
over network, and the networking support is usually implemented using
network game engine. The network game engine should minimize the
network delay and mitigate the network traffic congestion. To minimize
the network traffic between game users, a client-based prediction
(dead reckoning algorithm) is used. Each game entity uses the
algorithm to estimates its own movement (also other entities'
movement), and when the estimation error is over threshold, the entity
sends the UPDATE (including position, velocity, etc) packet to other
entities. As the estimation accuracy is increased, each entity can
minimize the transmission of the UPDATE packet. To improve the
prediction accuracy of dead reckoning algorithm, we propose the Kalman
filter based dead reckoning approach. To show real demonstration, we
use a popular network game (BZFlag), and improve the game optimized
dead reckoning algorithm using Kalman filter. We improve the
prediction accuracy and reduce the network traffic by 12 percents.
Might seem wordy and like a whole new problem to learn what it's all about... and discrete state-space for that matter.
Briefly, I'd say a Kalman filter is a filter that takes into account uncertainty, which is what you've got here. It normally works on measurement uncertainty at a known sample rate, but it could be re-tooled to work with uncertainty in measurement period/phase.
The idea being that in lieu of a proper measurement, you'd simply update with the kalman predictions. The tactic is similar to target tracking applications.
I was recommended them on stackexchange myself - took about a week to figure out how they were relevant but I've since implemented them successfully in vision processing work.
(...it's making me want to experiment with your problem now !)
As I wanted more direct control over the filter, I copied someone else's roll-your-own implementation of a Kalman filter in matlab into openCV (in C++):
void Marker::kalmanPredict(){
//Prediction for state vector
Xx = A * Xx;
Xy = A * Xy;
//and covariance
Px = A * Px * A.t() + Q;
Py = A * Py * A.t() + Q;
}
void Marker::kalmanUpdate(Point2d& measuredPosition){
//Kalman gain K:
Mat tempINVx = Mat(2, 2, CV_64F);
Mat tempINVy = Mat(2, 2, CV_64F);
tempINVx = C*Px*C.t() + R;
tempINVy = C*Py*C.t() + R;
Kx = Px*C.t() * tempINVx.inv(DECOMP_CHOLESKY);
Ky = Py*C.t() * tempINVy.inv(DECOMP_CHOLESKY);
//Estimate of velocity
//units are pixels.s^-1
Point2d measuredVelocity = Point2d(measuredPosition.x - Xx.at<double>(0), measuredPosition.y - Xy.at<double>(0));
Mat zx = (Mat_<double>(2,1) << measuredPosition.x, measuredVelocity.x);
Mat zy = (Mat_<double>(2,1) << measuredPosition.y, measuredVelocity.y);
//kalman correction based on position measurement and velocity estimate:
Xx = Xx + Kx*(zx - C*Xx);
Xy = Xy + Ky*(zy - C*Xy);
//and covariance again
Px = Px - Kx*C*Px;
Py = Py - Ky*C*Py;
}
I don't expect you to be able to use this directly though, but if anyone comes across it and understand what 'A', 'P', 'Q' and 'C' are in state-space (hint hint, state-space understanding is a pre-req here) they'll likely see how connect the dots.
(both matlab and openCV have their own Kalman filter implementations included by the way...)
This question is being left open with a request for more detail, so I’ll try to fill in the gaps of Patrick Klug’s answer. He suggested, reasonably, that you transmit both the current position and the current velocity at each time point.
Since two position and two velocity measurements give a system of four equations, it enables us to solve for a system of four unknowns, namely a cubic spline (which has four coefficients, a, b, c and d). In order for this spline to be smooth, the first and second derivatives (velocity and acceleration) should be equal at the endpoints. There are two standard, equivalent ways of calculating this: Hermite splines (https://en.wikipedia.org/wiki/Cubic_Hermite_spline) and Bézier splines (http://mathfaculty.fullerton.edu/mathews/n2003/BezierCurveMod.html). For a two-dimensional problem such as this, I suggested separating variables and finding splines for both x and y based on the tangent data in the updates, which is called a clamped piecewise cubic Hermite spline. This has several advantages over the splines in the link above, such as cardinal splines, which do not take advantage of that information. The locations and velocities at the control points will match, you can interpolate up to the last update rather than the one before, and you can apply this method just as easily to polar coordinates if the game world is inherently polar like Space wars. (Another approach sometimes used for periodic data is to perform a FFT and do trigonometric interpolation in the frequency domain, but that doesn’t sound applicable here.)
What originally appeared here was a derivation of the Hermite spline using linear algebra in a somewhat unusual way that (unless I made a mistake entering it) would have worked. However, the comments convinced me it would be more helpful to give the standard names for what I was talking about. If you are interested in the mathematical details of how and why this works, this is a better explanation: https://math.stackexchange.com/questions/62360/natural-cubic-splines-vs-piecewise-hermite-splines
A better algorithm than the one I gave is to represent the sample points and first derivatives as a tridiagonal matrix that, multiplied by a column vector of coefficients, produces the boundary conditions, and solve for the coefficients. An alternative is to add control points to a Bézier curve where the tangent lines at the sampled points intersect and on the tangent lines at the endpoints. Both methods produce the same, unique, smooth cubic spline.
One situation you might be able to avoid if you were choosing the points rather than receiving updates is if you get a bad sample of points. You can’t, for example, intersect parallel tangent lines, or tell what happened if it’s back in the same place with a nonzero first derivative. You’d never choose those points for a piecewise spline, but you might get them if an object made a swerve between updates.
If my computer weren’t broken right now, here is where I would put fancy graphics like the ones I posted to TeX.SX. Unfortunately, I have to bow out of those for now.
Is this better than straight linear interpolation? Definitely: linear interpolation will get you straight- line paths, quadratic splines won't be smooth, and higher-order polynomials will likely be overfitted. Cubic splines are the standard way to solve that problem.
Are they better for extrapolation, where you try to predict where a game object will go? Possibly not: this way, you’re assuming that a player who’s accelerating will keep accelerating, rather than that they will immediately stop accelerating, and that could put you much further off. However, the time between updates should be short, so you shouldn’t get too far off.
Finally, you might make things a lot easier on yourself by programming in a bit more conservation of momentum. If there’s a limit to how quickly objects can turn, accelerate or decelerate, their paths will not be able to diverge as much from where you predict based on their last positions and velocities.
Depending on your game you might want to prefer smooth player movement over super-precise location. If so, then I'd suggest to aim for 'eventual consistency'. I think your idea of keeping 'real' and 'simulated' data-points is a good one. Just make sure that from time to time you force the simulated to converge with the real, otherwise the gap will get too big.
Regarding your concern about different movement speed I'd suggest you include the current velocity and direction of the player in addition to the current position in your packet. This will enable you to more smoothly predict where the player would be based on your own framerate/update timing.
Essentially you would calculate the current simulated velocity and direction taking into account the last simulated location and velocity as well as last known location and velocity (put more emphasis on the second) and then simulate new position based on that.
If the gap between simulated and known gets too big, just put more emphasis on the known location and the otherPlayer will catch up quicker.

CANNON.js: check if a body is being constrained

I've been trying to make a multiplayer game using javascript (most of which is on the server, using Node.js); one of the core mechanics I want to make is that players will be able to design their own fighting style (right down to how they swing their sword etc). Problem is that I can't find any simple way of constraining players' movements.
I first tried to write a method that checks then clamps the player's style so it doesn't look like they're breaking every limb simultaneously, but that didn't really work. I then found the wonderful CANNON.ConeTwistConstraint, but after looking through the documentation I've found that CANNON.js's constraints don't seem to have any sort of built-in function for just testing whether two bodies are exceeding the constraint's limits. I've thought about having my game just create objects in a separate simulation and check whether a force is being applied to either object, but I'm not sure about how to go about this, or if there's a better way.
Is there a simple/easier solution to my problem? If not, what would be the least CPU-intensive way of implementing the above?
You can manually check if the ConeTwistConstraint is hitting its limit. If you have a look at the method CANNON.ConeEquation.prototype.computeB, you can see that it computes the constraint violation, "g", using cos() and a dot product. You can simply do the same with the following code.
var eq = coneTwistConstraint.coneEquation;
var g = Math.cos(eq.angle) - eq.axisA.dot(eq.axisB);
if(g > 0) {
// Constraint limit exceeded
} else {
// Constraint is within limits
}
Using the same strategy, you can check if the twist limit is exceeded. Since the twist equation is a CANNON.RotationalEquation, the code becomes:
var eq2 = coneTwistConstraint.twistEquation;
var g2 = Math.cos(eq2.maxAngle) - eq2.axisA.dot(eq2.axisB);

Verlet / Euler Integration is inaccurate

I want create some physx to game, and I started with small example to understand how it works. During this i had a few problems but i resolved them in 90%.
To create my exmaple i studied some other examples and to create this one i used: codeflow.org/entries/2010/aug/28/integration-by-example-euler-vs-verlet-vs-runge-kutta/
At first - This is dirty and inefficient code, only 1 thing i am interested in two problems:
#1 There is "timestep" loop to create accurate ellipse but if i move 1 object (second is static) with for example steps = 5, ellipse is accurate, but if both object are dynamic, curves are totaly inaccurate.
BUT run with steps = 1 my objects are more accurate (WHAT?) moreover if 1 object is static my ellipse is little inaccurate.
planet1.updateVelocity(planet2.position);
planet1.updatePosition();
planet1.repaint();
jsfiddle example with 1 static - http://jsfiddle.net/hnq8eqta/
change window.steps (1 or 5) to test.
planet1.updateVelocity(planet2.position);
planet2.updateVelocity(planet1.position);
planet1.updatePosition();
planet1.repaint();
planet2.updatePosition();
planet2.repaint();
jsfiddle example with 2 dynamic - http://jsfiddle.net/agbhwe9g/
change steps too.
#2 I think this is not normal behavior - if 1 of object have greater inital vector, both objects trajectory is werid and they run away from the screen. Is it normal for this alorithm? We can do very similar simulation here: phet.colorado.edu/sims/my-solar-system/my-solar-system_en.html
but this is not the same...
window.planet1 = new Planet("planet1",250,350,0,1);
window.planet2 = new Planet("planet2",550,250,0,-1);
//changed to
window.planet1 = new Planet("planet1",250,350,0,1);
window.planet2 = new Planet("planet2",550,250,0,-2);
example - jsfiddle.net/hr1ebq3c/
Whats wrong with my verlet integration?
First, what you are using is not Verlet but the symplectic Euler method.
Second, it is of utmost importance to treat a coupled system as a coupled system. In this special instance this happens to be correct for steps=1. Any other value of steps or an implementation of Verlet in this style will destroy the consistency of the method.
Always compute the accelerations for all components of the system at once, without updating any position or velocity values in between.

Multi-tempo/meter js DAW

Has anyone implemented a javascript audio DAW with multiple tempo and meter change capabilities like most of the desktop daws (pro tools, sonar, and the like)? As far as I can tell, claw, openDAW, and web audio editor don't do this. Drawing a grid meter, converting between samples and MBT time, and rendering waveforms is easy when the tempo and meter do not change during the project, but when they do it gets quite a bit more complicated. I'm looking for any information on how to accomplish something like this. I'm aware that the source for Audacity is available, but I'd love to not have to dig through an enormous pile of code in a language I'm not an expert in to figure this out.
web-based DAW solutions exists.web-based DAW's are seen as SaaS(Software as a Service) applications.
They are lightweight and contain basic fundamental DAW features.
For designing rich client applications(RCA) you should take a look at GWT and Vaadin.
I recommend GWT because it is mature and has reusable components and its also AJAX driven.
Also here at musicradar site they have listed nine different browser based audio workstations.you can also refer to popcorn maker which is entirely javascript code.You can get some inspiration from there to get started.
You're missing the last step, which will make it easier.
All measures are relative to fractions of minutes, based on the time-signature and tempo.
The math gets a little more complex, now that you can't just plot 4/4 or 6/8 across the board and be done with it, but what you're looking at is running an actual time-line (whether drawn onscreen or not), and then figuring out where each measure starts and ends, based on either the running sum of a track's current length (in minutes/seconds), or based on the left-most take's x-coordinate (starting point) + duration...
or based on the running total of each measure's length in seconds, up to the current beat you care about.
var measure = { beats : 4, denomination : 4, tempo : 80 };
Given those three data-points, you should be able to say:
var measure_length = SECONDS_PER_MINUTE / measure.tempo * measure.beats;
Of course, that's currently in seconds. To get it in ms, you'd just use MS_PER_MINUTE, or whichever other ratio of minutes you'd want to measure by.
current_position + measure_length === start_of_next_measure;
You've now separated out each dimension required to allow you to calculate each measure on the fly.
Positioning each measure on the track, to match up with where it belongs on the timeline is as simple as keeping a running tally of where X is (the left edge of the measure) in ms (really in screen-space and project-coordinates, but ms can work fine for now).
var current_position = 0,
current_tempo = 120,
current_beats = 4,
current_denomination = 4,
measures = [ ];
measures.forEach(function (measure) {
if (measure.tempo !== current_tempo) {
/* draw tempo-change, set current_tempo */
/* draw time-signature */
}
if (measure.beats !== current_beats ||
measure.denomination !== current_denomination) {
/* set changes, draw time-signature */
}
draw_measure(measure, current_position);
current_position = MS_PER_MINUTE / measure.beats * measure.tempo;
});
Drawing samples just requires figuring out where you're starting from, and then sticking to some resolution (MS/MS*4/Seconds).
The added benefit of separating out the calculation of the time is that you can change the resolution of your rendering on the fly, by changing which time-scale you're comparing against (ms/sec/min/etc), so long as you re-render the whole thing, after scaling.
The rabbit hole goes deeper (for instance, actual audio tracks don't really care about measures/beats, though quantization-processes do), so to write a non-destructive, non-linear DAW, you can just set start-time and duration properties on views into your audio-buffer (or views into view-buffers of your audio buffer).
Those views would be the non-destructive windows that you can resize and drag around your track.
Then there's just the logic of figuring out snaps -- what your screen-space is, versus project-space, and when you click on a track's clip, which measure, et cetera, you're in, to do audio-snapping on resize/move.
Of course, to do a 1:1 recreation of ProTools in JS in the browser would not fly (gigs of RAM for one browser tab won't do, media capture API is still insufficient for multi-tracking, disk-writes are much, much more difficult in browser than in C++, in your OS of choice, et cetera), but this should at least give you enough to run with.
Let me know if I'm missing something.

Categories

Resources