Roots of a function: Difference between revisions
Content added Content deleted
m (→{{header|FreeBASIC}}: fixed indent+removed emply lines+added output template) |
Thundergnat (talk | contribs) m (syntax highlighting fixup automation) |
||
Line 13: | Line 13: | ||
{{trans|Python}} |
{{trans|Python}} |
||
< |
<syntaxhighlight lang="11l">F f(x) |
||
R x^3 - 3 * x^2 + 2 * x |
R x^3 - 3 * x^2 + 2 * x |
||
Line 32: | Line 32: | ||
sgn = value > 0 |
sgn = value > 0 |
||
x += step</ |
x += step</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 42: | Line 42: | ||
=={{header|Ada}}== |
=={{header|Ada}}== |
||
< |
<syntaxhighlight lang="ada">with Ada.Text_Io; use Ada.Text_Io; |
||
procedure Roots_Of_Function is |
procedure Roots_Of_Function is |
||
Line 80: | Line 80: | ||
X := X + Step; |
X := X + Step; |
||
end loop; |
end loop; |
||
end Roots_Of_Function;</ |
end Roots_Of_Function;</syntaxhighlight> |
||
=={{header|ALGOL 68}}== |
=={{header|ALGOL 68}}== |
||
Line 88: | 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}} |
{{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: |
Finding 3 roots using the secant method: |
||
< |
<syntaxhighlight lang="algol68">MODE DBL = LONG REAL; |
||
FORMAT dbl = $g(-long real width, long real width-6, -2)$; |
FORMAT dbl = $g(-long real width, long real width-6, -2)$; |
||
Line 157: | Line 157: | ||
) |
) |
||
OUT printf($"No third root found"l$); stop |
OUT printf($"No third root found"l$); stop |
||
ESAC</ |
ESAC</syntaxhighlight> |
||
Output: |
Output: |
||
<pre>1st root found at x = 9.1557112297752398099031e-1 (Approximately) |
<pre>1st root found at x = 9.1557112297752398099031e-1 (Approximately) |
||
Line 165: | Line 165: | ||
=={{header|ATS}}== |
=={{header|ATS}}== |
||
<syntaxhighlight lang="ats"> |
|||
<lang ATS> |
|||
#include |
#include |
||
"share/atspre_staload.hats" |
"share/atspre_staload.hats" |
||
Line 212: | Line 212: | ||
main0 () = |
main0 () = |
||
findRoots (~1.0, 3.0, 0.001, lam (x) => x*x*x - 3.0*x*x + 2.0*x, 0, 0.0) |
findRoots (~1.0, 3.0, 0.001, lam (x) => x*x*x - 3.0*x*x + 2.0*x, 0, 0.0) |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|AutoHotkey}}== |
=={{header|AutoHotkey}}== |
||
Line 221: | Line 221: | ||
[http://www.autohotkey.com/forum/viewtopic.php?t=44657&postdays=0&postorder=asc&start=139 discussion] |
[http://www.autohotkey.com/forum/viewtopic.php?t=44657&postdays=0&postorder=asc&start=139 discussion] |
||
< |
<syntaxhighlight lang="autohotkey">MsgBox % roots("poly", -0.99, 2, 0.1, 1.0e-5) |
||
MsgBox % roots("poly", -1, 3, 0.1, 1.0e-5) |
MsgBox % roots("poly", -1, 3, 0.1, 1.0e-5) |
||
Line 256: | Line 256: | ||
poly(x) { |
poly(x) { |
||
Return ((x-3)*x+2)*x |
Return ((x-3)*x+2)*x |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Axiom}}== |
=={{header|Axiom}}== |
||
Using a polynomial solver: |
Using a polynomial solver: |
||
< |
<syntaxhighlight lang="axiom">expr := x^3-3*x^2+2*x |
||
solve(expr,x)</ |
solve(expr,x)</syntaxhighlight> |
||
Output: |
Output: |
||
< |
<syntaxhighlight lang="axiom"> (1) [x= 2,x= 1,x= 0] |
||
Type: List(Equation(Fraction(Polynomial(Integer))))</ |
Type: List(Equation(Fraction(Polynomial(Integer))))</syntaxhighlight> |
||
Using the secant method in the interpreter: |
Using the secant method in the interpreter: |
||
< |
<syntaxhighlight lang="axiom">digits(30) |
||
secant(eq: Equation Expression Float, binding: SegmentBinding(Float)):Float == |
secant(eq: Equation Expression Float, binding: SegmentBinding(Float)):Float == |
||
eps := 1.0e-30 |
eps := 1.0e-30 |
||
Line 280: | Line 280: | ||
abs(fx2)<eps => return x2 |
abs(fx2)<eps => return x2 |
||
(x1, fx1, x2) := (x2, fx2, x2 - fx2 * (x2 - x1) / (fx2 - fx1)) |
(x1, fx1, x2) := (x2, fx2, x2 - fx2 * (x2 - x1) / (fx2 - fx1)) |
||
error "Function not converging."</ |
error "Function not converging."</syntaxhighlight> |
||
The example can now be called using: |
The example can now be called using: |
||
< |
<syntaxhighlight lang="axiom">secant(expr=0,x=-0.5..0.5)</syntaxhighlight> |
||
=={{header|BBC BASIC}}== |
=={{header|BBC BASIC}}== |
||
< |
<syntaxhighlight lang="bbcbasic"> function$ = "x^3-3*x^2+2*x" |
||
rangemin = -1 |
rangemin = -1 |
||
rangemax = 3 |
rangemax = 3 |
||
Line 311: | Line 311: | ||
oldsign% = sign% |
oldsign% = sign% |
||
NEXT x |
NEXT x |
||
ENDPROC</ |
ENDPROC</syntaxhighlight> |
||
Output: |
Output: |
||
<pre>Root found near x = 2.29204307E-9 |
<pre>Root found near x = 2.29204307E-9 |
||
Line 321: | Line 321: | ||
=== Secant Method === |
=== Secant Method === |
||
< |
<syntaxhighlight lang="c">#include <math.h> |
||
#include <stdio.h> |
#include <stdio.h> |
||
Line 380: | Line 380: | ||
} |
} |
||
return 0; |
return 0; |
||
}</ |
}</syntaxhighlight> |
||
=== GNU Scientific Library === |
=== GNU Scientific Library === |
||
< |
<syntaxhighlight lang="c">#include <gsl/gsl_poly.h> |
||
#include <stdio.h> |
#include <stdio.h> |
||
Line 400: | Line 400: | ||
return 0; |
return 0; |
||
}</ |
}</syntaxhighlight> |
||
One can also use the GNU Scientific Library to find roots of functions. Compile with <pre>gcc roots.c -lgsl -lcblas -o roots</pre> |
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: | Line 408: | ||
{{trans|C++}} |
{{trans|C++}} |
||
< |
<syntaxhighlight lang="csharp">using System; |
||
class Program |
class Program |
||
Line 441: | Line 441: | ||
} |
} |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
{{trans|Java}} |
{{trans|Java}} |
||
< |
<syntaxhighlight lang="csharp">using System; |
||
class Program |
class Program |
||
Line 486: | Line 486: | ||
PrintRoots(f, -1.0, 4, 0.002); |
PrintRoots(f, -1.0, 4, 0.002); |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
===Brent's Method=== |
===Brent's Method=== |
||
{{trans|C++}} |
{{trans|C++}} |
||
< |
<syntaxhighlight lang="csharp">using System; |
||
class Program |
class Program |
||
Line 597: | Line 597: | ||
// end brents_fun |
// end brents_fun |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|C++}}== |
=={{header|C++}}== |
||
< |
<syntaxhighlight lang="cpp">#include <iostream> |
||
double f(double x) |
double f(double x) |
||
Line 635: | Line 635: | ||
sign = ( value > 0 ); |
sign = ( value > 0 ); |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
===Brent's Method=== |
===Brent's Method=== |
||
Line 643: | 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. |
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. |
||
< |
<syntaxhighlight lang="cpp">#include <iostream> |
||
#include <cmath> |
#include <cmath> |
||
#include <algorithm> |
#include <algorithm> |
||
Line 741: | Line 741: | ||
} // end brents_fun |
} // end brents_fun |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Clojure}}== |
=={{header|Clojure}}== |
||
{{trans|Haskell}} |
{{trans|Haskell}} |
||
<syntaxhighlight lang="clojure"> |
|||
<lang Clojure> |
|||
(defn findRoots [f start stop step eps] |
(defn findRoots [f start stop step eps] |
||
(filter #(-> (f %) Math/abs (< eps)) (range start stop step))) |
(filter #(-> (f %) Math/abs (< eps)) (range start stop step))) |
||
</syntaxhighlight> |
|||
</lang> |
|||
<pre> |
<pre> |
||
Line 759: | Line 759: | ||
=={{header|CoffeeScript}}== |
=={{header|CoffeeScript}}== |
||
{{trans|Python}} |
{{trans|Python}} |
||
< |
<syntaxhighlight lang="coffeescript"> |
||
print_roots = (f, begin, end, step) -> |
print_roots = (f, begin, end, step) -> |
||
# Print approximate roots of f between x=begin and x=end, |
# Print approximate roots of f between x=begin and x=end, |
||
Line 795: | Line 795: | ||
f4 = (x) -> x*x - 2 |
f4 = (x) -> x*x - 2 |
||
print_roots f4, -2, 2, step |
print_roots f4, -2, 2, step |
||
</syntaxhighlight> |
|||
</lang> |
|||
output |
output |
||
<lang> |
<syntaxhighlight lang="text"> |
||
> coffee roots.coffee |
> coffee roots.coffee |
||
----- |
----- |
||
Line 813: | Line 813: | ||
Root found near -1.4140625 |
Root found near -1.4140625 |
||
Root found near 1.41796875 |
Root found near 1.41796875 |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Common Lisp}}== |
=={{header|Common Lisp}}== |
||
Line 821: | 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. |
<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. |
||
< |
<syntaxhighlight lang="lisp">(defun find-roots (function start end &optional (step 0.0001)) |
||
(let* ((roots '()) |
(let* ((roots '()) |
||
(value (funcall function start)) |
(value (funcall function start)) |
||
Line 837: | Line 837: | ||
(format t "~&Root found near ~w." x) |
(format t "~&Root found near ~w." x) |
||
(push (cons (- x step) x) roots))) |
(push (cons (- x step) x) roots))) |
||
(setf plusp (plusp value)))))</ |
(setf plusp (plusp value)))))</syntaxhighlight> |
||
<pre>> (find-roots #'(lambda (x) (+ (* x x x) (* -3 x x) (* 2 x))) -1 3) |
<pre>> (find-roots #'(lambda (x) (+ (* x x x) (* -3 x x) (* 2 x))) -1 3) |
||
Line 848: | Line 848: | ||
=={{header|D}}== |
=={{header|D}}== |
||
< |
<syntaxhighlight lang="d">import std.stdio, std.math, std.algorithm; |
||
bool nearZero(T)(in T a, in T b = T.epsilon * 4) pure nothrow { |
bool nearZero(T)(in T a, in T b = T.epsilon * 4) pure nothrow { |
||
Line 919: | Line 919: | ||
findRoot(&f, -1.0L, 3.0L, 0.001L).report(&f); |
findRoot(&f, -1.0L, 3.0L, 0.001L).report(&f); |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>Root found (tolerance = 0.0001): |
<pre>Root found (tolerance = 0.0001): |
||
Line 929: | Line 929: | ||
=={{header|Dart}}== |
=={{header|Dart}}== |
||
{{trans|Scala}} |
{{trans|Scala}} |
||
< |
<syntaxhighlight lang="dart">double fn(double x) => x * x * x - 3 * x * x + 2 * x; |
||
findRoots(Function(double) f, double start, double stop, double step, double epsilon) sync* { |
findRoots(Function(double) f, double start, double stop, double step, double epsilon) sync* { |
||
Line 940: | Line 940: | ||
// Vector(-9.381755897326649E-14, 0.9999999999998124, 1.9999999999997022) |
// Vector(-9.381755897326649E-14, 0.9999999999998124, 1.9999999999997022) |
||
print(findRoots(fn, -1.0, 3.0, 0.0001, 0.000000001)); |
print(findRoots(fn, -1.0, 3.0, 0.0001, 0.000000001)); |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Delphi}}== |
=={{header|Delphi}}== |
||
Line 947: | Line 947: | ||
=={{header|DWScript}}== |
=={{header|DWScript}}== |
||
{{trans|C}} |
{{trans|C}} |
||
< |
<syntaxhighlight lang="delphi">type TFunc = function (x : Float) : Float; |
||
function f(x : Float) : Float; |
function f(x : Float) : Float; |
||
Line 997: | Line 997: | ||
end; |
end; |
||
x += fstep; |
x += fstep; |
||
end;</ |
end;</syntaxhighlight> |
||
=={{header|EchoLisp}}== |
=={{header|EchoLisp}}== |
||
We use the 'math' library, and define f(x) as the polynomial : x<sup>3</sup> -3x<sup>2</sup> +2x |
We use the 'math' library, and define f(x) as the polynomial : x<sup>3</sup> -3x<sup>2</sup> +2x |
||
< |
<syntaxhighlight lang="lisp"> |
||
(lib 'math.lib) |
(lib 'math.lib) |
||
Lib: math.lib loaded. |
Lib: math.lib loaded. |
||
Line 1,014: | Line 1,014: | ||
(root f -1000 (- 2 epsilon)) → 1.385559938161431e-7 ;; 0 |
(root f -1000 (- 2 epsilon)) → 1.385559938161431e-7 ;; 0 |
||
(root f epsilon (- 2 epsilon)) → 1.0000000002190812 ;; 1 |
(root f epsilon (- 2 epsilon)) → 1.0000000002190812 ;; 1 |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Elixir}}== |
=={{header|Elixir}}== |
||
{{trans|Ruby}} |
{{trans|Ruby}} |
||
< |
<syntaxhighlight lang="elixir">defmodule RC do |
||
def find_roots(f, range, step \\ 0.001) do |
def find_roots(f, range, step \\ 0.001) do |
||
first .. last = range |
first .. last = range |
||
Line 1,044: | Line 1,044: | ||
f = fn x -> x*x*x - 3*x*x + 2*x end |
f = fn x -> x*x*x - 3*x*x + 2*x end |
||
RC.find_roots(f, -1..3)</ |
RC.find_roots(f, -1..3)</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,054: | Line 1,054: | ||
=={{header|Erlang}}== |
=={{header|Erlang}}== |
||
< |
<syntaxhighlight lang="erlang">% Implemented by Arjun Sunel |
||
-module(roots). |
-module(roots). |
||
-export([main/0]). |
-export([main/0]). |
||
Line 1,082: | Line 1,082: | ||
while(X+Step, Step, Start, Stop, Value > 0,F) |
while(X+Step, Step, Start, Stop, Value > 0,F) |
||
end. |
end. |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre>Root found near 8.81239525796218e-16 |
<pre>Root found near 8.81239525796218e-16 |
||
Line 1,090: | Line 1,090: | ||
=={{header|ERRE}}== |
=={{header|ERRE}}== |
||
<syntaxhighlight lang="erre"> |
|||
<lang ERRE> |
|||
PROGRAM ROOTS_FUNCTION |
PROGRAM ROOTS_FUNCTION |
||
Line 1,147: | Line 1,147: | ||
END LOOP |
END LOOP |
||
END PROGRAM |
END PROGRAM |
||
</syntaxhighlight> |
|||
</lang> |
|||
Note: Outputs are calculated in single precision. |
Note: Outputs are calculated in single precision. |
||
{{out}} |
{{out}} |
||
Line 1,162: | Line 1,162: | ||
=={{header|Fortran}}== |
=={{header|Fortran}}== |
||
{{works with|Fortran|90 and later}} |
{{works with|Fortran|90 and later}} |
||
< |
<syntaxhighlight lang="fortran">PROGRAM ROOTS_OF_A_FUNCTION |
||
IMPLICIT NONE |
IMPLICIT NONE |
||
Line 1,187: | Line 1,187: | ||
END DO |
END DO |
||
END PROGRAM ROOTS_OF_A_FUNCTION</ |
END PROGRAM ROOTS_OF_A_FUNCTION</syntaxhighlight> |
||
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. |
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. |
||
< |
<syntaxhighlight lang="fortran">INTEGER, PARAMETER :: dp = SELECTED_REAL_KIND(15) |
||
INTEGER :: i=1, limit=100 |
INTEGER :: i=1, limit=100 |
||
REAL(dp) :: d, e, f, x, x1, x2 |
REAL(dp) :: d, e, f, x, x1, x2 |
||
Line 1,210: | Line 1,210: | ||
x2 = x2 - d |
x2 = x2 - d |
||
i = i + 1 |
i = i + 1 |
||
END DO</ |
END DO</syntaxhighlight> |
||
=={{header|FreeBASIC}}== |
=={{header|FreeBASIC}}== |
||
Simple bisection method. |
Simple bisection method. |
||
< |
<syntaxhighlight lang="freebasic">#Include "crt.bi" |
||
const iterations=20000000 |
const iterations=20000000 |
||
Line 1,263: | Line 1,263: | ||
next n |
next n |
||
end if |
end if |
||
sleep</ |
sleep</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>in range -20 to 20 |
<pre>in range -20 to 20 |
||
Line 1,274: | Line 1,274: | ||
=={{header|Go}}== |
=={{header|Go}}== |
||
Secant method. No error checking. |
Secant method. No error checking. |
||
< |
<syntaxhighlight lang="go">package main |
||
import ( |
import ( |
||
Line 1,310: | Line 1,310: | ||
} |
} |
||
return 0, "" |
return 0, "" |
||
}</ |
}</syntaxhighlight> |
||
Output: |
Output: |
||
<pre> |
<pre> |
||
Line 1,319: | Line 1,319: | ||
=={{header|Haskell}}== |
=={{header|Haskell}}== |
||
< |
<syntaxhighlight lang="haskell">f x = x^3-3*x^2+2*x |
||
findRoots start stop step eps = |
findRoots start stop step eps = |
||
[x | x <- [start, start+step .. stop], abs (f x) < eps]</ |
[x | x <- [start, start+step .. stop], abs (f x) < eps]</syntaxhighlight> |
||
Executed in GHCi: |
Executed in GHCi: |
||
< |
<syntaxhighlight lang="haskell">*Main> findRoots (-1.0) 3.0 0.0001 0.000000001 |
||
[-9.381755897326649e-14,0.9999999999998124,1.9999999999997022]</ |
[-9.381755897326649e-14,0.9999999999998124,1.9999999999997022]</syntaxhighlight> |
||
Or using package [http://hackage.haskell.org/package/hmatrix hmatrix] from HackageDB. |
Or using package [http://hackage.haskell.org/package/hmatrix hmatrix] from HackageDB. |
||
< |
<syntaxhighlight lang="haskell">import Numeric.GSL.Polynomials |
||
import Data.Complex |
import Data.Complex |
||
Line 1,334: | Line 1,334: | ||
(-5.421010862427522e-20) :+ 0.0 |
(-5.421010862427522e-20) :+ 0.0 |
||
2.000000000000001 :+ 0.0 |
2.000000000000001 :+ 0.0 |
||
0.9999999999999996 :+ 0.0</ |
0.9999999999999996 :+ 0.0</syntaxhighlight> |
||
No complex roots, so: |
No complex roots, so: |
||
< |
<syntaxhighlight lang="haskell">*Main> mapM_ (print.realPart) $ polySolve [0,2,-3,1] |
||
-5.421010862427522e-20 |
-5.421010862427522e-20 |
||
2.000000000000001 |
2.000000000000001 |
||
0.9999999999999996</ |
0.9999999999999996</syntaxhighlight> |
||
It is possible to solve the problem directly and elegantly using robust bisection method and Alternative type class. |
It is possible to solve the problem directly and elegantly using robust bisection method and Alternative type class. |
||
< |
<syntaxhighlight lang="haskell">import Control.Applicative |
||
data Root a = Exact a | Approximate a deriving (Show, Eq) |
data Root a = Exact a | Approximate a deriving (Show, Eq) |
||
Line 1,362: | Line 1,362: | ||
findRoots f [] = empty |
findRoots f [] = empty |
||
findRoots f [x] = if f x == 0 then pure (Exact x) else 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)</ |
findRoots f (a:b:xs) = bisection f a b <|> findRoots f (b:xs)</syntaxhighlight> |
||
It is possible to use these functions with different Alternative functors: IO, Maybe or List: |
It is possible to use these functions with different Alternative functors: IO, Maybe or List: |
||
Line 1,384: | Line 1,384: | ||
=={{header|HicEst}}== |
=={{header|HicEst}}== |
||
HicEst's [http://www.HicEst.com/SOLVE.htm SOLVE] function employs the Levenberg-Marquardt method: |
HicEst's [http://www.HicEst.com/SOLVE.htm SOLVE] function employs the Levenberg-Marquardt method: |
||
< |
<syntaxhighlight lang="hicest">OPEN(FIle='test.txt') |
||
1 DLG(NameEdit=x0, DNum=3) |
1 DLG(NameEdit=x0, DNum=3) |
||
Line 1,393: | Line 1,393: | ||
WRITE(FIle='test.txt', LENgth=6, Name) x0, x, solution, chi2, iterations |
WRITE(FIle='test.txt', LENgth=6, Name) x0, x, solution, chi2, iterations |
||
GOTO 1</ |
GOTO 1</syntaxhighlight> |
||
< |
<syntaxhighlight lang="hicest">x0=0.5; x=1; solution=exact; chi2=79E-32 iterations=65; |
||
x0=0.4; x=2E-162 solution=exact; chi2=0; iterations=1E4; |
x0=0.4; x=2E-162 solution=exact; chi2=0; iterations=1E4; |
||
x0=0.45; x=1; solution=exact; chi2=79E-32 iterations=67; |
x0=0.45; x=1; solution=exact; chi2=79E-32 iterations=67; |
||
Line 1,402: | Line 1,402: | ||
x0=1.55; x=2; solution=exact; chi2=79E-32 iterations=55; |
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=2; solution=exact; chi2=18E-31 iterations=511; |
||
x0=-1E10; x=0; solution=exact; chi2=0; iterations=1E4;</ |
x0=-1E10; x=0; solution=exact; chi2=0; iterations=1E4;</syntaxhighlight> |
||
=={{header|Icon}} and {{header|Unicon}}== |
=={{header|Icon}} and {{header|Unicon}}== |
||
Line 1,408: | Line 1,408: | ||
Works in both languages: |
Works in both languages: |
||
< |
<syntaxhighlight lang="unicon">procedure main() |
||
showRoots(f, -1.0, 4, 0.002) |
showRoots(f, -1.0, 4, 0.002) |
||
end |
end |
||
Line 1,435: | Line 1,435: | ||
procedure sign(x) |
procedure sign(x) |
||
return (x<0, -1) | (x>0, 1) | 0 |
return (x<0, -1) | (x>0, 1) | 0 |
||
end</ |
end</syntaxhighlight> |
||
Output: |
Output: |
||
Line 1,450: | 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: |
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: |
||
< |
<syntaxhighlight lang="j"> 1{::p. 0 2 _3 1 |
||
2 1 0</ |
2 1 0</syntaxhighlight> |
||
We can determine whether the roots are exact or approximate by evaluating the polynomial at the candidate roots, and testing for zero: |
We can determine whether the roots are exact or approximate by evaluating the polynomial at the candidate roots, and testing for zero: |
||
< |
<syntaxhighlight lang="j"> (0=]p.1{::p.) 0 2 _3 1 |
||
1 1 1</ |
1 1 1</syntaxhighlight> |
||
As you can see, <tt>p.</tt> is also the operator which evaluates polynomials. This is not a coincidence. |
As you can see, <tt>p.</tt> is also the operator which evaluates polynomials. This is not a coincidence. |
||
Line 1,462: | 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. |
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. |
||
< |
<syntaxhighlight lang="j"> blackbox=: 0 2 _3 1&p. |
||
(#~ (=<./)@:|@blackbox) i.&.(1e6&*)&.(1&+) 3 |
(#~ (=<./)@:|@blackbox) i.&.(1e6&*)&.(1&+) 3 |
||
0 1 2 |
0 1 2 |
||
0=blackbox 0 1 2 |
0=blackbox 0 1 2 |
||
1 1 1</ |
1 1 1</syntaxhighlight> |
||
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). |
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}}== |
=={{header|Java}}== |
||
< |
<syntaxhighlight lang="java">public class Roots { |
||
public interface Function { |
public interface Function { |
||
public double f(double x); |
public double f(double x); |
||
Line 1,508: | Line 1,508: | ||
printRoots(poly, -1.0, 4, 0.002); |
printRoots(poly, -1.0, 4, 0.002); |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
Produces this output: |
Produces this output: |
||
<pre>~2.616794878713638E-18 |
<pre>~2.616794878713638E-18 |
||
Line 1,518: | Line 1,518: | ||
{{works with|SpiderMonkey|22}} |
{{works with|SpiderMonkey|22}} |
||
{{works with|Firefox|22}} |
{{works with|Firefox|22}} |
||
< |
<syntaxhighlight lang="javascript"> |
||
// This function notation is sorta new, but useful here |
// This function notation is sorta new, but useful here |
||
// Part of the EcmaScript 6 Draft |
// Part of the EcmaScript 6 Draft |
||
Line 1,549: | Line 1,549: | ||
printRoots(poly, -1.0, 4, 0.002); |
printRoots(poly, -1.0, 4, 0.002); |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|jq}}== |
=={{header|jq}}== |
||
Line 1,562: | Line 1,562: | ||
printRoots/3 emits an array of results, each of which is either a |
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. |
number (representing an exact root within the limits of machine arithmetic) or a string consisting of "~" followed by an approximation to the root. |
||
< |
<syntaxhighlight lang="jq">def sign: |
||
if . < 0 then -1 elif . > 0 then 1 else 0 end; |
if . < 0 then -1 elif . > 0 then 1 else 0 end; |
||
Line 1,584: | Line 1,584: | ||
end ) |
end ) |
||
| .[3] ; |
| .[3] ; |
||
</syntaxhighlight> |
|||
</lang> |
|||
We present two examples, one where step is a power of 1/2, and one where it is not: |
We present two examples, one where step is a power of 1/2, and one where it is not: |
||
{{Out}} |
{{Out}} |
||
< |
<syntaxhighlight lang="jq">printRoots( .*.*. - 3*.*. + 2*.; -1.0; 4; 1/256) |
||
[ |
[ |
||
Line 1,600: | Line 1,600: | ||
"~1.0000000000000002", |
"~1.0000000000000002", |
||
"~1.9999999999999993" |
"~1.9999999999999993" |
||
]</ |
]</syntaxhighlight> |
||
=={{header|Julia}}== |
=={{header|Julia}}== |
||
Line 1,606: | Line 1,606: | ||
Assuming that one has the Roots package installed: |
Assuming that one has the Roots package installed: |
||
< |
<syntaxhighlight lang="julia">using Roots |
||
println(find_zero(x -> x^3 - 3x^2 + 2x, (-100, 100)))</ |
println(find_zero(x -> x^3 - 3x^2 + 2x, (-100, 100)))</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,616: | Line 1,616: | ||
Without the Roots package, Newton's method may be defined in this manner: |
Without the Roots package, Newton's method may be defined in this manner: |
||
< |
<syntaxhighlight lang="julia">function newton(f, fp, x::Float64,tol=1e-14::Float64,maxsteps=100::Int64) |
||
##f: the function of x |
##f: the function of x |
||
##fp: the derivative of f |
##fp: the derivative of f |
||
Line 1,637: | Line 1,637: | ||
end |
end |
||
end |
end |
||
</syntaxhighlight> |
|||
</lang> |
|||
Finding the roots of f(x) = x3 - 3x2 + 2x: |
Finding the roots of f(x) = x3 - 3x2 + 2x: |
||
<syntaxhighlight lang="julia"> |
|||
<lang Julia> |
|||
f(x) = x^3 - 3*x^2 + 2*x |
f(x) = x^3 - 3*x^2 + 2*x |
||
fp(x) = 3*x^2-6*x+2 |
fp(x) = 3*x^2-6*x+2 |
||
x_s, count = newton(f,fp,1.00) |
x_s, count = newton(f,fp,1.00) |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
Line 1,653: | Line 1,653: | ||
=={{header|Kotlin}}== |
=={{header|Kotlin}}== |
||
{{trans|C}} |
{{trans|C}} |
||
< |
<syntaxhighlight lang="scala">// version 1.1.2 |
||
typealias DoubleToDouble = (Double) -> Double |
typealias DoubleToDouble = (Double) -> Double |
||
Line 1,702: | Line 1,702: | ||
x += step |
x += step |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,712: | Line 1,712: | ||
=={{header|Lambdatalk}}== |
=={{header|Lambdatalk}}== |
||
< |
<syntaxhighlight lang="scheme"> |
||
1) defining the function: |
1) defining the function: |
||
{def func {lambda {:x} {+ {* 1 :x :x :x} {* -3 :x :x} {* 2 :x}}}} |
{def func {lambda {:x} {+ {* 1 :x :x :x} {* -3 :x :x} {* 2 :x}}}} |
||
Line 1,743: | Line 1,743: | ||
- a root found at 540° |
- a root found at 540° |
||
- a root found at 720° |
- a root found at 720° |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Liberty BASIC}}== |
=={{header|Liberty BASIC}}== |
||
< |
<syntaxhighlight lang="lb">' Finds and output the roots of a given function f(x), |
||
' within a range of x values. |
' within a range of x values. |
||
Line 1,791: | Line 1,791: | ||
function f( x) |
function f( x) |
||
f =x^3 -3 *x^2 +2 *x |
f =x^3 -3 *x^2 +2 *x |
||
end function</ |
end function</syntaxhighlight> |
||
=={{header|Lua}}== |
=={{header|Lua}}== |
||
< |
<syntaxhighlight lang="lua">-- Function to have roots found |
||
function f (x) return x^3 - 3*x^2 + 2*x end |
function f (x) return x^3 - 3*x^2 + 2*x end |
||
Line 1,823: | Line 1,823: | ||
for _, r in pairs(root(f, -1, 3, 10^-6)) do |
for _, r in pairs(root(f, -1, 3, 10^-6)) do |
||
print(string.format("%0.12f", r.val), r.err) |
print(string.format("%0.12f", r.val), r.err) |
||
end</ |
end</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>Root (to 12DP) Max. Error |
<pre>Root (to 12DP) Max. Error |
||
Line 1,831: | Line 1,831: | ||
2.000000999934 1e-06</pre> |
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. |
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. |
||
< |
<syntaxhighlight lang="lua">-- Main procedure |
||
print("Root (to 12DP)\tMax. Error\n") |
print("Root (to 12DP)\tMax. Error\n") |
||
for _, r in pairs(root(f, -1, 3, 2^-10)) do |
for _, r in pairs(root(f, -1, 3, 2^-10)) do |
||
print(string.format("%0.12f", r.val), r.err) |
print(string.format("%0.12f", r.val), r.err) |
||
end</ |
end</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>Root (to 12DP) Max. Error |
<pre>Root (to 12DP) Max. Error |
||
Line 1,845: | Line 1,845: | ||
=={{header|Maple}}== |
=={{header|Maple}}== |
||
< |
<syntaxhighlight lang="maple">f := x^3-3*x^2+2*x; |
||
roots(f,x);</ |
roots(f,x);</syntaxhighlight> |
||
outputs: |
outputs: |
||
< |
<syntaxhighlight lang="maple">[[0, 1], [1, 1], [2, 1]]</syntaxhighlight> |
||
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). |
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: | Line 1,860: | ||
===Solve=== |
===Solve=== |
||
This requires a full equation and will perform symbolic operations only: |
This requires a full equation and will perform symbolic operations only: |
||
< |
<syntaxhighlight lang="mathematica">Solve[x^3-3*x^2+2*x==0,x]</syntaxhighlight> |
||
Output |
Output |
||
<pre> {{x->0},{x->1},{x->2}}</pre> |
<pre> {{x->0},{x->1},{x->2}}</pre> |
||
Line 1,866: | Line 1,866: | ||
===NSolve=== |
===NSolve=== |
||
This requires merely the polynomial and will perform numerical operations if needed: |
This requires merely the polynomial and will perform numerical operations if needed: |
||
< |
<syntaxhighlight lang="mathematica"> NSolve[x^3 - 3*x^2 + 2*x , x]</syntaxhighlight> |
||
Output |
Output |
||
<pre> {{x->0.},{x->1.},{x->2.}}</pre> |
<pre> {{x->0.},{x->1.},{x->2.}}</pre> |
||
Line 1,873: | Line 1,873: | ||
===FindRoot=== |
===FindRoot=== |
||
This will numerically try to find one(!) local root from a given starting point: |
This will numerically try to find one(!) local root from a given starting point: |
||
< |
<syntaxhighlight lang="mathematica">FindRoot[x^3 - 3*x^2 + 2*x , {x, 1.5}]</syntaxhighlight> |
||
Output |
Output |
||
<pre> {x->0.}</pre> |
<pre> {x->0.}</pre> |
||
From a different start point: |
From a different start point: |
||
< |
<syntaxhighlight lang="mathematica">FindRoot[x^3 - 3*x^2 + 2*x , {x, 1.1}]</syntaxhighlight> |
||
Output |
Output |
||
<pre>{x->1.}</pre> |
<pre>{x->1.}</pre> |
||
Line 1,884: | Line 1,884: | ||
===FindInstance=== |
===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: |
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: |
||
< |
<syntaxhighlight lang="mathematica"> FindInstance[x^3 - 3*x^2 + 2*x == 0, x]</syntaxhighlight> |
||
Output |
Output |
||
<pre>{{x->0}}</pre> |
<pre>{{x->0}}</pre> |
||
Line 1,890: | Line 1,890: | ||
===Reduce=== |
===Reduce=== |
||
This will (symbolically) reduce a given expression to the simplest possible form, solving equations and performing substitutions in the process: |
This will (symbolically) reduce a given expression to the simplest possible form, solving equations and performing substitutions in the process: |
||
< |
<syntaxhighlight lang="mathematica">Reduce[x^3 - 3*x^2 + 2*x == 0, x]</syntaxhighlight> |
||
<pre> x==0||x==1||x==2</pre> |
<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) |
(note that this doesn't yield a "solution" but a different expression that expresses the same thing as the original) |
||
=={{header|Maxima}}== |
=={{header|Maxima}}== |
||
< |
<syntaxhighlight lang="maxima">e: x^3 - 3*x^2 + 2*x$ |
||
/* Number of roots in a real interval, using Sturm sequences */ |
/* Number of roots in a real interval, using Sturm sequences */ |
||
Line 1,948: | Line 1,948: | ||
[x=1.16154139999725193608791768724717407484314725802151429063617b0*%i + 3.41163901914009663684741869855524128445594290948999288901864b-1, |
[x=1.16154139999725193608791768724717407484314725802151429063617b0*%i + 3.41163901914009663684741869855524128445594290948999288901864b-1, |
||
x=3.41163901914009663684741869855524128445594290948999288901864b-1 - 1.16154139999725193608791768724717407484314725802151429063617b0*%i, |
x=3.41163901914009663684741869855524128445594290948999288901864b-1 - 1.16154139999725193608791768724717407484314725802151429063617b0*%i, |
||
x=-6.82327803828019327369483739711048256891188581897998577803729b-1]</ |
x=-6.82327803828019327369483739711048256891188581897998577803729b-1]</syntaxhighlight> |
||
=={{header|Nim}}== |
=={{header|Nim}}== |
||
< |
<syntaxhighlight lang="nim">import math |
||
import strformat |
import strformat |
||
Line 1,972: | Line 1,972: | ||
sign = value > 0 |
sign = value > 0 |
||
x += step</ |
x += step</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,983: | Line 1,983: | ||
=={{header|Objeck}}== |
=={{header|Objeck}}== |
||
{{trans|C++}} |
{{trans|C++}} |
||
< |
<syntaxhighlight lang="objeck"> |
||
bundle Default { |
bundle Default { |
||
class Roots { |
class Roots { |
||
Line 2,018: | Line 2,018: | ||
} |
} |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|OCaml}}== |
=={{header|OCaml}}== |
||
Line 2,024: | 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. |
A general root finder using the False Position (Regula Falsi) method, which will find all simple roots given a small step size. |
||
< |
<syntaxhighlight lang="ocaml">let bracket u v = |
||
((u > 0.0) && (v < 0.0)) || ((u < 0.0) && (v > 0.0));; |
((u > 0.0) && (v < 0.0)) || ((u < 0.0) && (v > 0.0));; |
||
Line 2,056: | Line 2,056: | ||
x fx (if fx = 0.0 then "exact" else "approx") in |
x fx (if fx = 0.0 then "exact" else "approx") in |
||
let f x = ((x -. 3.0)*.x +. 2.0)*.x in |
let f x = ((x -. 3.0)*.x +. 2.0)*.x in |
||
List.iter showroot (search (-5.0) 5.0 0.1 f);;</ |
List.iter showroot (search (-5.0) 5.0 0.1 f);;</syntaxhighlight> |
||
Output: |
Output: |
||
Line 2,071: | Line 2,071: | ||
If the equation is a polynomial, we can put the coefficients in a vector and use ''roots'': |
If the equation is a polynomial, we can put the coefficients in a vector and use ''roots'': |
||
< |
<syntaxhighlight lang="octave">a = [ 1, -3, 2, 0 ]; |
||
r = roots(a); |
r = roots(a); |
||
% let's print it |
% let's print it |
||
Line 2,081: | Line 2,081: | ||
endif |
endif |
||
printf(" exact)\n"); |
printf(" exact)\n"); |
||
endfor</ |
endfor</syntaxhighlight> |
||
Otherwise we can program our (simple) method: |
Otherwise we can program our (simple) method: |
||
{{trans|Python}} |
{{trans|Python}} |
||
< |
<syntaxhighlight lang="octave">function y = f(x) |
||
y = x.^3 -3.*x.^2 + 2.*x; |
y = x.^3 -3.*x.^2 + 2.*x; |
||
endfunction |
endfunction |
||
Line 2,106: | Line 2,106: | ||
se = sign(v); |
se = sign(v); |
||
x = x + step; |
x = x + step; |
||
endwhile</ |
endwhile</syntaxhighlight> |
||
=={{header|Oforth}}== |
=={{header|Oforth}}== |
||
< |
<syntaxhighlight lang="oforth">: findRoots(f, a, b, st) |
||
| x y lasty | |
| x y lasty | |
||
a f perform dup ->y ->lasty |
a f perform dup ->y ->lasty |
||
Line 2,121: | Line 2,121: | ||
] ; |
] ; |
||
: f(x) x 3 pow x sq 3 * - x 2 * + ; </ |
: f(x) x 3 pow x sq 3 * - x 2 * + ; </syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 2,137: | Line 2,137: | ||
=={{header|ooRexx}}== |
=={{header|ooRexx}}== |
||
< |
<syntaxhighlight lang="oorexx">/* REXX program to solve a cubic polynom equation |
||
a*x**3+b*x**2+c*x+d =(x-x1)*(x-x2)*(x-x3) |
a*x**3+b*x**2+c*x+d =(x-x1)*(x-x2)*(x-x3) |
||
*/ |
*/ |
||
Line 2,191: | Line 2,191: | ||
Else |
Else |
||
Return xr |
Return xr |
||
::requires 'rxmath' LIBRARY</ |
::requires 'rxmath' LIBRARY</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>p=-3 |
<pre>p=-3 |
||
Line 2,206: | Line 2,206: | ||
=={{header|PARI/GP}}== |
=={{header|PARI/GP}}== |
||
===Gourdon–Schönhage algorithm===<!-- X. Gourdon, "Algorithmique du théorème fondamental de l'algèbre" (1993). --> |
===Gourdon–Schönhage algorithm===<!-- X. Gourdon, "Algorithmique du théorème fondamental de l'algèbre" (1993). --> |
||
< |
<syntaxhighlight lang="parigp">polroots(x^3-3*x^2+2*x)</syntaxhighlight> |
||
===Newton's method=== |
===Newton's method=== |
||
This uses a modified version of the Newton–Raphson method. |
This uses a modified version of the Newton–Raphson method. |
||
< |
<syntaxhighlight lang="parigp">polroots(x^3-3*x^2+2*x,1)</syntaxhighlight> |
||
===Brent's method=== |
===Brent's method=== |
||
< |
<syntaxhighlight lang="parigp">solve(x=-.5,.5,x^3-3*x^2+2*x) |
||
solve(x=.5,1.5,x^3-3*x^2+2*x) |
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)</ |
solve(x=1.5,2.5,x^3-3*x^2+2*x)</syntaxhighlight> |
||
===Factorization to linear factors=== |
===Factorization to linear factors=== |
||
< |
<syntaxhighlight lang="parigp">findRoots(P)={ |
||
my(f=factor(P),t); |
my(f=factor(P),t); |
||
for(i=1,#f[,1], |
for(i=1,#f[,1], |
||
Line 2,236: | Line 2,236: | ||
) |
) |
||
}; |
}; |
||
findRoots(x^3-3*x^2+2*x)</ |
findRoots(x^3-3*x^2+2*x)</syntaxhighlight> |
||
===Factorization to quadratic factors=== |
===Factorization to quadratic factors=== |
||
Of course this process could be continued to degrees 3 and 4 with sufficient additional work. |
Of course this process could be continued to degrees 3 and 4 with sufficient additional work. |
||
< |
<syntaxhighlight lang="parigp">findRoots(P)={ |
||
my(f=factor(P),t); |
my(f=factor(P),t); |
||
for(i=1,#f[,1], |
for(i=1,#f[,1], |
||
Line 2,285: | Line 2,285: | ||
) |
) |
||
}; |
}; |
||
findRoots(x^3-3*x^2+2*x)</ |
findRoots(x^3-3*x^2+2*x)</syntaxhighlight> |
||
=={{header|Pascal}}== |
=={{header|Pascal}}== |
||
{{trans|Fortran}} |
{{trans|Fortran}} |
||
< |
<syntaxhighlight lang="pascal">Program RootsFunction; |
||
var |
var |
||
Line 2,353: | Line 2,353: | ||
end; |
end; |
||
end. |
end. |
||
</syntaxhighlight> |
|||
</lang> |
|||
Output: |
Output: |
||
<pre> |
<pre> |
||
Line 2,365: | Line 2,365: | ||
=={{header|Perl}}== |
=={{header|Perl}}== |
||
< |
<syntaxhighlight lang="perl">sub f |
||
{ |
{ |
||
my $x = shift; |
my $x = shift; |
||
Line 2,401: | Line 2,401: | ||
# Update our sign |
# Update our sign |
||
$sign = ( $value > 0 ); |
$sign = ( $value > 0 ); |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Phix}}== |
=={{header|Phix}}== |
||
{{trans|CoffeeScript}} |
{{trans|CoffeeScript}} |
||
<!--< |
<!--<syntaxhighlight lang="phix">(phixonline)--> |
||
<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: #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;">-- |
<span style="color: #000080;font-style:italic;">-- |
||
Line 2,439: | 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;">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> |
<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> |
||
<!--</ |
<!--</syntaxhighlight>--> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 2,458: | Line 2,458: | ||
=={{header|PicoLisp}}== |
=={{header|PicoLisp}}== |
||
{{trans|Clojure}} |
{{trans|Clojure}} |
||
< |
<syntaxhighlight lang="picolisp">(de findRoots (F Start Stop Step Eps) |
||
(filter |
(filter |
||
'((N) (> Eps (abs (F N)))) |
'((N) (> Eps (abs (F N)))) |
||
Line 2,468: | Line 2,468: | ||
(findRoots |
(findRoots |
||
'((X) (+ (*/ X X X `(* 1.0 1.0)) (*/ -3 X X 1.0) (* 2 X))) |
'((X) (+ (*/ X X X `(* 1.0 1.0)) (*/ -3 X X 1.0) (* 2 X))) |
||
-1.0 3.0 0.0001 0.00000001 ) )</ |
-1.0 3.0 0.0001 0.00000001 ) )</syntaxhighlight> |
||
Output: |
Output: |
||
<pre>-> ("0.000" "1.000" "2.000")</pre> |
<pre>-> ("0.000" "1.000" "2.000")</pre> |
||
=={{header|PL/I}}== |
=={{header|PL/I}}== |
||
<syntaxhighlight lang="pl/i"> |
|||
<lang PL/I> |
|||
f: procedure (x) returns (float (18)); |
f: procedure (x) returns (float (18)); |
||
declare x float (18); |
declare x float (18); |
||
Line 2,515: | Line 2,515: | ||
end; |
end; |
||
end locate_root; |
end locate_root; |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|PureBasic}}== |
=={{header|PureBasic}}== |
||
{{trans|C++}} |
{{trans|C++}} |
||
< |
<syntaxhighlight lang="purebasic">Procedure.d f(x.d) |
||
ProcedureReturn x*x*x-3*x*x+2*x |
ProcedureReturn x*x*x-3*x*x+2*x |
||
EndProcedure |
EndProcedure |
||
Line 2,546: | Line 2,546: | ||
EndProcedure |
EndProcedure |
||
main()</ |
main()</syntaxhighlight> |
||
=={{header|Python}}== |
=={{header|Python}}== |
||
{{trans|Perl}} |
{{trans|Perl}} |
||
< |
<syntaxhighlight lang="python">f = lambda x: x * x * x - 3 * x * x + 2 * x |
||
step = 0.001 # Smaller step values produce more accurate and precise results |
step = 0.001 # Smaller step values produce more accurate and precise results |
||
Line 2,572: | Line 2,572: | ||
sign = value > 0 |
sign = value > 0 |
||
x += step</ |
x += step</syntaxhighlight> |
||
=={{header|R}}== |
=={{header|R}}== |
||
{{trans|Octave}} |
{{trans|Octave}} |
||
< |
<syntaxhighlight lang="r">f <- function(x) x^3 -3*x^2 + 2*x |
||
findroots <- function(f, begin, end, tol = 1e-20, step = 0.001) { |
findroots <- function(f, begin, end, tol = 1e-20, step = 0.001) { |
||
Line 2,593: | Line 2,593: | ||
} |
} |
||
findroots(f, -1, 3)</ |
findroots(f, -1, 3)</syntaxhighlight> |
||
=={{header|Racket}}== |
=={{header|Racket}}== |
||
< |
<syntaxhighlight lang="racket"> |
||
#lang racket |
#lang racket |
||
Line 2,637: | Line 2,637: | ||
(define tolerance (make-parameter 5e-16)) |
(define tolerance (make-parameter 5e-16)) |
||
</syntaxhighlight> |
|||
</lang> |
|||
Different root-finding methods |
Different root-finding methods |
||
< |
<syntaxhighlight lang="racket"> |
||
(define (secant f a b) |
(define (secant f a b) |
||
(let next ([x1 a] [y1 (f a)] [x2 b] [y2 (f b)] [n 50]) |
(let next ([x1 a] [y1 (f a)] [x2 b] [y2 (f b)] [n 50]) |
||
Line 2,659: | Line 2,659: | ||
c |
c |
||
(or (divide a c) (divide c b))))))) |
(or (divide a c) (divide c b))))))) |
||
</syntaxhighlight> |
|||
</lang> |
|||
Examples: |
Examples: |
||
< |
<syntaxhighlight lang="racket"> |
||
-> (find-root (λ (x) (- 2. (* x x))) 1 2) |
-> (find-root (λ (x) (- 2. (* x x))) 1 2) |
||
1.414213562373095 |
1.414213562373095 |
||
Line 2,671: | Line 2,671: | ||
-> (find-roots f -3 4 #:divisions 50) |
-> (find-roots f -3 4 #:divisions 50) |
||
'(2.4932181969624796e-33 1.0 2.0) |
'(2.4932181969624796e-33 1.0 2.0) |
||
</syntaxhighlight> |
|||
</lang> |
|||
In order to provide a comprehensive code the given solution does not optimize the number of function calls. |
In order to provide a comprehensive code the given solution does not optimize the number of function calls. |
||
Line 2,677: | Line 2,677: | ||
Simple memoization operator |
Simple memoization operator |
||
< |
<syntaxhighlight lang="racket"> |
||
(define (memoized f) |
(define (memoized f) |
||
(define tbl (make-hash)) |
(define tbl (make-hash)) |
||
Line 2,685: | Line 2,685: | ||
(hash-set! tbl x res) |
(hash-set! tbl x res) |
||
res]))) |
res]))) |
||
</ |
</syntaxhighlight> |
||
To use memoization just call |
To use memoization just call |
||
< |
<syntaxhighlight lang="racket"> |
||
-> (find-roots (memoized f) -3 4 #:divisions 50) |
-> (find-roots (memoized f) -3 4 #:divisions 50) |
||
'(2.4932181969624796e-33 1.0 2.0) |
'(2.4932181969624796e-33 1.0 2.0) |
||
</syntaxhighlight> |
|||
</lang> |
|||
The profiling shows that memoization reduces the number of function calls |
The profiling shows that memoization reduces the number of function calls |
||
Line 2,699: | Line 2,699: | ||
(formerly Perl 6) |
(formerly Perl 6) |
||
Uses exact arithmetic. |
Uses exact arithmetic. |
||
<lang |
<syntaxhighlight lang="raku" line>sub f(\x) { x³ - 3*x² + 2*x } |
||
my $start = -1; |
my $start = -1; |
||
Line 2,717: | Line 2,717: | ||
NEXT $sign = $next; |
NEXT $sign = $next; |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>Root found at 0 |
<pre>Root found at 0 |
||
Line 2,726: | Line 2,726: | ||
Both of these REXX versions use the '''bisection method'''. |
Both of these REXX versions use the '''bisection method'''. |
||
===function coded as a REXX function=== |
===function coded as a REXX function=== |
||
< |
<syntaxhighlight lang="rexx">/*REXX program finds the roots of a specific function: x^3 - 3*x^2 + 2*x via bisection*/ |
||
parse arg bot top inc . /*obtain optional arguments from the CL*/ |
parse arg bot top inc . /*obtain optional arguments from the CL*/ |
||
if bot=='' | bot=="," then bot= -5 /*Not specified? Then use the default.*/ |
if bot=='' | bot=="," then bot= -5 /*Not specified? Then use the default.*/ |
||
Line 2,743: | Line 2,743: | ||
f: parse arg x; return x * (x * (x-3) +2) /*formula used ──► x^3 - 3x^2 + 2x */ |
f: parse arg x; return x * (x * (x-3) +2) /*formula used ──► x^3 - 3x^2 + 2x */ |
||
/*with factoring ──► x{ x^2 -3x + 2 } */ |
/*with factoring ──► x{ x^2 -3x + 2 } */ |
||
/*more " ──► x{ x( x-3 ) + 2 } */</ |
/*more " ──► x{ x( x-3 ) + 2 } */</syntaxhighlight> |
||
{{out|output|text= when using the defaults for input:}} |
{{out|output|text= when using the defaults for input:}} |
||
<pre> |
<pre> |
||
Line 2,753: | Line 2,753: | ||
===function coded in-line=== |
===function coded in-line=== |
||
This version is about '''40%''' faster than the 1<sup>st</sup> REXX version. |
This version is about '''40%''' faster than the 1<sup>st</sup> REXX version. |
||
< |
<syntaxhighlight lang="rexx">/*REXX program finds the roots of a specific function: x^3 - 3*x^2 + 2*x via bisection*/ |
||
parse arg bot top inc . /*obtain optional arguments from the CL*/ |
parse arg bot top inc . /*obtain optional arguments from the CL*/ |
||
if bot=='' | bot=="," then bot= -5 /*Not specified? Then use the default.*/ |
if bot=='' | bot=="," then bot= -5 /*Not specified? Then use the default.*/ |
||
Line 2,766: | Line 2,766: | ||
else if !\==$ then if !\==0 then say 'passed a root at' x/1 |
else if !\==$ then if !\==0 then say 'passed a root at' x/1 |
||
!= $ /*use the new sign for the next compare*/ |
!= $ /*use the new sign for the next compare*/ |
||
end /*x*/ /*dividing by unity normalizes X [↑] */</ |
end /*x*/ /*dividing by unity normalizes X [↑] */</syntaxhighlight> |
||
{{out|output|text= is the same as the 1<sup>st</sup> REXX version.}} <br><br> |
{{out|output|text= is the same as the 1<sup>st</sup> REXX version.}} <br><br> |
||
=={{header|Ring}}== |
=={{header|Ring}}== |
||
< |
<syntaxhighlight lang="ring"> |
||
load "stdlib.ring" |
load "stdlib.ring" |
||
function = "return pow(x,3)-3*pow(x,2)+2*x" |
function = "return pow(x,3)-3*pow(x,2)+2*x" |
||
Line 2,792: | Line 2,792: | ||
oldsign = num |
oldsign = num |
||
next |
next |
||
</syntaxhighlight> |
|||
</lang> |
|||
Output: |
Output: |
||
<pre> |
<pre> |
||
Line 2,806: | 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'' |
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, |
using the bisection method on the interval -5 to 5 is, |
||
<syntaxhighlight lang="rlab"> |
|||
<lang RLaB> |
|||
f = function(x) |
f = function(x) |
||
{ |
{ |
||
Line 2,815: | Line 2,815: | ||
>> findroot(f, , [-5,5]) |
>> findroot(f, , [-5,5]) |
||
0 |
0 |
||
</syntaxhighlight> |
|||
</lang> |
|||
For a detailed description of the solver and its parameters interested reader is directed to the ''rlabplus'' manual. |
For a detailed description of the solver and its parameters interested reader is directed to the ''rlabplus'' manual. |
||
Line 2,822: | Line 2,822: | ||
{{trans|Python}} |
{{trans|Python}} |
||
< |
<syntaxhighlight lang="ruby">def sign(x) |
||
x <=> 0 |
x <=> 0 |
||
end |
end |
||
Line 2,840: | Line 2,840: | ||
f = lambda { |x| x**3 - 3*x**2 + 2*x } |
f = lambda { |x| x**3 - 3*x**2 + 2*x } |
||
find_roots(f, -1..3)</ |
find_roots(f, -1..3)</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 2,851: | Line 2,851: | ||
Or we could use Enumerable#inject, monkey patching and block: |
Or we could use Enumerable#inject, monkey patching and block: |
||
< |
<syntaxhighlight lang="ruby">class Numeric |
||
def sign |
def sign |
||
self <=> 0 |
self <=> 0 |
||
Line 2,869: | Line 2,869: | ||
end |
end |
||
find_roots(-1..3) { |x| x**3 - 3*x**2 + 2*x }</ |
find_roots(-1..3) { |x| x**3 - 3*x**2 + 2*x }</syntaxhighlight> |
||
=={{header|Rust}}== |
=={{header|Rust}}== |
||
< |
<syntaxhighlight lang="rust">// 202100315 Rust programming solution |
||
use roots::find_roots_cubic; |
use roots::find_roots_cubic; |
||
Line 2,881: | Line 2,881: | ||
println!("Result : {:?}", roots); |
println!("Result : {:?}", roots); |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 2,888: | Line 2,888: | ||
Another without external crates: |
Another without external crates: |
||
< |
<syntaxhighlight lang="rust"> |
||
use num::Float; |
use num::Float; |
||
Line 2,921: | Line 2,921: | ||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 2,931: | Line 2,931: | ||
{{trans|Java}} |
{{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)]. |
{{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)]. |
||
< |
<syntaxhighlight lang="scala">object Roots extends App { |
||
val poly = (x: Double) => x * x * x - 3 * x * x + 2 * x |
val poly = (x: Double) => x * x * x - 3 * x * x + 2 * x |
||
Line 2,955: | Line 2,955: | ||
printRoots(poly, -1.0, 4, 0.002) |
printRoots(poly, -1.0, 4, 0.002) |
||
}</ |
}</syntaxhighlight> |
||
===Functional version (Recommended)=== |
===Functional version (Recommended)=== |
||
< |
<syntaxhighlight lang="scala">object RootsOfAFunction extends App { |
||
def findRoots(fn: Double => Double, start: Double, stop: Double, step: Double, epsilon: Double) = { |
def findRoots(fn: Double => Double, start: Double, stop: Double, step: Double, epsilon: Double) = { |
||
for { |
for { |
||
Line 2,968: | Line 2,968: | ||
println(findRoots(fn, -1.0, 3.0, 0.0001, 0.000000001)) |
println(findRoots(fn, -1.0, 3.0, 0.0001, 0.000000001)) |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Vector(-9.381755897326649E-14, 0.9999999999998124, 1.9999999999997022) |
Vector(-9.381755897326649E-14, 0.9999999999998124, 1.9999999999997022) |
||
=={{header|Sidef}}== |
=={{header|Sidef}}== |
||
< |
<syntaxhighlight lang="ruby">func f(x) { |
||
x*x*x - 3*x*x + 2*x |
x*x*x - 3*x*x + 2*x |
||
} |
} |
||
Line 2,992: | Line 2,992: | ||
} |
} |
||
sign = value>0 |
sign = value>0 |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>Root found at 0 |
<pre>Root found at 0 |
||
Line 3,000: | Line 3,000: | ||
=={{header|Tcl}}== |
=={{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). |
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). |
||
< |
<syntaxhighlight lang="tcl">proc froots {lambda {start -3} {end 3} {step 0.0001}} { |
||
set res {} |
set res {} |
||
set lastsign [sgn [apply $lambda $start]] |
set lastsign [sgn [apply $lambda $start]] |
||
Line 3,014: | Line 3,014: | ||
proc sgn x {expr {($x>0) - ($x<0)}} |
proc sgn x {expr {($x>0) - ($x<0)}} |
||
puts [froots {x {expr {$x**3 - 3*$x**2 + 2*$x}}}]</ |
puts [froots {x {expr {$x**3 - 3*$x**2 + 2*$x}}}]</syntaxhighlight> |
||
Result and timing: |
Result and timing: |
||
<pre>/Tcl $ time ./froots.tcl |
<pre>/Tcl $ time ./froots.tcl |
||
Line 3,023: | Line 3,023: | ||
sys 0m0.030s</pre> |
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. |
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. |
||
< |
<syntaxhighlight lang="tcl">proc frootsNR {f df {start -3} {end 3} {step 0.001}} { |
||
set res {} |
set res {} |
||
set lastsign [sgn [apply $f $start]] |
set lastsign [sgn [apply $f $start]] |
||
Line 3,051: | Line 3,051: | ||
puts [frootsNR \ |
puts [frootsNR \ |
||
{x {expr {$x**3 - 3*$x**2 + 2*$x}}} \ |
{x {expr {$x**3 - 3*$x**2 + 2*$x}}} \ |
||
{x {expr {3*$x**2 - 6*$x + 2}}}]</ |
{x {expr {3*$x**2 - 6*$x + 2}}}]</syntaxhighlight> |
||
=={{header|TI-89 BASIC}}== |
=={{header|TI-89 BASIC}}== |
||
Line 3,062: | Line 3,062: | ||
{{trans|Go}} |
{{trans|Go}} |
||
{{libheader|Wren-fmt}} |
{{libheader|Wren-fmt}} |
||
< |
<syntaxhighlight lang="ecmascript">import "/fmt" for Fmt |
||
var secant = Fn.new { |f, x0, x1| |
var secant = Fn.new { |f, x0, x1| |
||
Line 3,096: | Line 3,096: | ||
var example = Fn.new { |x| x*x*x - 3*x*x + 2*x } |
var example = Fn.new { |x| x*x*x - 3*x*x + 2*x } |
||
findRoots.call(example, -0.5, 2.6, 1)</ |
findRoots.call(example, -0.5, 2.6, 1)</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 3,107: | Line 3,107: | ||
=={{header|zkl}}== |
=={{header|zkl}}== |
||
{{trans|Haskell}} |
{{trans|Haskell}} |
||
< |
<syntaxhighlight lang="zkl">fcn findRoots(f,start,stop,step,eps){ |
||
[start..stop,step].filter('wrap(x){ f(x).closeTo(0.0,eps) }) |
[start..stop,step].filter('wrap(x){ f(x).closeTo(0.0,eps) }) |
||
}</ |
}</syntaxhighlight> |
||
< |
<syntaxhighlight lang="zkl">fcn f(x){ x*x*x - 3.0*x*x + 2.0*x } |
||
findRoots(f, -1.0, 3.0, 0.0001, 0.00000001).println();</ |
findRoots(f, -1.0, 3.0, 0.0001, 0.00000001).println();</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>L(-9.38176e-14,1,2)</pre> |
<pre>L(-9.38176e-14,1,2)</pre> |
||
{{trans|C}} |
{{trans|C}} |
||
< |
<syntaxhighlight lang="zkl">fcn secant(f,xA,xB){ |
||
reg e=1.0e-12; |
reg e=1.0e-12; |
||
Line 3,128: | Line 3,128: | ||
if(f(xB).closeTo(0.0,e)) xB |
if(f(xB).closeTo(0.0,e)) xB |
||
else "Function is not converging near (%7.4f,%7.4f).".fmt(xA,xB); |
else "Function is not converging near (%7.4f,%7.4f).".fmt(xA,xB); |
||
}</ |
}</syntaxhighlight> |
||
< |
<syntaxhighlight lang="zkl">step:=0.1; |
||
xs:=findRoots(f, -1.032, 3.0, step, 0.1); |
xs:=findRoots(f, -1.032, 3.0, step, 0.1); |
||
xs.println(" --> ",xs.apply('wrap(x){ secant(f,x-step,x+step) }));</ |
xs.println(" --> ",xs.apply('wrap(x){ secant(f,x-step,x+step) }));</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>L(-0.032,0.968,1.068,1.968) --> L(1.87115e-19,1,1,2)</pre> |
<pre>L(-0.032,0.968,1.068,1.968) --> L(1.87115e-19,1,1,2)</pre> |