littleredcomputer / odex-js

Bulirsch-Stoer integration of systems of ordinary differential equations in JavaScript
BSD 2-Clause "Simplified" License
53 stars 5 forks source link

Simple in browser use? #1

Closed zahachtah closed 7 years ago

zahachtah commented 7 years ago

Hi Colin,

I really like this and would like to use it for making a scientific climate change model accessible to readers to investigate. It seems to me that the way the code is written its for running on Node (since you use var odex = require('odex'); )? even though you have some nice demopages for viewing in browser. But I cannot understand how to easily get odex-js to load into a webpage without require.

Would you be able to give me a little hint on how to most simply make a webpage with a custom ode to solve? I can do the displaying and stuff, I essentially just need to know the best way to access odex-js in a browser.

Many thanks!

littleredcomputer commented 7 years ago

Hello, and thanks for writing!

There's a thing called browserify which prepares JS modules written in the node style for the browser. The source code that drives my github pages is on github too, so you can take a peek at how I did it here, using gulp to orchestrate the typescript compilation and browserify steps.

Warning: on the frontend, I'm a dabbler not an expert, so you might find a way to put it together that you like better. For example, other ways to do this include requirejs and webpack

zahachtah commented 7 years ago

Hi, and thanks for those pointers. I'll see how far I get, I'll let you know :-)

zahachtah commented 7 years ago

I am getting slowly somewhere...

to get an array output of the integration, does this seem like a reasonable (efficient) way or can I get it to store an array of outputs directly, e.g. in out.y (now out.y seems to be the last value only)?:

a=[];
s.denseOutput = true;
out=s.solve(f, 0, [1], 1, s.grid(0.2, function(x,y) {
  a.push(y[0]);
}));
littleredcomputer commented 7 years ago

Odex has a very Fortran style, so there is no dynamic memory allocation in it, and the array storage that it statically allocates is often recycled. Your solution is what I would write.

zahachtah commented 7 years ago

I love it, a javascript library with fortran style :-D

littleredcomputer commented 7 years ago

Heh. Here's the source if you're curious. Initially, I tried to change the style, but that turned into a fight. In the end, I decided that the original style has virtues of its own (discretion is the better part of valor).

For example, if you don't need to store the whole vector of results because you are plotting them as they are generated, you don't have to. So it's a feature :)

zahachtah commented 7 years ago

here's why I prefer fortran before javascript:

I use the following:

var f = function(x, y) {
  return y;
};
data=[];
s.denseOutput = true;
out=s.solve(f, 0, [1], 1, s.grid(0.2, function(x,y) {
  data.push(y[0]);
}));

and data becomes a nice array one can pass to a graphing script,

BUT...change only a little:

var f = function(x, y) {
  return 0.1 * y;
};

and data returns only a single value.....and there's no logic why this happens.

Will have to sleep on this :-)

littleredcomputer commented 7 years ago
var f = function(x, y) {
  return [0.1 * y[0]];
}

y is always an array even when solving a one-dimensional system. The job of f is to return a vector of the same length as y.

zahachtah commented 7 years ago

thanks. working now

bramvandijk88 commented 3 years ago

I'm trying to use Browserify to make your package available within the browser too, but so far I have failed doing so. Could you maybe give an example as to how you would do this? I've gone all the way with your examples on github, but it really doesn't allow me to do what I want to do:

Load up your module Load up my own code Call Solver() from my own code in the browser

Thanks for the help :)

<html>
    <head><title>Some ODE integration </title></head>
    <!--<script type="module" src="./odex.js"></script>-->
            <script type="module" src="some_ode_thing.js"></script>
    <body>
    </body>
</html>

With some_ode_thing.js being:

import {Solver, Derivative} from './odex.js'

var s = new Solver(2);
var eq = function(x, y) {
    return [y[1], -y[0]];
};
// This is y'' = -y, y(0) = 1, y'(0) = 0, e.g. cos(x)
console.log(s.solve(eq, 0, [1, 0], Math.PI));
// We observe that at x = π, y is near -1 and y' is near 0,
// as expected.

As discussed above, this won't work in the browser, although running a nodejs version (with require) works perfectly fine:

user@computer$ node lotka_volterra.js 
{ y: [ -1.0000012130554767, 2.867958371527322e-7 ],
  outcome: 0,
  nStep: 8,
  xEnd: 3.141592653589793,
  nAccept: 8,
  nReject: 0,
  nEval: 114 }

I tried to use browserify, but didn't get really far.

[Resolved]

Alright, I found a way of doing it, i was just browserifying the wrong way. For future troubleshooters: here's what to do with the above code to run it in the browser:

browserify some_ode_thing.js -o out.js

And then run out.js within your html code.

littleredcomputer commented 3 years ago

I forgot how to use Browserify, but I recently set up something like this with webpack. I did it by following the instructions here https://webpack.js.org/guides/getting-started/.

My src/index.js has this in it:

import {Solver, Outcome} from 'odex'

let s = new Solver(6); s.denseOutput = true; s.solve( ...

My dist/index.html looks like this:

<!DOCTYPE html>

Getting Started

And here's package.json:

{ "name": "foo", "version": "1.0.0", "description": "", "private": true, "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "webpack": "^5.5.0", "webpack-cli": "^4.2.0" }, "dependencies": { "odex": "^2.0.4" } }

I just run "npx webpack" to build "main.js", which rewrites all the import/export stuff to work in the browser. HTH!

On Fri, Nov 20, 2020 at 1:59 AM Bram van Dijk notifications@github.com wrote:

I'm trying to use Browserify to make your package available within the browser too, but so far I have failed doing so. Could you maybe give an example as to how you would do this? I've gone all the way with your examples on github, but it really doesn't allow me to do what I want to do:

Load up your module Load up my own code Call Solver() from my own code in the browser

Thanks for the help :)

— You are receiving this because you modified the open/close state. Reply to this email directly, view it on GitHub https://github.com/littleredcomputer/odex-js/issues/1#issuecomment-731069695, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAB3Y7NIUGYVSNUHWQVZHXDSQY4WJANCNFSM4DMB2TZA .