Non-linear regression with errors in variables in JavaScript - 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>

Related

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

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.

Is it better in practice to make sure the algorithm only initiates the function if there is a need to do so or to just initiate the function in jquery [duplicate]

CPU Cycles, Memory Usage, Execution Time, etc.?
Added: Is there a quantitative way of testing performance in JavaScript besides just perception of how fast the code runs?
Profilers are definitely a good way to get numbers, but in my experience, perceived performance is all that matters to the user/client. For example, we had a project with an Ext accordion that expanded to show some data and then a few nested Ext grids. Everything was actually rendering pretty fast, no single operation took a long time, there was just a lot of information being rendered all at once, so it felt slow to the user.
We 'fixed' this, not by switching to a faster component, or optimizing some method, but by rendering the data first, then rendering the grids with a setTimeout. So, the information appeared first, then the grids would pop into place a second later. Overall, it took slightly more processing time to do it that way, but to the user, the perceived performance was improved.
These days, the Chrome profiler and other tools are universally available and easy to use, as are
console.time() (mozilla-docs, chrome-docs)
console.profile() (mozilla-docs, chrome-docs)
performance.now() (mozilla-docs)
Chrome also gives you a timeline view which can show you what is killing your frame rate, where the user might be waiting, etc.
Finding documentation for all these tools is really easy, you don't need an SO answer for that. 7 years later, I'll still repeat the advice of my original answer and point out that you can have slow code run forever where a user won't notice it, and pretty fast code running where they do, and they will complain about the pretty fast code not being fast enough. Or that your request to your server API took 220ms. Or something else like that. The point remains that if you take a profiler out and go looking for work to do, you will find it, but it may not be the work your users need.
I do agree that perceived performance is really all that matters. But sometimes I just want to find out which method of doing something is faster. Sometimes the difference is HUGE and worth knowing.
You could just use javascript timers. But I typically get much more consistent results using the native Chrome (now also in Firefox and Safari) devTool methods console.time() & console.timeEnd()
Example of how I use it:
var iterations = 1000000;
console.time('Function #1');
for(var i = 0; i < iterations; i++ ){
functionOne();
};
console.timeEnd('Function #1')
console.time('Function #2');
for(var i = 0; i < iterations; i++ ){
functionTwo();
};
console.timeEnd('Function #2')
Update (4/4/2016):
Chrome canary recently added Line Level Profiling the dev tools sources tab which let's you see exactly how long each line took to execute!
We can always measure time taken by any function by simple date object.
var start = +new Date(); // log start timestamp
function1();
var end = +new Date(); // log end timestamp
var diff = end - start;
Try jsPerf. It's an online javascript performance tool for benchmarking and comparing snippets of code. I use it all the time.
Most browsers are now implementing high resolution timing in performance.now(). It's superior to new Date() for performance testing because it operates independently from the system clock.
Usage
var start = performance.now();
// code being timed...
var duration = performance.now() - start;
References
https://developer.mozilla.org/en-US/docs/Web/API/Performance.now()
http://www.w3.org/TR/hr-time/#dom-performance-now
JSLitmus is a lightweight tool for creating ad-hoc JavaScript benchmark tests
Let examine the performance between function expression and function constructor:
<script src="JSLitmus.js"></script>
<script>
JSLitmus.test("new Function ... ", function() {
return new Function("for(var i=0; i<100; i++) {}");
});
JSLitmus.test("function() ...", function() {
return (function() { for(var i=0; i<100; i++) {} });
});
</script>
What I did above is create a function expression and function constructor performing same operation. The result is as follows:
FireFox Performance Result
IE Performance Result
Some people are suggesting specific plug-ins and/or browsers. I would not because they're only really useful for that one platform; a test run on Firefox will not translate accurately to IE7. Considering 99.999999% of sites have more than one browser visit them, you need to check performance on all the popular platforms.
My suggestion would be to keep this in the JS. Create a benchmarking page with all your JS test on and time the execution. You could even have it AJAX-post the results back to you to keep it fully automated.
Then just rinse and repeat over different platforms.
Here is a simple function that displays the execution time of a passed in function:
var perf = function(testName, fn) {
var startTime = new Date().getTime();
fn();
var endTime = new Date().getTime();
console.log(testName + ": " + (endTime - startTime) + "ms");
}
I have a small tool where I can quickly run small test-cases in the browser and immediately get the results:
JavaScript Speed Test
You can play with code and find out which technique is better in the tested browser.
I think JavaScript performance (time) testing is quite enough. I found a very handy article about JavaScript performance testing here.
You could use this: http://getfirebug.com/js.html. It has a profiler for JavaScript.
I was looking something similar but found this.
https://jsbench.me/
It allows a side to side comparison and you can then also share the results.
performance.mark (Chrome 87 ^)
performance.mark('initSelect - start');
initSelect();
performance.mark('initSelect - end');
Quick answer
On jQuery (more specifically on Sizzle), we use this (checkout master and open speed/index.html on your browser), which in turn uses benchmark.js. This is used to performance test the library.
Long answer
If the reader doesn't know the difference between benchmark, workload and profilers, first read some performance testing foundations on the "readme 1st" section of spec.org. This is for system testing, but understanding this foundations will help JS perf testing as well. Some highlights:
What is a benchmark?
A benchmark is "a standard of measurement or evaluation" (Webster’s II Dictionary). A computer benchmark is typically a computer program that performs a strictly defined set of operations - a workload - and returns some form of result - a metric - describing how the tested computer performed. Computer benchmark metrics usually measure speed: how fast was the workload completed; or throughput: how many workload units per unit time were completed. Running the same computer benchmark on multiple computers allows a comparison to be made.
Should I benchmark my own application?
Ideally, the best comparison test for systems would be your own application with your own workload. Unfortunately, it is often impractical to get a wide base of reliable, repeatable and comparable measurements for different systems using your own application with your own workload. Problems might include generation of a good test case, confidentiality concerns, difficulty ensuring comparable conditions, time, money, or other constraints.
If not my own application, then what?
You may wish to consider using standardized benchmarks as a reference point. Ideally, a standardized benchmark will be portable, and may already have been run on the platforms that you are interested in. However, before you consider the results you need to be sure that you understand the correlation between your application/computing needs and what the benchmark is measuring. Are the benchmarks similar to the kinds of applications you run? Do the workloads have similar characteristics? Based on your answers to these questions, you can begin to see how the benchmark may approximate your reality.
Note: A standardized benchmark can serve as reference point. Nevertheless, when you are doing vendor or product selection, SPEC does not claim that any standardized benchmark can replace benchmarking your own actual application.
Performance testing JS
Ideally, the best perf test would be using your own application with your own workload switching what you need to test: different libraries, machines, etc.
If this is not feasible (and usually it is not). The first important step: define your workload. It should reflect your application's workload. In this talk, Vyacheslav Egorov talks about shitty workloads you should avoid.
Then, you could use tools like benchmark.js to assist you collect metrics, usually speed or throughput. On Sizzle, we're interested in comparing how fixes or changes affect the systemic performance of the library.
If something is performing really bad, your next step is to look for bottlenecks.
How do I find bottlenecks? Profilers
What is the best way to profile javascript execution?
I find execution time to be the best measure.
You could use console.profile in firebug
I usually just test javascript performance, how long script runs. jQuery Lover gave a good article link for testing javascript code performance, but the article only shows how to test how long your javascript code runs. I would also recommend reading article called "5 tips on improving your jQuery code while working with huge data sets".
Here is a reusable class for time performance. Example is included in code:
/*
Help track time lapse - tells you the time difference between each "check()" and since the "start()"
*/
var TimeCapture = function () {
var start = new Date().getTime();
var last = start;
var now = start;
this.start = function () {
start = new Date().getTime();
};
this.check = function (message) {
now = (new Date().getTime());
console.log(message, 'START:', now - start, 'LAST:', now - last);
last = now;
};
};
//Example:
var time = new TimeCapture();
//begin tracking time
time.start();
//...do stuff
time.check('say something here')//look at your console for output
//..do more stuff
time.check('say something else')//look at your console for output
//..do more stuff
time.check('say something else one more time')//look at your console for output
UX Profiler approaches this problem from user perspective. It groups all the browser events, network activity etc caused by some user action (click) and takes into consideration all the aspects like latency, timeouts etc.
Performance testing became something of a buzzword as of late but that’s not to say that performance testing is not an important process in QA or even after the product has shipped. And while I develop the app I use many different tools, some of them mentioned above like the chrome Profiler I usually look at a SaaS or something opensource that I can get going and forget about it until I get that alert saying that something went belly up.
There are lots of awesome tools that will help you keep an eye on performance without having you jump through hoops just to get some basics alerts set up. Here are a few that I think are worth checking out for yourself.
Sematext.com
Datadog.com
Uptime.com
Smartbear.com
Solarwinds.com
To try and paint a clearer picture, here is a little tutorial on how to set up monitoring for a react application.
You could use https://github.com/anywhichway/benchtest which wraps existing Mocha unit tests with performance tests.
The golden rule is to NOT under ANY circumstances lock your users browser. After that, I usually look at execution time, followed by memory usage (unless you're doing something crazy, in which case it could be a higher priority).
This is a very old question but I think we can contribute with a simple solution based on es6 for fast testing your code.
This is a basic bench for execution time. We use performance.now() to improve the accuracy:
/**
* Figure out how long it takes for a method to execute.
*
* #param {Function} method to test
* #param {number} iterations number of executions.
* #param {Array} list of set of args to pass in.
* #param {T} context the context to call the method in.
* #return {number} the time it took, in milliseconds to execute.
*/
const bench = (method, list, iterations, context) => {
let start = 0
const timer = action => {
const time = performance.now()
switch (action) {
case 'start':
start = time
return 0
case 'stop':
const elapsed = time - start
start = 0
return elapsed
default:
return time - start
}
};
const result = []
timer('start')
list = [...list]
for (let i = 0; i < iterations; i++) {
for (const args of list) {
result.push(method.apply(context, args))
}
}
const elapsed = timer('stop')
console.log(`Called method [${method.name}]
Mean: ${elapsed / iterations}
Exec. time: ${elapsed}`)
return elapsed
}
const fnc = () => {}
const isFunction = (f) => f && f instanceof Function
const isFunctionFaster = (f) => f && 'function' === typeof f
class A {}
function basicFnc(){}
async function asyncFnc(){}
const arrowFnc = ()=> {}
const arrowRFnc = ()=> 1
// Not functions
const obj = {}
const arr = []
const str = 'function'
const bol = true
const num = 1
const a = new A()
const list = [
[isFunction],
[basicFnc],
[arrowFnc],
[arrowRFnc],
[asyncFnc],
[Array],
[Date],
[Object],
[Number],
[String],
[Symbol],
[A],
[obj],
[arr],
[str],
[bol],
[num],
[a],
[null],
[undefined],
]
const e1 = bench(isFunction, list, 10000)
const e2 = bench(isFunctionFaster, list, 10000)
const rate = e2/e1
const percent = Math.abs(1 - rate)*100
console.log(`[isFunctionFaster] is ${(percent).toFixed(2)}% ${rate < 1 ? 'faster' : 'slower'} than [isFunction]`)
This is a good way of collecting performance information for the specific operation.
start = new Date().getTime();
for (var n = 0; n < maxCount; n++) {
/* perform the operation to be measured *//
}
elapsed = new Date().getTime() - start;
assert(true,"Measured time: " + elapsed);

Converting Vector Processing syntax to p5 sketch

I am learning coding and am a novice. I am currently trying to convert a Processing(java) sketch to a p5(javascript) sketch to put on my first website.
I'm having trouble translating the Vector and Array syntax from the Processing sketch.
This is the Vector from the processing Sketch (working):
for (int i = pts.size()-1; i >= 0; i --){
PVector pt = (PVector)pts.get(i);
......
PVector pt2 = (PVector)pts.get(j);
if (pt.dist(pt2) < 20){
......
Here is how I've been trying to translate it in p5 (not working)
for (var i = pts.size()-1; i >= 0; i --){
pt = p5.Vector.pts.get(i);
...........
var pt2 = (PVector)pts.get(j);
if (pt.dist(pt2) < 20){
line(pt.x, pt.y, pt2.x, pt2.y);
}
}
You shouldn't try to translate code by going line-by-line and translating the syntax. Instead, you need to take a step back and convert the program into English first. Then you take that English and try to implement it in the targed language. That might sound dumb, but that English is called an algorithm.
So, you should have a description of your program like this:
"Show 10 circles bouncing around the screen. If a circle touches the edge of the screen, it should bounce off by..."
That's just an example, but you get the idea. Then you'd take that and implement it in P5.js.
So instead of saying "how do I convert this array syntax to P5.js", you should be asking yourself "how do arrays work in JavaScript" or even "how do variables work in JavaScript". From there you can read tutorials to figure out how to implement your algorithm in P5.js.
Then if you get stuck on a specific syntax error, please look in the JavaScript console for any errors you're getting. We can't really help if all you tell us is that it's not working. What error are you getting? Where is your MCVE?
All of that being said, I'll try to help with your specific question. Let's take the original line:
PVector pt = (PVector)pts.get(i);
This line is declaring a variable named pt and is pointing it at whatever is returned from pts.get(i), which it casts to a PVector because Java is statically typed so everything needs a type.
Compare that to what you're trying to do in P5.js:
pt = p5.Vector.pts.get(i);
First off, where did you declare the pt variable? Secondly what is p5.Vector.pts? This syntax doesn't make any sense. You need to read up on how variables and arrays work in JavaScript.
Similarly, let's look at this line in your P5.js code:
var pt2 = (PVector)pts.get(j);
Again, where is pts declared? And you never have to cast anything in JavaScript, because it's dynamically typed. Again, you need to go back and read up on how variables in JavaScript work.
Shameless self-promotion: I've written a series of tutorials geared towards Processing developers trying to learn JavaScript, available here.

How to manage arguments

I apologise in advance if I'm too bad at using the search engine and this has already been answered. Please point me in the right direction in that case.
I've recently begun to use the arguments variable in functions, and now I need to slice it. Everywhere I look people are doing things like:
function getArguments(args, start) {
return Array.prototype.slice.call(args, start);
}
And according to MDN this is bad for performance:
You should not slice on arguments because it prevents optimizations in JavaScript engines (V8 for example).
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments
Is there a reason why I don't see anyone doing things like this:
function getArguments(args, start) {
var i, p = 0;
var len = args.length;
var params = [];
for (i = start; i < len; ++i) {
params[p] = args[i];
p += 1;
}
return params;
}
You get the arguments you want, and no slicing is done. So from my point of view, you don't loose anything on this, well maybe it uses a little extra memory and is slightly slower, but not to the point where it really makes a difference, right?
Just wanted to know if my logic here is flawed.
Here is a discuss
and here is introduction
e.g. here uses the inline slice
It appears from the discussion that #Eason posted, (here) that the debate is in the "microptimization" category, ie: most of us will never hit those performance bumps because our code isn't being run through the kind of iterations needed to even appear on the radar.
Here's a good quote that sums it up:
Micro-optimizations like this are always going to be a trade-off
between the code's complexity/readability and its performance.
In many cases, the complexity/readability is more important. In this case, the
very slowest method that was tested netted a runtime of 4.3
microseconds. If you're writing a webservice and you're slicing args
two times per request and then doing 100 ms worth of other work, an
extra 0.0086 ms will not be noticeable and it's not worth the time or
the code pollution to optimize.
These optimizations are most helpful in really hot loops that you're hitting a gajillionty times. Use a
profiler to find your hot code, and optimize your hottest code first,
until the performance you've achieved is satisfactory.
I'm satisfied, and will use Array.prototype.slice.call() unless I detect a performance blip that points to that particular piece of code not hitting the V8 optimizer.

How to make the fastest possible bottom-up tree transformer in JavaScript? Should I manage memory on my own?

I am implementing a bottom-up tree transformer in JavaScript. It will be used for an interpreter for a supercombinator reducer, so this algorithm has to be as fast as possible, as it affects every program built on top of it. This is my current implementation:
function transform(tree,fn){
var root = tree,
node = tree,
child,
parent,
is_node,
dir;
root.dir = 0;
while(true) {
is_node = typeof(node)==="object";
dir = is_node ? node.dir : 2;
if (dir < 2)
child = node[dir],
node.dir++,
child.parent = parent = node,
child.dir = 0,
node = child;
else if ((changed = fn(node))!==undefined)
changed.parent = parent,
changed.dir = 0,
node = changed;
else
if (!parent)
return node;
else
parent[parent.dir-1] = node,
node = parent,
parent = node.parent;
};
};
// TEST
var tree = [[1,2],[[3,4],[5,6]]];
console.log(
JSON.stringify(transform(tree,function(a){
if (a[0]===1) return [3,[5,5]];
if (a[0]===5) return 77;
})) === "[[3,77],[[3,4],77]]");
This is obviously far from optimal. How do I make the transformer the fastest possible? Maybe instead of looking for a faster algorithm, I could manage the memory by myself, and use asm.js.
You have a couple of options, going from easiest-but-slowest to fastest-but-trickiest.
Using regular JavaScript
This is pretty much what you are doing at this point. Looking at your algorithm, I don't see anything that can really be suggested that would show anything more than an insignificant increase in speed.
Using asm.js
Using asm.js might be an option for you. This would offer a speed increase. You don't go in to a lot of details of where this system will be used, but if it works, it shouldn't be terribly difficult to implement something like this. You would likely see performance increases, but depending on how you are planning to use this, it might not be as substantial as you would like (for something like this, you'd probably see somewhere between 50%-500% increase in speed, depending how efficient the code is).
Build it in a different, compiled, typed language.
If speed is really at a premium, depending on your use case, it might be best to write this program (or at least this function) in a different language which is compiled. You could then run this compiled script on the server and communicate with it via web services.
If the number of times you need to transform the tree in a short amount of times is huge, it won't be much of a boost because of the time it would take to send and receive the data. However, if you are just doing relatively few but long-running tree transformation, you could see a huge benefit in performance. A compiled, typed language (C++, Java, etc) will always have better performance than an interpreted, typeless language like JavaScript.
The other benefit of running it on a server is you can generally throw a lot more horsepower at it, since you could write it to be multi-threaded and even run on a cluster of machines instead of just one (for a high-end build). With JavaScript, you are limited to generally one thread and also by the end-users computer.

Categories

Resources