Skip to content

Instantly share code, notes, and snippets.

@wrayal
Forked from 140bytes/LICENSE.txt
Created June 3, 2011 10:39
Show Gist options
  • Save wrayal/1006157 to your computer and use it in GitHub Desktop.
Save wrayal/1006157 to your computer and use it in GitHub Desktop.
92 byte Interval Bisection

Interval bisection

This will find a root of a given function in a given interval.

How to use

Pass the function start and end points for the search, the function and tell it how accurate you want the result (in the form 2^-n). It will then bisect and find!

Caveats

This has the usual caveats of interval bisection methods (especially short ones lacking error checking...): if you pick an interval without roots, it can't find any! (hence why it returns the root together with the error :) ); if you pick a particularly pathological function, the error may be significant (think tanh(l*x) for l >> 1); if you pick an interval with multiple roots, you will get at most one, perhaps none of the roots.

function z(
a, //Left-hand end of the interval
b, //Right-hand end of the interval
d, //Depth so far (0 initially)
r, //Desired accuracy (2^-r)
g, //test function
c){ //placeholder
return //No messing about, let's just calculate the answer
d++<r? //Have we hit recursion depth?
g(a)/g(c=(a+b)/2)<0? //NO: Do we want the left hand or right hand interval?
z(a,c,d,r,g) //Left...
:z(c,b,d,r,g) //Right...(I suspect there's room for minimisation by absorbing the ternary operator into a single call to z()....
:[a,g(a)] //YES: return the answer together with the error
}
function z(a,b,d,r,g,c){return d++<r?g(a)/g(c=(a+b)/2)<0?z(a,c,d,r,g):z(c,b,d,r,g):[a,g(a)]}
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2011 YOUR_NAME_HERE <YOUR_URL_HERE>
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.
{
"name": "Bisection rootfinding",
"description": "Find roots of any function by interval bisection (usual caveats of IB's apply)",
"keywords": [
"interval bisection"
]
}
<!DOCTYPE html>
<title>Interval Bisecton</title>
<div>Expected value: <b>1.6180339455604553,-9.657452082478812e-8</b></div>
<div>Actual value: <b id="ret"></b></div>
<script>
function f(x){return x*x-x-1}; //The golden ratio
var myFunction = function z(a,b,d,r,g,c){return d++<r?g(a)/g(c=(a+b)/2)<0?z(a,c,d,r,g):z(c,b,d,r,g):[a,g(a)]}
var k=7;
document.getElementById( "ret" ).innerHTML = myFunction(1,2,0,Math.log(Math.pow(10,k))/Math.LN2,f); //The natty logarithmic calculation in here is to give "k" decimal places of accuracy
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment