简体   繁体   中英

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>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM