Roots of a function: Difference between revisions
m
syntax highlighting fixup automation
m (→{{header|FreeBASIC}}: fixed indent+removed emply lines+added output template) |
Thundergnat (talk | contribs) m (syntax highlighting fixup automation) |
||
Line 13:
{{trans|Python}}
<
R x^3 - 3 * x^2 + 2 * x
Line 32:
sgn = value > 0
x += step</
{{out}}
Line 42:
=={{header|Ada}}==
<
procedure Roots_Of_Function is
Line 80:
X := X + Step;
end loop;
end Roots_Of_Function;</
=={{header|ALGOL 68}}==
Line 88:
{{wont work with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release [http://sourceforge.net/projects/algol68/files/algol68toc/algol68toc-1.8.8d/algol68toc-1.8-8d.fc9.i386.rpm/download 1.8-8d] - due to extensive use of FORMATted transput}}
Finding 3 roots using the secant method:
<
FORMAT dbl = $g(-long real width, long real width-6, -2)$;
Line 157:
)
OUT printf($"No third root found"l$); stop
ESAC</
Output:
<pre>1st root found at x = 9.1557112297752398099031e-1 (Approximately)
Line 165:
=={{header|ATS}}==
<syntaxhighlight lang="ats">
#include
"share/atspre_staload.hats"
Line 212:
main0 () =
findRoots (~1.0, 3.0, 0.001, lam (x) => x*x*x - 3.0*x*x + 2.0*x, 0, 0.0)
</syntaxhighlight>
=={{header|AutoHotkey}}==
Line 221:
[http://www.autohotkey.com/forum/viewtopic.php?t=44657&postdays=0&postorder=asc&start=139 discussion]
<
MsgBox % roots("poly", -1, 3, 0.1, 1.0e-5)
Line 256:
poly(x) {
Return ((x-3)*x+2)*x
}</
=={{header|Axiom}}==
Using a polynomial solver:
<
solve(expr,x)</
Output:
<
Type: List(Equation(Fraction(Polynomial(Integer))))</
Using the secant method in the interpreter:
<
secant(eq: Equation Expression Float, binding: SegmentBinding(Float)):Float ==
eps := 1.0e-30
Line 280:
abs(fx2)<eps => return x2
(x1, fx1, x2) := (x2, fx2, x2 - fx2 * (x2 - x1) / (fx2 - fx1))
error "Function not converging."</
The example can now be called using:
<
=={{header|BBC BASIC}}==
<
rangemin = -1
rangemax = 3
Line 311:
oldsign% = sign%
NEXT x
ENDPROC</
Output:
<pre>Root found near x = 2.29204307E-9
Line 321:
=== Secant Method ===
<
#include <stdio.h>
Line 380:
}
return 0;
}</
=== GNU Scientific Library ===
<
#include <stdio.h>
Line 400:
return 0;
}</
One can also use the GNU Scientific Library to find roots of functions. Compile with <pre>gcc roots.c -lgsl -lcblas -o roots</pre>
Line 408:
{{trans|C++}}
<
class Program
Line 441:
}
}
}</
{{trans|Java}}
<
class Program
Line 486:
PrintRoots(f, -1.0, 4, 0.002);
}
}</
===Brent's Method===
{{trans|C++}}
<
class Program
Line 597:
// end brents_fun
}
</syntaxhighlight>
=={{header|C++}}==
<
double f(double x)
Line 635:
sign = ( value > 0 );
}
}</
===Brent's Method===
Line 643:
The implementation is taken from the pseudo code on the wikipedia page for Brent's Method found here: https://en.wikipedia.org/wiki/Brent%27s_method.
<
#include <cmath>
#include <algorithm>
Line 741:
} // end brents_fun
</syntaxhighlight>
=={{header|Clojure}}==
{{trans|Haskell}}
<syntaxhighlight lang="clojure">
(defn findRoots [f start stop step eps]
(filter #(-> (f %) Math/abs (< eps)) (range start stop step)))
</syntaxhighlight>
<pre>
Line 759:
=={{header|CoffeeScript}}==
{{trans|Python}}
<
print_roots = (f, begin, end, step) ->
# Print approximate roots of f between x=begin and x=end,
Line 795:
f4 = (x) -> x*x - 2
print_roots f4, -2, 2, step
</syntaxhighlight>
output
<syntaxhighlight lang="text">
> coffee roots.coffee
-----
Line 813:
Root found near -1.4140625
Root found near 1.41796875
</syntaxhighlight>
=={{header|Common Lisp}}==
Line 821:
<code>find-roots</code> prints roots (and values near roots) and returns a list of root designators, each of which is either a number <code><var>n</var></code>, in which case <code>(zerop (funcall function <var>n</var>))</code> is true, or a <code>cons</code> whose <code>car</code> and <code>cdr</code> are such that the sign of function at car and cdr changes.
<
(let* ((roots '())
(value (funcall function start))
Line 837:
(format t "~&Root found near ~w." x)
(push (cons (- x step) x) roots)))
(setf plusp (plusp value)))))</
<pre>> (find-roots #'(lambda (x) (+ (* x x x) (* -3 x x) (* 2 x))) -1 3)
Line 848:
=={{header|D}}==
<
bool nearZero(T)(in T a, in T b = T.epsilon * 4) pure nothrow {
Line 919:
findRoot(&f, -1.0L, 3.0L, 0.001L).report(&f);
}</
{{out}}
<pre>Root found (tolerance = 0.0001):
Line 929:
=={{header|Dart}}==
{{trans|Scala}}
<
findRoots(Function(double) f, double start, double stop, double step, double epsilon) sync* {
Line 940:
// Vector(-9.381755897326649E-14, 0.9999999999998124, 1.9999999999997022)
print(findRoots(fn, -1.0, 3.0, 0.0001, 0.000000001));
}</
=={{header|Delphi}}==
Line 947:
=={{header|DWScript}}==
{{trans|C}}
<
function f(x : Float) : Float;
Line 997:
end;
x += fstep;
end;</
=={{header|EchoLisp}}==
We use the 'math' library, and define f(x) as the polynomial : x<sup>3</sup> -3x<sup>2</sup> +2x
<
(lib 'math.lib)
Lib: math.lib loaded.
Line 1,014:
(root f -1000 (- 2 epsilon)) → 1.385559938161431e-7 ;; 0
(root f epsilon (- 2 epsilon)) → 1.0000000002190812 ;; 1
</syntaxhighlight>
=={{header|Elixir}}==
{{trans|Ruby}}
<
def find_roots(f, range, step \\ 0.001) do
first .. last = range
Line 1,044:
f = fn x -> x*x*x - 3*x*x + 2*x end
RC.find_roots(f, -1..3)</
{{out}}
Line 1,054:
=={{header|Erlang}}==
<
-module(roots).
-export([main/0]).
Line 1,082:
while(X+Step, Step, Start, Stop, Value > 0,F)
end.
</syntaxhighlight>
{{out}}
<pre>Root found near 8.81239525796218e-16
Line 1,090:
=={{header|ERRE}}==
<syntaxhighlight lang="erre">
PROGRAM ROOTS_FUNCTION
Line 1,147:
END LOOP
END PROGRAM
</syntaxhighlight>
Note: Outputs are calculated in single precision.
{{out}}
Line 1,162:
=={{header|Fortran}}==
{{works with|Fortran|90 and later}}
<
IMPLICIT NONE
Line 1,187:
END DO
END PROGRAM ROOTS_OF_A_FUNCTION</
The following approach uses the [[wp:Secant_method|Secant Method]] to numerically find one root. Which root is found will depend on the start values x1 and x2 and if these are far from a root this method may not converge.
<
INTEGER :: i=1, limit=100
REAL(dp) :: d, e, f, x, x1, x2
Line 1,210:
x2 = x2 - d
i = i + 1
END DO</
=={{header|FreeBASIC}}==
Simple bisection method.
<
const iterations=20000000
Line 1,263:
next n
end if
sleep</
{{out}}
<pre>in range -20 to 20
Line 1,274:
=={{header|Go}}==
Secant method. No error checking.
<
import (
Line 1,310:
}
return 0, ""
}</
Output:
<pre>
Line 1,319:
=={{header|Haskell}}==
<
findRoots start stop step eps =
[x | x <- [start, start+step .. stop], abs (f x) < eps]</
Executed in GHCi:
<
[-9.381755897326649e-14,0.9999999999998124,1.9999999999997022]</
Or using package [http://hackage.haskell.org/package/hmatrix hmatrix] from HackageDB.
<
import Data.Complex
Line 1,334:
(-5.421010862427522e-20) :+ 0.0
2.000000000000001 :+ 0.0
0.9999999999999996 :+ 0.0</
No complex roots, so:
<
-5.421010862427522e-20
2.000000000000001
0.9999999999999996</
It is possible to solve the problem directly and elegantly using robust bisection method and Alternative type class.
<
data Root a = Exact a | Approximate a deriving (Show, Eq)
Line 1,362:
findRoots f [] = empty
findRoots f [x] = if f x == 0 then pure (Exact x) else empty
findRoots f (a:b:xs) = bisection f a b <|> findRoots f (b:xs)</
It is possible to use these functions with different Alternative functors: IO, Maybe or List:
Line 1,384:
=={{header|HicEst}}==
HicEst's [http://www.HicEst.com/SOLVE.htm SOLVE] function employs the Levenberg-Marquardt method:
<
1 DLG(NameEdit=x0, DNum=3)
Line 1,393:
WRITE(FIle='test.txt', LENgth=6, Name) x0, x, solution, chi2, iterations
GOTO 1</
<
x0=0.4; x=2E-162 solution=exact; chi2=0; iterations=1E4;
x0=0.45; x=1; solution=exact; chi2=79E-32 iterations=67;
Line 1,402:
x0=1.55; x=2; solution=exact; chi2=79E-32 iterations=55;
x0=1E10; x=2; solution=exact; chi2=18E-31 iterations=511;
x0=-1E10; x=0; solution=exact; chi2=0; iterations=1E4;</
=={{header|Icon}} and {{header|Unicon}}==
Line 1,408:
Works in both languages:
<
showRoots(f, -1.0, 4, 0.002)
end
Line 1,435:
procedure sign(x)
return (x<0, -1) | (x>0, 1) | 0
end</
Output:
Line 1,450:
J has builtin a root-finding operator, '''<tt>p.</tt>''', whose input is the coeffiecients of the polynomial (where the exponent of the indeterminate variable matches the index of the coefficient: 0 1 2 would be 0 + x + (2 times x squared)). Hence:
<
2 1 0</
We can determine whether the roots are exact or approximate by evaluating the polynomial at the candidate roots, and testing for zero:
<
1 1 1</
As you can see, <tt>p.</tt> is also the operator which evaluates polynomials. This is not a coincidence.
Line 1,462:
That said, we could also implement the technique used by most others here. Specifically: we can implement the function as a black box and check every 1 millionth of a unit between minus one and three, and we can test that result for exactness.
<
(#~ (=<./)@:|@blackbox) i.&.(1e6&*)&.(1&+) 3
0 1 2
0=blackbox 0 1 2
1 1 1</
Here, we see that each of the results (0, 1 and 2) are as accurate as we expect our computer arithmetic to be. (The = returns 1 where paired values are equal and 0 where they are not equal).
=={{header|Java}}==
<
public interface Function {
public double f(double x);
Line 1,508:
printRoots(poly, -1.0, 4, 0.002);
}
}</
Produces this output:
<pre>~2.616794878713638E-18
Line 1,518:
{{works with|SpiderMonkey|22}}
{{works with|Firefox|22}}
<
// This function notation is sorta new, but useful here
// Part of the EcmaScript 6 Draft
Line 1,549:
printRoots(poly, -1.0, 4, 0.002);
</syntaxhighlight>
=={{header|jq}}==
Line 1,562:
printRoots/3 emits an array of results, each of which is either a
number (representing an exact root within the limits of machine arithmetic) or a string consisting of "~" followed by an approximation to the root.
<
if . < 0 then -1 elif . > 0 then 1 else 0 end;
Line 1,584:
end )
| .[3] ;
</syntaxhighlight>
We present two examples, one where step is a power of 1/2, and one where it is not:
{{Out}}
<
[
Line 1,600:
"~1.0000000000000002",
"~1.9999999999999993"
]</
=={{header|Julia}}==
Line 1,606:
Assuming that one has the Roots package installed:
<
println(find_zero(x -> x^3 - 3x^2 + 2x, (-100, 100)))</
{{out}}
Line 1,616:
Without the Roots package, Newton's method may be defined in this manner:
<
##f: the function of x
##fp: the derivative of f
Line 1,637:
end
end
</syntaxhighlight>
Finding the roots of f(x) = x3 - 3x2 + 2x:
<syntaxhighlight lang="julia">
f(x) = x^3 - 3*x^2 + 2*x
fp(x) = 3*x^2-6*x+2
x_s, count = newton(f,fp,1.00)
</syntaxhighlight>
{{out}}
Line 1,653:
=={{header|Kotlin}}==
{{trans|C}}
<
typealias DoubleToDouble = (Double) -> Double
Line 1,702:
x += step
}
}</
{{out}}
Line 1,712:
=={{header|Lambdatalk}}==
<
1) defining the function:
{def func {lambda {:x} {+ {* 1 :x :x :x} {* -3 :x :x} {* 2 :x}}}}
Line 1,743:
- a root found at 540°
- a root found at 720°
</syntaxhighlight>
=={{header|Liberty BASIC}}==
<
' within a range of x values.
Line 1,791:
function f( x)
f =x^3 -3 *x^2 +2 *x
end function</
=={{header|Lua}}==
<
function f (x) return x^3 - 3*x^2 + 2*x end
Line 1,823:
for _, r in pairs(root(f, -1, 3, 10^-6)) do
print(string.format("%0.12f", r.val), r.err)
end</
{{out}}
<pre>Root (to 12DP) Max. Error
Line 1,831:
2.000000999934 1e-06</pre>
Note that the roots found are all near misses because fractional numbers that seem nice and 'round' in decimal (such as 10^-6) often have some rounding error when represented in binary. To increase the chances of finding exact integer roots, try using an integer start value with a step value that is a power of two.
<
print("Root (to 12DP)\tMax. Error\n")
for _, r in pairs(root(f, -1, 3, 2^-10)) do
print(string.format("%0.12f", r.val), r.err)
end</
{{out}}
<pre>Root (to 12DP) Max. Error
Line 1,845:
=={{header|Maple}}==
<
roots(f,x);</
outputs:
<
which means there are three roots. Each root is named as a pair where the first element is the value (0, 1, and 2), the second one the multiplicity (=1 for each means none of the three are degenerate).
Line 1,860:
===Solve===
This requires a full equation and will perform symbolic operations only:
<
Output
<pre> {{x->0},{x->1},{x->2}}</pre>
Line 1,866:
===NSolve===
This requires merely the polynomial and will perform numerical operations if needed:
<
Output
<pre> {{x->0.},{x->1.},{x->2.}}</pre>
Line 1,873:
===FindRoot===
This will numerically try to find one(!) local root from a given starting point:
<
Output
<pre> {x->0.}</pre>
From a different start point:
<
Output
<pre>{x->1.}</pre>
Line 1,884:
===FindInstance===
This finds a value (optionally out of a given domain) for the given variable (or a set of values for a set of given variables) that satisfy a given equality or inequality:
<
Output
<pre>{{x->0}}</pre>
Line 1,890:
===Reduce===
This will (symbolically) reduce a given expression to the simplest possible form, solving equations and performing substitutions in the process:
<
<pre> x==0||x==1||x==2</pre>
(note that this doesn't yield a "solution" but a different expression that expresses the same thing as the original)
=={{header|Maxima}}==
<
/* Number of roots in a real interval, using Sturm sequences */
Line 1,948:
[x=1.16154139999725193608791768724717407484314725802151429063617b0*%i + 3.41163901914009663684741869855524128445594290948999288901864b-1,
x=3.41163901914009663684741869855524128445594290948999288901864b-1 - 1.16154139999725193608791768724717407484314725802151429063617b0*%i,
x=-6.82327803828019327369483739711048256891188581897998577803729b-1]</
=={{header|Nim}}==
<
import strformat
Line 1,972:
sign = value > 0
x += step</
{{out}}
Line 1,983:
=={{header|Objeck}}==
{{trans|C++}}
<
bundle Default {
class Roots {
Line 2,018:
}
}
</syntaxhighlight>
=={{header|OCaml}}==
Line 2,024:
A general root finder using the False Position (Regula Falsi) method, which will find all simple roots given a small step size.
<
((u > 0.0) && (v < 0.0)) || ((u < 0.0) && (v > 0.0));;
Line 2,056:
x fx (if fx = 0.0 then "exact" else "approx") in
let f x = ((x -. 3.0)*.x +. 2.0)*.x in
List.iter showroot (search (-5.0) 5.0 0.1 f);;</
Output:
Line 2,071:
If the equation is a polynomial, we can put the coefficients in a vector and use ''roots'':
<
r = roots(a);
% let's print it
Line 2,081:
endif
printf(" exact)\n");
endfor</
Otherwise we can program our (simple) method:
{{trans|Python}}
<
y = x.^3 -3.*x.^2 + 2.*x;
endfunction
Line 2,106:
se = sign(v);
x = x + step;
endwhile</
=={{header|Oforth}}==
<
| x y lasty |
a f perform dup ->y ->lasty
Line 2,121:
] ;
: f(x) x 3 pow x sq 3 * - x 2 * + ; </
{{out}}
Line 2,137:
=={{header|ooRexx}}==
<
a*x**3+b*x**2+c*x+d =(x-x1)*(x-x2)*(x-x3)
*/
Line 2,191:
Else
Return xr
::requires 'rxmath' LIBRARY</
{{out}}
<pre>p=-3
Line 2,206:
=={{header|PARI/GP}}==
===Gourdon–Schönhage algorithm===<!-- X. Gourdon, "Algorithmique du théorème fondamental de l'algèbre" (1993). -->
<
===Newton's method===
This uses a modified version of the Newton–Raphson method.
<
===Brent's method===
<
solve(x=.5,1.5,x^3-3*x^2+2*x)
solve(x=1.5,2.5,x^3-3*x^2+2*x)</
===Factorization to linear factors===
<
my(f=factor(P),t);
for(i=1,#f[,1],
Line 2,236:
)
};
findRoots(x^3-3*x^2+2*x)</
===Factorization to quadratic factors===
Of course this process could be continued to degrees 3 and 4 with sufficient additional work.
<
my(f=factor(P),t);
for(i=1,#f[,1],
Line 2,285:
)
};
findRoots(x^3-3*x^2+2*x)</
=={{header|Pascal}}==
{{trans|Fortran}}
<
var
Line 2,353:
end;
end.
</syntaxhighlight>
Output:
<pre>
Line 2,365:
=={{header|Perl}}==
<
{
my $x = shift;
Line 2,401:
# Update our sign
$sign = ( $value > 0 );
}</
=={{header|Phix}}==
{{trans|CoffeeScript}}
<!--<
<span style="color: #008080;">procedure</span> <span style="color: #000000;">print_roots</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">f</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">atom</span> <span style="color: #000000;">start</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">stop</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">step</span><span style="color: #0000FF;">)</span>
<span style="color: #000080;font-style:italic;">--
Line 2,439:
<span style="color: #000000;">print_roots</span><span style="color: #0000FF;">(</span><span style="color: #000000;">f3</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">4</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">step</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">print_roots</span><span style="color: #0000FF;">(</span><span style="color: #000000;">f4</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">step</span><span style="color: #0000FF;">)</span>
<!--</
{{out}}
<pre>
Line 2,458:
=={{header|PicoLisp}}==
{{trans|Clojure}}
<
(filter
'((N) (> Eps (abs (F N))))
Line 2,468:
(findRoots
'((X) (+ (*/ X X X `(* 1.0 1.0)) (*/ -3 X X 1.0) (* 2 X)))
-1.0 3.0 0.0001 0.00000001 ) )</
Output:
<pre>-> ("0.000" "1.000" "2.000")</pre>
=={{header|PL/I}}==
<syntaxhighlight lang="pl/i">
f: procedure (x) returns (float (18));
declare x float (18);
Line 2,515:
end;
end locate_root;
</syntaxhighlight>
=={{header|PureBasic}}==
{{trans|C++}}
<
ProcedureReturn x*x*x-3*x*x+2*x
EndProcedure
Line 2,546:
EndProcedure
main()</
=={{header|Python}}==
{{trans|Perl}}
<
step = 0.001 # Smaller step values produce more accurate and precise results
Line 2,572:
sign = value > 0
x += step</
=={{header|R}}==
{{trans|Octave}}
<
findroots <- function(f, begin, end, tol = 1e-20, step = 0.001) {
Line 2,593:
}
findroots(f, -1, 3)</
=={{header|Racket}}==
<
#lang racket
Line 2,637:
(define tolerance (make-parameter 5e-16))
</syntaxhighlight>
Different root-finding methods
<
(define (secant f a b)
(let next ([x1 a] [y1 (f a)] [x2 b] [y2 (f b)] [n 50])
Line 2,659:
c
(or (divide a c) (divide c b)))))))
</syntaxhighlight>
Examples:
<
-> (find-root (λ (x) (- 2. (* x x))) 1 2)
1.414213562373095
Line 2,671:
-> (find-roots f -3 4 #:divisions 50)
'(2.4932181969624796e-33 1.0 2.0)
</syntaxhighlight>
In order to provide a comprehensive code the given solution does not optimize the number of function calls.
Line 2,677:
Simple memoization operator
<
(define (memoized f)
(define tbl (make-hash))
Line 2,685:
(hash-set! tbl x res)
res])))
</
To use memoization just call
<
-> (find-roots (memoized f) -3 4 #:divisions 50)
'(2.4932181969624796e-33 1.0 2.0)
</syntaxhighlight>
The profiling shows that memoization reduces the number of function calls
Line 2,699:
(formerly Perl 6)
Uses exact arithmetic.
<syntaxhighlight lang="raku"
my $start = -1;
Line 2,717:
NEXT $sign = $next;
}
}</
{{out}}
<pre>Root found at 0
Line 2,726:
Both of these REXX versions use the '''bisection method'''.
===function coded as a REXX function===
<
parse arg bot top inc . /*obtain optional arguments from the CL*/
if bot=='' | bot=="," then bot= -5 /*Not specified? Then use the default.*/
Line 2,743:
f: parse arg x; return x * (x * (x-3) +2) /*formula used ──► x^3 - 3x^2 + 2x */
/*with factoring ──► x{ x^2 -3x + 2 } */
/*more " ──► x{ x( x-3 ) + 2 } */</
{{out|output|text= when using the defaults for input:}}
<pre>
Line 2,753:
===function coded in-line===
This version is about '''40%''' faster than the 1<sup>st</sup> REXX version.
<
parse arg bot top inc . /*obtain optional arguments from the CL*/
if bot=='' | bot=="," then bot= -5 /*Not specified? Then use the default.*/
Line 2,766:
else if !\==$ then if !\==0 then say 'passed a root at' x/1
!= $ /*use the new sign for the next compare*/
end /*x*/ /*dividing by unity normalizes X [↑] */</
{{out|output|text= is the same as the 1<sup>st</sup> REXX version.}} <br><br>
=={{header|Ring}}==
<
load "stdlib.ring"
function = "return pow(x,3)-3*pow(x,2)+2*x"
Line 2,792:
oldsign = num
next
</syntaxhighlight>
Output:
<pre>
Line 2,806:
The script that finds a root of a scalar function <math>f(x) = x^3-3\,x^2 + 2\,x</math> of a scalar variable ''x''
using the bisection method on the interval -5 to 5 is,
<syntaxhighlight lang="rlab">
f = function(x)
{
Line 2,815:
>> findroot(f, , [-5,5])
0
</syntaxhighlight>
For a detailed description of the solver and its parameters interested reader is directed to the ''rlabplus'' manual.
Line 2,822:
{{trans|Python}}
<
x <=> 0
end
Line 2,840:
f = lambda { |x| x**3 - 3*x**2 + 2*x }
find_roots(f, -1..3)</
{{out}}
Line 2,851:
Or we could use Enumerable#inject, monkey patching and block:
<
def sign
self <=> 0
Line 2,869:
end
find_roots(-1..3) { |x| x**3 - 3*x**2 + 2*x }</
=={{header|Rust}}==
<
use roots::find_roots_cubic;
Line 2,881:
println!("Result : {:?}", roots);
}</
{{out}}
<pre>
Line 2,888:
Another without external crates:
<
use num::Float;
Line 2,921:
}
</syntaxhighlight>
{{out}}
<pre>
Line 2,931:
{{trans|Java}}
{{Out}}Best seen running in your browser either by [https://scalafiddle.io/sf/T63KUsH/0 (ES aka JavaScript, non JVM)] or [https://scastie.scala-lang.org/bh8von94Q1y0tInvEZ3cBQ Scastie (remote JVM)].
<
val poly = (x: Double) => x * x * x - 3 * x * x + 2 * x
Line 2,955:
printRoots(poly, -1.0, 4, 0.002)
}</
===Functional version (Recommended)===
<
def findRoots(fn: Double => Double, start: Double, stop: Double, step: Double, epsilon: Double) = {
for {
Line 2,968:
println(findRoots(fn, -1.0, 3.0, 0.0001, 0.000000001))
}</
{{out}}
Vector(-9.381755897326649E-14, 0.9999999999998124, 1.9999999999997022)
=={{header|Sidef}}==
<
x*x*x - 3*x*x + 2*x
}
Line 2,992:
}
sign = value>0
}</
{{out}}
<pre>Root found at 0
Line 3,000:
=={{header|Tcl}}==
This simple brute force iteration marks all results, with a leading "~", as approximate. This version always reports its results as approximate because of the general limits of computation using fixed-width floating-point numbers (i.e., IEEE double-precision floats).
<
set res {}
set lastsign [sgn [apply $lambda $start]]
Line 3,014:
proc sgn x {expr {($x>0) - ($x<0)}}
puts [froots {x {expr {$x**3 - 3*$x**2 + 2*$x}}}]</
Result and timing:
<pre>/Tcl $ time ./froots.tcl
Line 3,023:
sys 0m0.030s</pre>
A more elegant solution (and faster, because you can usually make the initial search coarser) is to use brute-force iteration and then refine with [[wp:Newton's method|Newton-Raphson]], but that requires the differential of the function with respect to the search variable.
<
set res {}
set lastsign [sgn [apply $f $start]]
Line 3,051:
puts [frootsNR \
{x {expr {$x**3 - 3*$x**2 + 2*$x}}} \
{x {expr {3*$x**2 - 6*$x + 2}}}]</
=={{header|TI-89 BASIC}}==
Line 3,062:
{{trans|Go}}
{{libheader|Wren-fmt}}
<
var secant = Fn.new { |f, x0, x1|
Line 3,096:
var example = Fn.new { |x| x*x*x - 3*x*x + 2*x }
findRoots.call(example, -0.5, 2.6, 1)</
{{out}}
Line 3,107:
=={{header|zkl}}==
{{trans|Haskell}}
<
[start..stop,step].filter('wrap(x){ f(x).closeTo(0.0,eps) })
}</
<
findRoots(f, -1.0, 3.0, 0.0001, 0.00000001).println();</
{{out}}
<pre>L(-9.38176e-14,1,2)</pre>
{{trans|C}}
<
reg e=1.0e-12;
Line 3,128:
if(f(xB).closeTo(0.0,e)) xB
else "Function is not converging near (%7.4f,%7.4f).".fmt(xA,xB);
}</
<
xs:=findRoots(f, -1.032, 3.0, step, 0.1);
xs.println(" --> ",xs.apply('wrap(x){ secant(f,x-step,x+step) }));</
{{out}}
<pre>L(-0.032,0.968,1.068,1.968) --> L(1.87115e-19,1,1,2)</pre>
|