A Bisection Based Solve Routine Return the real number x^p when x is positive and (-x)^p * m1_val when x is negative. Defined to avoid branch complications when considering fractional powers of negative numbers. > to_power:=proc(x,p,m1_val) > if x>= 0 then > evalf(x^p) > else > evalf((-x)^p)*m1_val > fi > end: > to_power(8,1/3,-1); to_power(-8,1/3,-1); 2.000000000 -2.000000000 > f:=x->to_power(x,1/3,-1)-3*to_power(x-2,1/3,-1); f := x -> to_power(x, 1/3, -1) - 3 to_power(x - 2, 1/3, -1) Returns a set of approximate zeroes of f on interval if f has opposite signs at the endpoints. Attempts to determine the zero to an error of at most min_width/2. The algorithm tries to keep the location of the zero between left and right. Assumes continuuity but does not assume differentiability. Returns an empty list when difficulty arises. Example: bisect_go(f,-5..5,.01); > bisect_go:=proc(f,interval,min_width) > local left,right,mid,solns,f_left, f_right, f_mid, found; > found:=false; > solns:={}; > left:=evalf(op(1,interval)); right:=evalf(op(2,interval)): > f_left:=f(left); f_right:=f(right); > if (f_left*f_right> 0) then > return {} > fi: > if (f_left=0) then > solns:= solns union {left}: > found:= true; > fi: > if (f_right=0) then > solns:= solns union {right}: > found:= true; > fi: > > #now f_left and f_right should be of opposite sign > while (((right-left)> min_width) and not found) do > mid:=(left+right)/2.0; > f_mid:=f(mid); > #print(left,mid,right,f_left,f_mid,f_right); > if (f_mid*f_left < 0) then > right:= mid; f_right:=f_mid; > else if (f_mid*f_right < 0) then > left:= mid; f_left:=f_mid; > else if (f_mid=0) then > solns:=solns union {mid}: > return solns; > fi: fi: fi: > od: > if ((right-left)<= min_width) then > return solns union {mid}; > else > return {} > fi: > #print(endgo); > end: > > bisect_go(f,0..1,.01); {} > val_set:=bisect_go(f,-5..5,.01); val_set := {2.080078125} > Digits:=10; Digits := 10 > val_set:=bisect_go(f,-5..5,.00000000000000000000000001); val_set := {2.076923077} > f(val_set[1]); 0. Return a list of solutions provided by bisect_go for a collection of subintervals of width at most coarse_width. > bisect_solve:= proc(f,interval,coarse_width,min_width) > local a,b,upper,solns,new_solns; > solns:={}; > #print(beforewhile); > a:=op(1,interval); > b:=op(2,interval); > while (a < b) > do upper:=a+coarse_width; > new_solns:=bisect_go(f,a..upper,min_width); > #print(new_solns); > solns:= solns union new_solns; > a:=upper: > od; > solns; > #print(afterwhile); > end: > > g:=x->tan(x); g := tan > bisect_solve(g,-10..10,1,.00001); beforewhile {-9.424781799} {} {-7.853981018} {-6.283180235} {} {-4.712394714} {-3.141593933} {} {-1.570793152} {} {} {1.570793152} {} {3.141593933} {4.712394714} {} {6.283180235} {7.853981018} {} {9.424781799} afterwhile > bisect_solve(f,-5..5,1,.01); beforewhile {} {} {} {} {} {} {} {2.070312500} {} {} afterwhile >