Forum Moderators: coopster

Message Too Old, No Replies

Bisection method: What's wrong?

Cannot find all roots of function

         

DNnetz

10:28 pm on Apr 6, 2009 (gmt 0)

10+ Year Member



I coded a simple php script which should find roots of equations using the bisection method.

For the function ...
(5-x)*(25-x)-11*11
... the results are perfect. The script finds two of two roots and then exits when searching for a third one.

But when I want to find the roots of the function ...
(((x-10)*x+35)*x-50)*x+24
... nothing happens. The script gives no output and doesn't find any roots.

I know there must be a way to find the four roots because some other tools find them, too.

Could you please tell me what I did wrong? Thank you very much in advance!

PS: Here's the code:


<?php
error_reporting(E_ALL);
function in_gleichung_einsetzen($equationterm, $thevalue) {
$replacetext = '('.$thevalue.')';
$input_value = str_replace('x', $replacetext, $equationterm);
$berechnung_befehl = "\$result_value = ".$input_value.";";
eval($berechnung_befehl);
return $result_value;
}
function solve_equation($equationterm, $genaue_stellen=5) { // FINDS THE ROOTS
if ($equationterm[0] == '+') { $equationterm = substr($equationterm, 1); }
$nullstelle_in_intervall = FALSE;
$accuracy = pow(0.1, $genaue_stellen);
// CHOOSE INTERVAL START
$interval_schritt = 10;
$interval_a = -100;
$interval_b = -99;
while ($nullstelle_in_intervall === FALSE && $interval_schritt >= 0.3125) { // 10*(1/2)^5 = 0.3125
while ($nullstelle_in_intervall === FALSE && $interval_b < 100) {
$interval_a = $interval_b;
$interval_b = $interval_b+$interval_schritt;
$temp1 = in_gleichung_einsetzen($equationterm, $interval_a);
if ($temp1 === FALSE) { return FALSE; }
$temp2 = in_gleichung_einsetzen($equationterm, $interval_b);
if ($temp2 === FALSE) { return FALSE; }
if (($temp1*$temp2) < 0) { $nullstelle_in_intervall = TRUE; }
if (abs($temp1) < $accuracy) { return $interval_a; }
if (abs($temp2) < $accuracy) { return $interval_b; }
}
$interval_schritt = $interval_schritt*0.5;
}
// CHOOSE INTERVAL END
echo '<p>interval ['.$interval_a.', '.$interval_b.'] ';
$thevalue1 = in_gleichung_einsetzen($equationterm, $interval_a);
$thevalue2 = in_gleichung_einsetzen($equationterm, $interval_b);
echo '&rarr; ['.$thevalue1.', '.$thevalue2.'] ';
echo 'for equation '.$equationterm.'</p>';
$function_value_of_c = 100;
$interval_c = 0;
$steps_done = 0; // EXIT AFTER x STEPS TO AVOID A TIMEOUT
while (abs($function_value_of_c) > $accuracy && $steps_done < 500) {
if ($interval_a == $interval_b) {
echo '<li style="color:red">left value a and right value b of the interval are the same</li>';
exit;
}
$interval_c = ($interval_a+$interval_b)/2;
$function_value_of_c = in_gleichung_einsetzen($equationterm, $interval_c);
$function_value_of_a = in_gleichung_einsetzen($equationterm, $interval_a);
echo '<li>approximation '.$interval_c.'&rarr;'.$function_value_of_c.' for equation '.$equationterm.'</li>';
if ($function_value_of_c !== FALSE) {
// CHANGE INTERVAL START
echo '<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;interval ['.$interval_a.', '.$interval_b.']';
if (($function_value_of_a*$function_value_of_c) > 0) {
$interval_a = $interval_c;
}
else {
$interval_b = $interval_c;
}
echo ' becomes ['.$interval_a.', '.$interval_b.']</li>';
// CHANGE INTERVAL END
}
$steps_done++;
}
if ($steps_done < 500) {
root_found($interval_c, $equationterm);
}
else {
root_found(FALSE, $equationterm);
}
}
function root_found($nullstelle, $equationterm) {
if ($nullstelle === FALSE) {
echo '<p>no root found for equation '.$equationterm.'</p>';
}
else {
echo '<p>root '.$nullstelle.' found for equation '.$equationterm.'</p>';
$equationterm = '('.$equationterm.')/(x-('.$nullstelle.'))';
echo '<p>#########################################################<br />#########################################################</p>';
solve_equation($equationterm);
}
}
$equationterm = '(5-x)*(25-x)-11*11';
if (isset($_GET['t'])) {
$equationterm = '(((x-10)*x+35)*x-50)*x+24';
}
solve_equation($equationterm);
?>

[edited by: coopster at 6:07 pm (utc) on April 7, 2009]
[edit reason] no personal urls please TOS [webmasterworld.com] [/edit]

DNnetz

10:51 am on Apr 8, 2009 (gmt 0)

10+ Year Member



Sorry for this double post but the thread was pending approval and so it didn't get any attention here.
Do you have any idea for the cause of that problem? Could it be that the function isn't continuous?

[edited by: DNnetz at 10:51 am (utc) on April 8, 2009]

coopster

12:35 pm on Apr 8, 2009 (gmt 0)

WebmasterWorld Administrator 10+ Year Member



I had a quick glance but it would take me a more considerable amount of time to analyze the code, DNnetz. I notice that the wiki page for bisection method [en.wikipedia.org] has some pseudo code that may be easier to adapt if your function is not performing as intended.

DNnetz

9:11 pm on Apr 8, 2009 (gmt 0)

10+ Year Member



Yes, I've already seen that pseudo code on the wiki page and I compared it with my code: I implemented it correctly so I don't have any idea for why the function can't solve the one equation.
Nobody here who could help me?

coopster

11:56 am on Apr 9, 2009 (gmt 0)

WebmasterWorld Administrator 10+ Year Member



Everybody here volunteers time they can but most all have day jobs to which they must attend.

If you have implemented the code properly and are not receiving any runtime errors, merely unexpected output, then it seems you have a logic issue. The path to resolution is breaking it down, step-by-step. Debugging time takes time.