Polynomial derivative: Difference between revisions
(add FreeBASIC) |
m (→{{header|Wren}}: Changed to Wren S/H) |
||
(30 intermediate revisions by 16 users not shown) | |||
Line 2: | Line 2: | ||
Given a polynomial, represented by an ordered list of its coefficients by increasing degree (e.g. [-1, 6, 5] represents 5x<sup>2</sup>+6x-1), calculate the polynomial representing the derivative. For example, the derivative of the aforementioned polynomial is 10x+6, represented by [6, 10]. Test cases: 5, -3x+4, 5x<sup>2</sup>+6x-1, x<sup>3</sup>-2x<sup>2</sup>+3x-4, -x<sup>4</sup>-x<sup>3</sup>+x+1 |
Given a polynomial, represented by an ordered list of its coefficients by increasing degree (e.g. [-1, 6, 5] represents 5x<sup>2</sup>+6x-1), calculate the polynomial representing the derivative. For example, the derivative of the aforementioned polynomial is 10x+6, represented by [6, 10]. Test cases: 5, -3x+4, 5x<sup>2</sup>+6x-1, x<sup>3</sup>-2x<sup>2</sup>+3x-4, -x<sup>4</sup>-x<sup>3</sup>+x+1 |
||
;Related task: |
|||
=={{header|Factor}}== |
|||
:* [[Polynomial long division]] |
|||
<lang factor>USING: math.polynomials prettyprint ; |
|||
=={{header|ALGOL 68}}== |
|||
{ -1 6 5 } pdiff .</lang> |
|||
<syntaxhighlight lang="algol68">BEGIN # find the derivatives of polynominals, given their coefficients # |
|||
# returns the derivative polynominal of the polynominal defined by # |
|||
# the array of coeficients, where the coefficients are in # |
|||
# order of ioncreasing power of x # |
|||
OP DERIVATIVE = ( []INT p )[]INT: |
|||
BEGIN |
|||
[ 1 : UPB p - 1 ]INT result; |
|||
FOR i FROM 2 TO UPB p DO |
|||
result[ i - 1 ] := ( i - 1 ) * p[ i ] |
|||
OD; |
|||
result |
|||
END # DERIVATIVE # ; |
|||
# prints the polynomial defined by the coefficients in p # |
|||
OP SHOW = ( []INT p )VOID: |
|||
BEGIN |
|||
BOOL first := TRUE; |
|||
FOR i FROM UPB p BY -1 TO LWB p DO |
|||
IF p[ i ] /= 0 THEN |
|||
IF first THEN |
|||
IF p[ i ] < 0 THEN print( ( "-" ) ) FI |
|||
ELSE |
|||
IF p[ i ] < 0 |
|||
THEN print( ( " - " ) ) |
|||
ELSE print( ( " + " ) ) |
|||
FI |
|||
FI; |
|||
first := FALSE; |
|||
IF i = LWB p |
|||
THEN print( ( whole( ABS p[ i ], 0 ) ) ) |
|||
ELSE |
|||
IF ABS p[ i ] > 1 THEN print( ( whole( ABS p[ i ], 0 ) ) ) FI; |
|||
print( ( "x" ) ); |
|||
IF i > LWB p + 1 THEN print( ( "^", whole( i - 1, 0 ) ) ) FI |
|||
FI |
|||
FI |
|||
OD; |
|||
IF first THEN |
|||
# all coefficients were 0 # |
|||
print( ( "0" ) ) |
|||
FI |
|||
END # SHOW # ; |
|||
# task test cases # |
|||
PROC test = ( []INT p )VOID: BEGIN SHOW p; print( ( " -> " ) ); SHOW DERIVATIVE p; print( ( newline ) ) END; |
|||
test( ( 5 ) ); test( ( 4, -3 ) ); test( ( -1, 6, 5 ) ); test( ( -4, 3, -2, 1 ) ); test( ( 1, 1, 0, -1, -1 ) ) |
|||
END</syntaxhighlight> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
5 -> 0 |
|||
-3x + 4 -> -3 |
|||
5x^2 + 6x - 1 -> 10x + 6 |
|||
x^3 - 2x^2 + 3x - 4 -> 3x^2 - 4x + 3 |
|||
-x^4 - x^3 + x + 1 -> -4x^3 - 3x^2 + 1 |
|||
</pre> |
</pre> |
||
=={{header|Delphi}}== |
|||
The implementation of <code>pdiff</code>: |
|||
{{works with|Delphi|6.0}} |
|||
{{libheader|SysUtils,StdCtrls}} |
|||
<lang factor>USING: kernel math.vectors sequences ; |
|||
IN: math.polynomials |
|||
: pdiff ( p -- p' ) dup length <iota> v* rest ;</lang> |
|||
<syntaxhighlight lang="Delphi"> |
|||
const Poly1: array [0..1-1] of double = (5); {5} |
|||
const Poly2: array [0..2-1] of double = (4,-3); {-3x+4} |
|||
const Poly3: array [0..3-1] of double = (-1,6,5); {5x^2+6x-1} |
|||
const Poly4: array [0..4-1] of double = (-4,3,-2,1); {x^3-2x^2+3x-4} |
|||
const Poly5: array [0..5-1] of double = (1,1,0,-1,-1); {-x^4-x^3+x+1} |
|||
=={{header|Julia}}== |
|||
<lang julia>using Polynomials |
|||
testcases = [ |
|||
("5", [5]), |
|||
("-3x+4", [4, -3]), |
|||
("5x2+6x-1", [-1, 6, 5]), |
|||
("x3-2x2+3x-4", [-4, 3, -2, 1]), |
|||
("-x4-x3+x+1", [1, 1, 0, -1, -1]), |
|||
] |
|||
function GetDerivative(P: array of double): TDoubleDynArray; |
|||
for (s, coef) in testcases |
|||
var I,N: integer; |
|||
println("Derivative of $s: ", derivative(Polynomial(coef))) |
|||
begin |
|||
end |
|||
SetLength(Result,Length(P)-1); |
|||
</lang>{{out}} |
|||
if Length(P)<1 then exit; |
|||
for I:=0 to High(Result) do |
|||
Result[I]:= (I+1)*P[I+1]; |
|||
end; |
|||
function GetPolyStr(D: array of double): string; |
|||
{Get polynomial in standard math format string} |
|||
var I: integer; |
|||
var S: string; |
|||
function GetSignStr(Lead: boolean; D: double): string; |
|||
{Get the sign of coefficient} |
|||
begin |
|||
Result:=''; |
|||
if D>0 then |
|||
begin |
|||
if not Lead then Result:=' + '; |
|||
end |
|||
else |
|||
begin |
|||
Result:='-'; |
|||
if not Lead then Result:=' - '; |
|||
end; |
|||
end; |
|||
begin |
|||
Result:=''; |
|||
{Get each coefficient} |
|||
for I:=High(D) downto 0 do |
|||
begin |
|||
{Ignore zero values} |
|||
if D[I]=0 then continue; |
|||
{Get sign and coefficient} |
|||
S:=GetSignStr(Result='',D[I]); |
|||
S:=S+FloatToStrF(abs(D[I]),ffFixed,18,0); |
|||
{Combine with exponents } |
|||
if I>1 then Result:=Result+Format('%SX^%d',[S,I]) |
|||
else if I=1 then Result:=Result+Format('%SX',[S,I]) |
|||
else Result:=Result+Format('%S',[S]); |
|||
end; |
|||
end; |
|||
procedure ShowDerivative(Memo: TMemo; Poly: array of double); |
|||
{Show polynomial and and derivative} |
|||
var D: TDoubleDynArray; |
|||
begin |
|||
D:=GetDerivative(Poly); |
|||
Memo.Lines.Add('Polynomial: '+GetPolyStr(Poly)); |
|||
Memo.Lines.Add('Derivative: '+'['+GetPolyStr(D)+']'); |
|||
Memo.Lines.Add(''); |
|||
end; |
|||
procedure ShowPolyDerivative(Memo: TMemo); |
|||
var D: TDoubleDynArray; |
|||
begin |
|||
ShowDerivative(Memo,Poly1); |
|||
ShowDerivative(Memo,Poly2); |
|||
ShowDerivative(Memo,Poly3); |
|||
ShowDerivative(Memo,Poly4); |
|||
ShowDerivative(Memo,Poly5); |
|||
end; |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
<pre> |
||
Polynomial: 5 |
|||
Derivative of 5: 0 |
|||
Derivative |
Derivative: [] |
||
Derivative of 5x2+6x-1: 6 + 10*x |
|||
Polynomial: -3X + 4 |
|||
Derivative of x3-2x2+3x-4: 3 - 4*x + 3*x^2 |
|||
Derivative |
Derivative: [-3] |
||
Polynomial: 5X^2 + 6X - 1 |
|||
Derivative: [10X + 6] |
|||
Polynomial: 1X^3 - 2X^2 + 3X - 4 |
|||
Derivative: [3X^2 - 4X + 3] |
|||
Polynomial: -1X^4 - 1X^3 + 1X + 1 |
|||
Derivative: [-4X^3 - 3X^2 + 1] |
|||
Elapsed Time: 17.842 ms. |
|||
</pre> |
</pre> |
||
=={{header|F_Sharp|F#}}== |
|||
<syntaxhighlight lang="fsharp"> |
|||
// Polynomial derivative. Nigel Galloway: January 4th., 2023 |
|||
let n=[[5];[4;-3];[-1;6;5];[-4;3;-2;1];[1;1;0;-1;-1]]|>List.iter((List.mapi(fun n g->n*g)>>List.skip 1>>printfn "%A")) |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
[] |
|||
[-3] |
|||
[6; 10] |
|||
[3; -4; 3] |
|||
[1; 0; -3; -4] |
|||
</pre> |
|||
=={{header|Factor}}== |
|||
<syntaxhighlight lang="factor">USING: generalizations kernel math.polynomials prettyprint ; |
|||
{ 5 } |
|||
{ 4 -3 } |
|||
{ -1 6 5 } |
|||
{ -4 3 -2 1 } |
|||
{ 1 1 0 -1 -1 } |
|||
[ pdiff ] 5 napply .s clear</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
{ } |
|||
{ -3 } |
|||
{ 6 10 } |
|||
{ 3 -4 3 } |
|||
{ 1 0 -3 -4 } |
|||
</pre> |
|||
The implementation of <code>pdiff</code>: |
|||
<syntaxhighlight lang="factor">USING: kernel math.vectors sequences ; |
|||
IN: math.polynomials |
|||
: pdiff ( p -- p' ) dup length <iota> v* rest ;</syntaxhighlight> |
|||
=={{header|FreeBASIC}}== |
=={{header|FreeBASIC}}== |
||
< |
<syntaxhighlight lang="freebasic">sub polydiff( p() as integer ) |
||
'differentiates the polynomial |
'differentiates the polynomial |
||
'p(0) + p(1)x + p(2)x^2 +... + p(n)x^n |
'p(0) + p(1)x + p(2)x^2 +... + p(n)x^n |
||
Line 109: | Line 274: | ||
print "Differentiates to " |
print "Differentiates to " |
||
polydiff(p()) |
polydiff(p()) |
||
print_poly(p()): print</ |
print_poly(p()): print</syntaxhighlight> |
||
{{out}}<pre> |
{{out}}<pre> |
||
5 |
|||
Differentiates to |
Differentiates to |
||
0 |
|||
4 - 3x |
|||
Differentiates to |
Differentiates to |
||
-3 |
-3 |
||
Line 121: | Line 286: | ||
-1 + 6x+ 5x^2 |
-1 + 6x+ 5x^2 |
||
Differentiates to |
Differentiates to |
||
6 + %10x |
|||
4 + 3x- 2x^2+ 1x^3 |
|||
Differentiates to |
Differentiates to |
||
3 - 4x+ 3x^2 |
|||
1 + 1x- 1x^3- 1x^4 |
|||
Differentiates to |
Differentiates to |
||
1 - 3x^2- 4x^3</pre> |
|||
=={{header|Go}}== |
|||
{{trans|Wren}} |
|||
<syntaxhighlight lang="go">package main |
|||
import ( |
|||
"fmt" |
|||
"strings" |
|||
) |
|||
func derivative(p []int) []int { |
|||
if len(p) == 1 { |
|||
return []int{0} |
|||
} |
|||
d := make([]int, len(p)-1) |
|||
copy(d, p[1:]) |
|||
for i := 0; i < len(d); i++ { |
|||
d[i] = p[i+1] * (i + 1) |
|||
} |
|||
return d |
|||
} |
|||
var ss = []string{"", "", "\u00b2", "\u00b3", "\u2074", "\u2075", "\u2076", "\u2077", "\u2078", "\u2079"} |
|||
// for n <= 20 |
|||
func superscript(n int) string { |
|||
if n < 10 { |
|||
return ss[n] |
|||
} |
|||
if n < 20 { |
|||
return ss[1] + ss[n-10] |
|||
} |
|||
return ss[2] + ss[0] |
|||
} |
|||
func abs(n int) int { |
|||
if n < 0 { |
|||
return -n |
|||
} |
|||
return n |
|||
} |
|||
func polyPrint(p []int) string { |
|||
if len(p) == 1 { |
|||
return fmt.Sprintf("%d", p[0]) |
|||
} |
|||
var terms []string |
|||
for i := 0; i < len(p); i++ { |
|||
if p[i] == 0 { |
|||
continue |
|||
} |
|||
c := fmt.Sprintf("%d", p[i]) |
|||
if i > 0 && abs(p[i]) == 1 { |
|||
c = "" |
|||
if p[i] != 1 { |
|||
c = "-" |
|||
} |
|||
} |
|||
x := "x" |
|||
if i <= 0 { |
|||
x = "" |
|||
} |
|||
terms = append(terms, fmt.Sprintf("%s%s%s", c, x, superscript(i))) |
|||
} |
|||
for i, j := 0, len(terms)-1; i < j; i, j = i+1, j-1 { |
|||
terms[i], terms[j] = terms[j], terms[i] |
|||
} |
|||
s := strings.Join(terms, "+") |
|||
return strings.Replace(s, "+-", "-", -1) |
|||
} |
|||
func main() { |
|||
fmt.Println("The derivatives of the following polynomials are:\n") |
|||
polys := [][]int{{5}, {4, -3}, {-1, 6, 5}, {-4, 3, -2, 1}, {1, 1, 0, -1, -1}} |
|||
for _, poly := range polys { |
|||
deriv := derivative(poly) |
|||
fmt.Printf("%v -> %v\n", poly, deriv) |
|||
} |
|||
fmt.Println("\nOr in normal mathematical notation:\n") |
|||
for _, poly := range polys { |
|||
deriv := derivative(poly) |
|||
fmt.Println("Polynomial : ", polyPrint(poly)) |
|||
fmt.Println("Derivative : ", polyPrint(deriv), "\n") |
|||
} |
|||
}</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
The derivatives of the following polynomials are: |
|||
[5] -> [0] |
|||
[4 -3] -> [-3] |
|||
[-1 6 5] -> [6 10] |
|||
[-4 3 -2 1] -> [3 -4 3] |
|||
[1 1 0 -1 -1] -> [1 0 -3 -4] |
|||
Or in normal mathematical notation: |
|||
Polynomial : 5 |
|||
Derivative : 0 |
|||
Polynomial : -3x+4 |
|||
Derivative : -3 |
|||
Polynomial : 5x²+6x-1 |
|||
Derivative : 10x+6 |
|||
Polynomial : x³-2x²+3x-4 |
|||
Derivative : 3x²-4x+3 |
|||
Polynomial : -x⁴-x³+x+1 |
|||
Derivative : -4x³-3x²+1 |
|||
</pre> |
|||
=={{header|Haskell}}== |
|||
<syntaxhighlight lang="haskell">deriv = zipWith (*) [1..] . tail |
|||
main = mapM_ (putStrLn . line) ps |
|||
where |
|||
line p = "\np = " ++ show p ++ "\np' = " ++ show (deriv p) |
|||
ps = [[5],[4,-3],[-1,6,5],[-4,3,-2,1],[1,1,0,-1,-1]]</syntaxhighlight> |
|||
<pre>main |
|||
p = [5] |
|||
p' = [] |
|||
p = [4,-3] |
|||
p' = [-3] |
|||
p = [-1,6,5] |
|||
p' = [6,10] |
|||
p = [-4,3,-2,1] |
|||
p' = [3,-4,3] |
|||
p = [1,1,0,-1,-1] |
|||
p' = [1,0,-3,-4]</pre> |
|||
With fancy output |
|||
<syntaxhighlight lang="haskell">{-# language LambdaCase #-} |
|||
showPoly [] = "0" |
|||
showPoly p = foldl1 (\r -> (r ++) . term) $ |
|||
dropWhile null $ |
|||
foldMap (\(c, n) -> [show c ++ expt n]) $ |
|||
zip p [0..] |
|||
where |
|||
expt = \case 0 -> "" |
|||
1 -> "*x" |
|||
n -> "*x^" ++ show n |
|||
term = \case [] -> "" |
|||
'0':'*':t -> "" |
|||
'-':'1':'*':t -> " - " ++ t |
|||
'1':'*':t -> " + " ++ t |
|||
'-':t -> " - " ++ t |
|||
t -> " + " ++ t |
|||
main = mapM_ (putStrLn . line) ps |
|||
where |
|||
line p = "\np = " ++ showPoly p ++ "\np' = " ++ showPoly (deriv p) |
|||
ps = [[5],[4,-3],[-1,6,5],[-4,3,-2,1],[1,1,0,-1,-1]]</syntaxhighlight> |
|||
<pre> main |
|||
p = 5 |
|||
p' = 0 |
|||
p = 4 - 3*x |
|||
p' = -3 |
|||
p = -1 + 6*x + 5*x^2 |
|||
p' = 6 + 10*x |
|||
p = -4 + 3*x - 2*x^2 + x^3 |
|||
p' = 3 - 4*x + 3*x^2 |
|||
p = 1 + 1*x - 1*x^3 - 1*x^4 |
|||
p' = 1 - 3*x^2 - 4*x^</pre> |
|||
=={{header|J}}== |
|||
Implementation: |
|||
<syntaxhighlight lang=J>pderiv=: -@(1 >. _1+#) {. (* i.@#)</syntaxhighlight> |
|||
Task examples: |
|||
<syntaxhighlight lang=J> pderiv 5 |
|||
0 |
|||
pderiv 4 _3 |
|||
_3 |
|||
pderiv _1 6 5 |
|||
6 10 |
|||
pderiv _4 3 _2 1 |
|||
3 _4 3 |
|||
pderiv 1 1 _1 _1 |
|||
1 _2 _3</syntaxhighlight> |
|||
Note also that J's <code>p.</code> can be used to apply one of these polynomials to an argument. For example: |
|||
<syntaxhighlight lang=J> 5 p. 2 3 5 7 |
|||
5 5 5 5 |
|||
(pderiv 5) p. 2 3 5 7 |
|||
0 0 0 0 |
|||
4 _3 p. 2 3 5 7 |
|||
_2 _5 _11 _17 |
|||
(pderiv 4 _3) p. 2 3 5 7 |
|||
_3 _3 _3 _3</syntaxhighlight> |
|||
=={{header|jq}}== |
|||
'''Adapted from [[#Wren|Wren]]''' (with corrections) |
|||
{{works with|jq}} |
|||
'''Works with gojq, the Go implementation of jq''' |
|||
The following definition of polyPrint has no restriction on the degree of the polynomial. |
|||
<syntaxhighlight lang="jq"># The input should be a non-empty array of integers representing a polynomial. |
|||
# The output likewise represents its derivative. |
|||
def derivative: |
|||
. as $p |
|||
| if length == 1 then [0] |
|||
else reduce range(0; length-1) as $i (.[1:]; |
|||
.[$i] = $p[$i+1] * ($i + 1) ) |
|||
end; |
|||
def polyPrint: |
|||
def ss: ["\u2070", "\u00b9", "\u00b2", "\u00b3", "\u2074", "\u2075", "\u2076", "\u2077", "\u2078", "\u2079"]; |
|||
def digits: tostring | explode[] | [.] | implode | tonumber; |
|||
ss as $ss |
|||
| def superscript: |
|||
if . <= 1 then "" |
|||
else reduce digits as $d (""; . + $ss[$d] ) |
|||
end; |
|||
. as $p |
|||
| if length == 1 then .[0] | tostring |
|||
else reduce range(0; length) as $i ([]; |
|||
if $p[$i] != 0 |
|||
then (if $i > 0 then "x" else "" end) as $x |
|||
| ( if $i > 0 and ($p[$i]|length) == 1 |
|||
then (if $p[$i] == 1 then "" else "-" end) |
|||
else ($p[$i]|tostring) |
|||
end ) as $c |
|||
| . + ["\($c)\($x)\($i|superscript)"] |
|||
else . end ) |
|||
| reverse |
|||
| join("+") |
|||
| gsub("\\+-"; "-") |
|||
end ; |
|||
def task: |
|||
def polys: [ [5], [4, -3], [-1, 6, 5], [-4, 3, -2, 1], [1, 1, 0, -1, -1] ]; |
|||
"Example polynomials and their derivatives:\n", |
|||
( polys[] | "\(.) -> \(derivative)" ), |
|||
"\nOr in normal mathematical notation:\n", |
|||
( polys[] |
|||
| "Polynomial : \(polyPrint)", |
|||
"Derivative : \(derivative|polyPrint)\n" ) ; |
|||
task</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
Example polynomials and their derivatives: |
|||
[5] -> [0] |
|||
[4,-3] -> [-3] |
|||
[-1,6,5] -> [6,10] |
|||
[-4,3,-2,1] -> [3,-4,3] |
|||
[1,1,0,-1,-1] -> [1,0,-3,-4] |
|||
Or in normal mathematical notation: |
|||
Polynomial : 5 |
|||
Derivative : 0 |
|||
Polynomial : -3x+4 |
|||
Derivative : -3 |
|||
Polynomial : 5x²+6x-1 |
|||
Derivative : 10x+6 |
|||
Polynomial : x³-2x²+3x-4 |
|||
Derivative : 3x²-4x+3 |
|||
Polynomial : -x⁴-x³+x+1 |
|||
Derivative : -4x³-3x²+1 |
|||
</pre> |
|||
=={{header|Julia}}== |
|||
<syntaxhighlight lang="julia">using Polynomials |
|||
testcases = [ |
|||
("5", [5]), |
|||
("-3x+4", [4, -3]), |
|||
("5x2+6x-1", [-1, 6, 5]), |
|||
("x3-2x2+3x-4", [-4, 3, -2, 1]), |
|||
("-x4-x3+x+1", [1, 1, 0, -1, -1]), |
|||
] |
|||
for (s, coef) in testcases |
|||
println("Derivative of $s: ", derivative(Polynomial(coef))) |
|||
end |
|||
</syntaxhighlight>{{out}} |
|||
<pre> |
|||
Derivative of 5: 0 |
|||
Derivative of -3x+4: -3 |
|||
Derivative of 5x2+6x-1: 6 + 10*x |
|||
Derivative of x3-2x2+3x-4: 3 - 4*x + 3*x^2 |
|||
Derivative of -x4-x3+x+1: 1 - 3*x^2 - 4*x^3 |
|||
</pre> |
|||
=={{header|Nim}}== |
|||
<syntaxhighlight lang="Nim">import std/sequtils |
|||
type |
|||
Polynomial[T] = object |
|||
coeffs: seq[T] |
|||
Term = tuple[coeff, exp: int] |
|||
template `[]`[T](poly: Polynomial[T]; idx: Natural): T = |
|||
poly.coeffs[idx] |
|||
template `[]=`[T](poly: var Polynomial; idx: Natural; val: T) = |
|||
poly.coeffs[idx] = val |
|||
template degree(poly: Polynomial): int = |
|||
poly.coeffs.high |
|||
func newPolynomial[T](coeffs: openArray[T]): Polynomial[T] = |
|||
## Create a polynomial from a list of coefficients. |
|||
result.coeffs = coeffs.toSeq |
|||
func newPolynomial[T](degree: Natural = 0): Polynomial[T] = |
|||
## Create a polynomial with given degree. |
|||
## Coefficients are all zeroes. |
|||
result.coeffs = newSeq[T](degree + 1) |
|||
const Superscripts: array['0'..'9', string] = ["⁰", "¹", "²", "³", "⁴", "⁵", "⁶", "⁷", "⁸", "⁹"] |
|||
func superscript(n: Natural): string = |
|||
## Return the Unicode string to use to represent an exponent. |
|||
if n == 1: |
|||
return "" |
|||
for d in $n: |
|||
result.add Superscripts[d] |
|||
func `$`(term: Term): string = |
|||
## Return the string representation of a term. |
|||
if term.coeff == 0: "0" |
|||
elif term.exp == 0: $term.coeff |
|||
else: |
|||
let base = 'x' & superscript(term.exp) |
|||
if term.coeff == 1: base |
|||
elif term.coeff == -1: '-' & base |
|||
else: $term.coeff & base |
|||
func `$`[T](poly: Polynomial[T]): string = |
|||
## Return the string representation of a polynomial. |
|||
for idx in countdown(poly.degree, 0): |
|||
let coeff = poly[idx] |
|||
var term: Term = (coeff: coeff, exp: idx) |
|||
if result.len == 0: |
|||
result.add $term |
|||
elif coeff > 0: |
|||
result.add '+' |
|||
result.add $term |
|||
elif coeff < 0: |
|||
term.coeff = -term.coeff |
|||
result.add '-' |
|||
result.add $term |
|||
func derivative[T](poly: Polynomial[T]): Polynomial[T] = |
|||
## Return the derivative of a polynomial. |
|||
if poly.degree == 0: return newPolynomial[T]() |
|||
result = newPolynomial[T](poly.degree - 1) |
|||
for degree in 1..poly.degree: |
|||
result[degree - 1] = degree * poly[degree] |
|||
for coeffs in @[@[5], @[4, -3], @[-1, 6, 5], @[-4, 3, -2, 1], @[1, 1, 0, -1, -1]]: |
|||
let poly = newPolynomial(coeffs) |
|||
echo "Polynomial: ", poly |
|||
echo "Derivative: ", poly.derivative |
|||
echo() |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre>Polynomial: 5 |
|||
Derivative: 0 |
|||
Polynomial: -3x+4 |
|||
Derivative: -3 |
|||
Polynomial: 5x²+6x-1 |
|||
Derivative: 10x+6 |
|||
Polynomial: x³-2x²+3x-4 |
|||
Derivative: 3x²-4x+3 |
|||
Polynomial: -x⁴-x³+x+1 |
|||
Derivative: -4x³-3x²+1 |
|||
</pre> |
|||
=={{header|Perl}}== |
|||
<syntaxhighlight lang="perl">use strict; |
|||
use warnings; |
|||
use feature 'say'; |
|||
use utf8; |
|||
binmode(STDOUT, ':utf8'); |
|||
sub pp { |
|||
my(@p) = @_; |
|||
return 0 unless @p; |
|||
my @f = $p[0]; |
|||
push @f, ($p[$_] != 1 and $p[$_]) . 'x' . ($_ != 1 and (qw<⁰ ¹ ² ³ ⁴ ⁵ ⁶ ⁷ ⁸ ⁹>)[$_]) |
|||
for grep { $p[$_] != 0 } 1 .. $#p; |
|||
( join('+', reverse @f) =~ s/-1x/-x/gr ) =~ s/\+-/-/gr |
|||
} |
|||
for ([5], [4,-3], [-1,3,-2,1], [-1,6,5], [1,1,0,-1,-1]) { |
|||
my @poly = @$_; |
|||
say 'Polynomial: ' . join(', ', @poly) . ' ==> ' . pp @poly; |
|||
$poly[$_] *= $_ for 0 .. $#poly; |
|||
shift @poly; |
|||
say 'Derivative: ' . (@poly ? join', ', @poly : 0) . ' ==> ' . pp(@poly) . "\n"; |
|||
}</syntaxhighlight> |
|||
{{out}} |
|||
<pre>Polynomial: 5 ==> 5 |
|||
Derivative: 0 ==> 0 |
|||
Polynomial: 4, -3 ==> -3x+4 |
|||
Derivative: -3 ==> -3 |
|||
Polynomial: -1, 3, -2, 1 ==> x³-2x²+3x-1 |
|||
Derivative: 3, -4, 3 ==> 3x²-4x+3 |
|||
Polynomial: -1, 6, 5 ==> 5x²+6x-1 |
|||
Derivative: 6, 10 ==> 10x+6 |
|||
Polynomial: 1, 1, 0, -1, -1 ==> -x⁴-x³+x+1 |
|||
Derivative: 1, 0, -3, -4 ==> -4x³-3x²+1</pre> |
|||
=={{header|Phix}}== |
|||
<!--<syntaxhighlight lang="phix">(phixonline)--> |
|||
<span style="color: #000080;font-style:italic;">-- |
|||
-- demo\rosetta\Polynomial_derivative.exw |
|||
--</span> |
|||
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span> |
|||
<span style="color: #008080;">function</span> <span style="color: #000000;">derivative</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">p</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">p</span><span style="color: #0000FF;">={}</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #0000FF;">{}</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">r</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">p</span><span style="color: #0000FF;">)-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">r</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span> |
|||
<span style="color: #000000;">r</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">*</span><span style="color: #000000;">p</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
<span style="color: #008080;">return</span> <span style="color: #000000;">r</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span> |
|||
<span style="color: #008080;">function</span> <span style="color: #000000;">poly</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">si</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #000080;font-style:italic;">-- display helper, copied from demo\rosetta\Polynomial_long_division.exw</span> |
|||
<span style="color: #004080;">string</span> <span style="color: #000000;">r</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">""</span> |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">t</span><span style="color: #0000FF;">=</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">si</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">to</span> <span style="color: #000000;">1</span> <span style="color: #008080;">by</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span> |
|||
<span style="color: #004080;">integer</span> <span style="color: #000000;">sit</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">si</span><span style="color: #0000FF;">[</span><span style="color: #000000;">t</span><span style="color: #0000FF;">]</span> |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">sit</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">sit</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">and</span> <span style="color: #000000;">t</span><span style="color: #0000FF;">></span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span> |
|||
<span style="color: #000000;">r</span> <span style="color: #0000FF;">&=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">r</span><span style="color: #0000FF;">=</span><span style="color: #008000;">""</span><span style="color: #0000FF;">?</span> <span style="color: #008000;">""</span><span style="color: #0000FF;">:</span><span style="color: #008000;">" + "</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #008080;">elsif</span> <span style="color: #000000;">sit</span><span style="color: #0000FF;">=-</span><span style="color: #000000;">1</span> <span style="color: #008080;">and</span> <span style="color: #000000;">t</span><span style="color: #0000FF;">></span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span> |
|||
<span style="color: #000000;">r</span> <span style="color: #0000FF;">&=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">r</span><span style="color: #0000FF;">=</span><span style="color: #008000;">""</span><span style="color: #0000FF;">?</span><span style="color: #008000;">"-"</span><span style="color: #0000FF;">:</span><span style="color: #008000;">" - "</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #008080;">else</span> |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">r</span><span style="color: #0000FF;">!=</span><span style="color: #008000;">""</span> <span style="color: #008080;">then</span> |
|||
<span style="color: #000000;">r</span> <span style="color: #0000FF;">&=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">sit</span><span style="color: #0000FF;"><</span><span style="color: #000000;">0</span><span style="color: #0000FF;">?</span><span style="color: #008000;">" - "</span><span style="color: #0000FF;">:</span><span style="color: #008000;">" + "</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #000000;">sit</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">abs</span><span style="color: #0000FF;">(</span><span style="color: #000000;">sit</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
<span style="color: #000000;">r</span> <span style="color: #0000FF;">&=</span> <span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"%d"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">sit</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
<span style="color: #000000;">r</span> <span style="color: #0000FF;">&=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t</span><span style="color: #0000FF;">></span><span style="color: #000000;">1</span><span style="color: #0000FF;">?</span><span style="color: #008000;">"x"</span><span style="color: #0000FF;">&</span><span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t</span><span style="color: #0000FF;">></span><span style="color: #000000;">2</span><span style="color: #0000FF;">?</span><span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"^%d"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">t</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">):</span><span style="color: #008000;">""</span><span style="color: #0000FF;">):</span><span style="color: #008000;">""</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">r</span><span style="color: #0000FF;">=</span><span style="color: #008000;">""</span> <span style="color: #008080;">then</span> <span style="color: #000000;">r</span><span style="color: #0000FF;">=</span><span style="color: #008000;">"0"</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
<span style="color: #008080;">return</span> <span style="color: #000000;">r</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span> |
|||
<span style="color: #008080;">constant</span> <span style="color: #000000;">tests</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{{</span><span style="color: #000000;">5</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">4</span><span style="color: #0000FF;">,-</span><span style="color: #000000;">3</span><span style="color: #0000FF;">},{-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">6</span><span style="color: #0000FF;">,</span><span style="color: #000000;">5</span><span style="color: #0000FF;">},{-</span><span style="color: #000000;">4</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,-</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">}}</span> |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tests</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span> |
|||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">t</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">tests</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span> |
|||
<span style="color: #000000;">r</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">derivative</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%20s ==> %16s (internally %v -> %v)\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">poly</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t</span><span style="color: #0000FF;">),</span><span style="color: #000000;">poly</span><span style="color: #0000FF;">(</span><span style="color: #000000;">r</span><span style="color: #0000FF;">),</span><span style="color: #000000;">t</span><span style="color: #0000FF;">,</span><span style="color: #000000;">r</span><span style="color: #0000FF;">})</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
<span style="color: #0000FF;">?</span><span style="color: #008000;">"done"</span> |
|||
<span style="color: #0000FF;">{}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">wait_key</span><span style="color: #0000FF;">()</span> |
|||
<!--</syntaxhighlight>--> |
|||
{{out}} |
|||
<pre> |
|||
5 ==> 0 (internally {5} -> {}) |
|||
-3x + 4 ==> -3 (internally {4,-3} -> {-3}) |
|||
5x^2 + 6x - 1 ==> 10x + 6 (internally {-1,6,5} -> {6,10}) |
|||
x^3 - 2x^2 + 3x - 4 ==> 3x^2 - 4x + 3 (internally {-4,3,-2,1} -> {3,-4,3}) |
|||
-x^4 - x^3 + x + 1 ==> -4x^3 - 3x^2 + 1 (internally {1,1,0,-1,-1} -> {1,0,-3,-4}) |
|||
</pre> |
|||
=={{header|Raku}}== |
|||
<syntaxhighlight lang="raku" line>use Lingua::EN::Numbers:ver<2.8+>; |
|||
sub pretty (@poly) { |
|||
join( '+', (^@poly).reverse.map: { @poly[$_] ~ "x{.&super}" } )\ |
|||
.subst(/['+'|'-']'0x'<[⁰¹²³⁴⁵⁶⁷⁸⁹]>*/, '', :g).subst(/'x¹'<?before <-[⁰¹²³⁴⁵⁶⁷⁸⁹]>>/, 'x')\ |
|||
.subst(/'x⁰'$/, '').subst(/'+-'/, '-', :g).subst(/(['+'|'-'|^])'1x'/, {"$0x"}, :g) || 0 |
|||
} |
|||
for [5], [4,-3], [-1,3,-2,1], [-1,6,5], [1,1,0,-1,-1] -> $test { |
|||
say "Polynomial: " ~ "[{$test.join: ','}] ➡ " ~ pretty $test; |
|||
my @poly = |$test; |
|||
(^@poly).map: { @poly[$_] *= $_ }; |
|||
shift @poly; |
|||
say "Derivative: " ~ "[{@poly.join: ','}] ➡ " ~ pretty @poly; |
|||
say ''; |
|||
}</syntaxhighlight> |
|||
{{out}} |
|||
<pre>Polynomial: [5] ➡ 5 |
|||
Derivative: [] ➡ 0 |
|||
Polynomial: [4,-3] ➡ -3x+4 |
|||
Derivative: [-3] ➡ -3 |
|||
Polynomial: [-1,3,-2,1] ➡ x³-2x²+3x-1 |
|||
Derivative: [3,-4,3] ➡ 3x²-4x+3 |
|||
Polynomial: [-1,6,5] ➡ 5x²+6x-1 |
|||
Derivative: [6,10] ➡ 10x+6 |
|||
Polynomial: [1,1,0,-1,-1] ➡ -x⁴-x³+x+1 |
|||
Derivative: [1,0,-3,-4] ➡ -4x³-3x²+1</pre> |
|||
=={{header|RPL}}== |
|||
RPL can symbolically derivate many functions, including polynoms. |
|||
{{works with|Halcyon Calc|4.2.7}} |
|||
===Built-in derivation=== |
|||
Formal derivation can be performed by the <code>∂</code> operator directly from the interpreter command line. Invoking then the <code>COLCT</code> function allows to simplify the formula but sometimes changes the order of terms, as shown with the last example. |
|||
5 'x' ∂ COLCT |
|||
'-3*x+4' 'x' ∂ COLCT |
|||
'5x^2+6*x-1' 'x' ∂ COLCT |
|||
'x^3-2*x^2+3*x-4' 'x' ∂ COLCT |
|||
'-x^4-x^3+x+1' 'x' ∂ |
|||
DUP COLCT |
|||
{{out}} |
|||
<pre> |
|||
6: 0 |
|||
5: -3 |
|||
4: '10*x+6' |
|||
3: '3*x^2-4*x+3' |
|||
2: '-(4*x^3)-3*x^2+1' |
|||
1: '1-4*x^3-3*x^2' |
|||
</pre> |
|||
===Classical programming=== |
|||
Assuming we ignore the existence of the <code>∂</code> operator, here is a typical RPL program that handles polynoms as lists of scalars, to be completed by another program to display the list on a fancier way. |
|||
≪ → coeffs |
|||
≪ IF coeffs SIZE 1 - |
|||
THEN |
|||
{ } 1 LAST FOR j |
|||
coeffs j 1 + GET j 1 MAX * + |
|||
NEXT |
|||
ELSE { 0 } |
|||
END |
|||
≫ ≫ |
|||
'DPDX' STO |
|||
{5} DPDX |
|||
{4 -3} DPDX |
|||
{-1 6 5} DPDX |
|||
{-4 3 -2 1} DPDX |
|||
{1 1 0 -1 -1} DPDX |
|||
{{out}} |
|||
<pre> |
|||
5: { 0 } |
|||
4: { -3 } |
|||
3: { 6 10 } |
|||
2: { 3 -4 3 } |
|||
1: { 1 0 -3 -4 } |
|||
</pre> |
|||
=== Fancy output === |
|||
≪ → coeffs |
|||
≪ coeffs 1 GET |
|||
coeffs SIZE 2 FOR j |
|||
coeffs j GET ‘x’ j 1 - ^ * SWAP + |
|||
-1 STEP |
|||
≫ COLCT |
|||
≫ |
|||
‘→EQ’ STO |
|||
{1 1 0 -1 -1} DPDX |
|||
DUP →EQ |
|||
{{out}} |
|||
<pre> |
|||
2: { 1 0 -3 -4 } |
|||
1: '1-3*x^2-4*x^3' |
|||
</pre> |
|||
=={{header|Sidef}}== |
|||
<syntaxhighlight lang="ruby">func derivative(f) { |
|||
Poly(f.coeffs.map_2d{|e,k| [e-1, k*e] }.flat...) |
|||
} |
|||
var coeffs = [ |
|||
[5], |
|||
[4,-3], |
|||
[-1,6,5], |
|||
[-4,3,-2,1], |
|||
[-1, 6, 5], |
|||
[1,1,0,-1,-1], |
|||
] |
|||
for c in (coeffs) { |
|||
var poly = Poly(c.flip) |
|||
var derv = derivative(poly) |
|||
var d = { derv.coeff(_) }.map(0..derv.degree) |
|||
say "Polynomial : #{'%20s' % c} = #{poly}" |
|||
say "Derivative : #{'%20s' % d} = #{derv || 0}\n" |
|||
}</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
Polynomial : [5] = 5 |
|||
Derivative : [0] = 0 |
|||
Polynomial : [4, -3] = -3*x + 4 |
|||
Derivative : [-3] = -3 |
|||
Polynomial : [-1, 6, 5] = 5*x^2 + 6*x - 1 |
|||
Derivative : [6, 10] = 10*x + 6 |
|||
Polynomial : [-4, 3, -2, 1] = x^3 - 2*x^2 + 3*x - 4 |
|||
Derivative : [3, -4, 3] = 3*x^2 - 4*x + 3 |
|||
Polynomial : [-1, 6, 5] = 5*x^2 + 6*x - 1 |
|||
Derivative : [6, 10] = 10*x + 6 |
|||
Polynomial : [1, 1, 0, -1, -1] = -x^4 - x^3 + x + 1 |
|||
Derivative : [1, 0, -3, -4] = -4*x^3 - 3*x^2 + 1 |
|||
</pre> |
|||
=={{header|Wren}}== |
|||
<syntaxhighlight lang="wren">var derivative = Fn.new { |p| |
|||
if (p.count == 1) return [0] |
|||
var d = p[1..-1].toList |
|||
for (i in 0...d.count) d[i] = p[i+1] * (i + 1) |
|||
return d |
|||
} |
|||
var ss = ["", "", "\u00b2", "\u00b3", "\u2074", "\u2075", "\u2076", "\u2077", "\u2078", "\u2079"] |
|||
// for n <= 20 |
|||
var superscript = Fn.new { |n| (n < 10) ? ss[n] : (n < 20) ? ss[1] + ss[n - 10] : ss[2] + ss[0] } |
|||
var polyPrint = Fn.new { |p| |
|||
if (p.count == 1) return p[0].toString |
|||
var terms = [] |
|||
for (i in 0...p.count) { |
|||
if (p[i] == 0) continue |
|||
var c = p[i].toString |
|||
if (i > 0 && p[i].abs == 1) c = (p[i] == 1) ? "" : "-" |
|||
var x = (i > 0) ? "x" : "" |
|||
terms.add("%(c)%(x)%(superscript.call(i))") |
|||
} |
|||
return terms[-1..0].join("+").replace("+-", "-") |
|||
} |
|||
System.print("The derivatives of the following polynomials are:\n") |
|||
var polys = [ [5], [4, -3], [-1, 6, 5], [-4, 3, -2, 1], [1, 1, 0, -1, -1] ] |
|||
for (poly in polys) { |
|||
var deriv = derivative.call(poly) |
|||
System.print("%(poly) -> %(deriv)") |
|||
} |
|||
System.print("\nOr in normal mathematical notation:\n") |
|||
for (poly in polys) { |
|||
var deriv = derivative.call(poly) |
|||
System.print("Polynomial : %(polyPrint.call(poly))") |
|||
System.print("Derivative : %(polyPrint.call(deriv))\n") |
|||
}</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
The derivatives of the following polynomials are: |
|||
[5] -> [0] |
|||
[4, -3] -> [-3] |
|||
[-1, 6, 5] -> [6, 10] |
|||
[-4, 3, -2, 1] -> [3, -4, 3] |
|||
[1, 1, 0, -1, -1] -> [1, 0, -3, -4] |
|||
Or in normal mathematical notation: |
|||
Polynomial : 5 |
|||
Derivative : 0 |
|||
Polynomial : -3x+4 |
|||
Derivative : -3 |
|||
Polynomial : 5x²+6x-1 |
|||
Derivative : 10x+6 |
|||
Polynomial : x³-2x²+3x-4 |
|||
Derivative : 3x²-4x+3 |
|||
Polynomial : -x⁴-x³+x+1 |
|||
Derivative : -4x³-3x²+1 |
|||
</pre> |
|||
=={{header|XPL0}}== |
|||
<syntaxhighlight lang="xpl0">int IntSize, Cases, Case, Len, Deg, Coef; |
|||
[IntSize:= @Case - @Cases; |
|||
Cases:=[[ 5], |
|||
[ 4, -3], |
|||
[-1, 6, 5], |
|||
[-4, 3, -2, 1], |
|||
[ 1, 1, 0, -1, -1], |
|||
[ 0]]; |
|||
for Case:= 0 to 5-1 do |
|||
[Len:= (Cases(Case+1) - Cases(Case)) / IntSize; |
|||
for Deg:= 0 to Len-1 do |
|||
[Coef:= Cases(Case, Deg); |
|||
if Deg = 0 then Text(0, "[") |
|||
else [IntOut(0, Coef*Deg); |
|||
if Deg < Len-1 then |
|||
Text(0, ", "); |
|||
]; |
|||
]; |
|||
Text(0, "]^M^J"); |
|||
]; |
|||
]</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
[] |
|||
[-3] |
|||
[6, 10] |
|||
[3, -4, 3] |
|||
[1, 0, -3, -4] |
|||
</pre> |
Latest revision as of 12:39, 25 January 2024
Given a polynomial, represented by an ordered list of its coefficients by increasing degree (e.g. [-1, 6, 5] represents 5x2+6x-1), calculate the polynomial representing the derivative. For example, the derivative of the aforementioned polynomial is 10x+6, represented by [6, 10]. Test cases: 5, -3x+4, 5x2+6x-1, x3-2x2+3x-4, -x4-x3+x+1
- Related task
ALGOL 68
BEGIN # find the derivatives of polynominals, given their coefficients #
# returns the derivative polynominal of the polynominal defined by #
# the array of coeficients, where the coefficients are in #
# order of ioncreasing power of x #
OP DERIVATIVE = ( []INT p )[]INT:
BEGIN
[ 1 : UPB p - 1 ]INT result;
FOR i FROM 2 TO UPB p DO
result[ i - 1 ] := ( i - 1 ) * p[ i ]
OD;
result
END # DERIVATIVE # ;
# prints the polynomial defined by the coefficients in p #
OP SHOW = ( []INT p )VOID:
BEGIN
BOOL first := TRUE;
FOR i FROM UPB p BY -1 TO LWB p DO
IF p[ i ] /= 0 THEN
IF first THEN
IF p[ i ] < 0 THEN print( ( "-" ) ) FI
ELSE
IF p[ i ] < 0
THEN print( ( " - " ) )
ELSE print( ( " + " ) )
FI
FI;
first := FALSE;
IF i = LWB p
THEN print( ( whole( ABS p[ i ], 0 ) ) )
ELSE
IF ABS p[ i ] > 1 THEN print( ( whole( ABS p[ i ], 0 ) ) ) FI;
print( ( "x" ) );
IF i > LWB p + 1 THEN print( ( "^", whole( i - 1, 0 ) ) ) FI
FI
FI
OD;
IF first THEN
# all coefficients were 0 #
print( ( "0" ) )
FI
END # SHOW # ;
# task test cases #
PROC test = ( []INT p )VOID: BEGIN SHOW p; print( ( " -> " ) ); SHOW DERIVATIVE p; print( ( newline ) ) END;
test( ( 5 ) ); test( ( 4, -3 ) ); test( ( -1, 6, 5 ) ); test( ( -4, 3, -2, 1 ) ); test( ( 1, 1, 0, -1, -1 ) )
END
- Output:
5 -> 0 -3x + 4 -> -3 5x^2 + 6x - 1 -> 10x + 6 x^3 - 2x^2 + 3x - 4 -> 3x^2 - 4x + 3 -x^4 - x^3 + x + 1 -> -4x^3 - 3x^2 + 1
Delphi
const Poly1: array [0..1-1] of double = (5); {5}
const Poly2: array [0..2-1] of double = (4,-3); {-3x+4}
const Poly3: array [0..3-1] of double = (-1,6,5); {5x^2+6x-1}
const Poly4: array [0..4-1] of double = (-4,3,-2,1); {x^3-2x^2+3x-4}
const Poly5: array [0..5-1] of double = (1,1,0,-1,-1); {-x^4-x^3+x+1}
function GetDerivative(P: array of double): TDoubleDynArray;
var I,N: integer;
begin
SetLength(Result,Length(P)-1);
if Length(P)<1 then exit;
for I:=0 to High(Result) do
Result[I]:= (I+1)*P[I+1];
end;
function GetPolyStr(D: array of double): string;
{Get polynomial in standard math format string}
var I: integer;
var S: string;
function GetSignStr(Lead: boolean; D: double): string;
{Get the sign of coefficient}
begin
Result:='';
if D>0 then
begin
if not Lead then Result:=' + ';
end
else
begin
Result:='-';
if not Lead then Result:=' - ';
end;
end;
begin
Result:='';
{Get each coefficient}
for I:=High(D) downto 0 do
begin
{Ignore zero values}
if D[I]=0 then continue;
{Get sign and coefficient}
S:=GetSignStr(Result='',D[I]);
S:=S+FloatToStrF(abs(D[I]),ffFixed,18,0);
{Combine with exponents }
if I>1 then Result:=Result+Format('%SX^%d',[S,I])
else if I=1 then Result:=Result+Format('%SX',[S,I])
else Result:=Result+Format('%S',[S]);
end;
end;
procedure ShowDerivative(Memo: TMemo; Poly: array of double);
{Show polynomial and and derivative}
var D: TDoubleDynArray;
begin
D:=GetDerivative(Poly);
Memo.Lines.Add('Polynomial: '+GetPolyStr(Poly));
Memo.Lines.Add('Derivative: '+'['+GetPolyStr(D)+']');
Memo.Lines.Add('');
end;
procedure ShowPolyDerivative(Memo: TMemo);
var D: TDoubleDynArray;
begin
ShowDerivative(Memo,Poly1);
ShowDerivative(Memo,Poly2);
ShowDerivative(Memo,Poly3);
ShowDerivative(Memo,Poly4);
ShowDerivative(Memo,Poly5);
end;
- Output:
Polynomial: 5 Derivative: [] Polynomial: -3X + 4 Derivative: [-3] Polynomial: 5X^2 + 6X - 1 Derivative: [10X + 6] Polynomial: 1X^3 - 2X^2 + 3X - 4 Derivative: [3X^2 - 4X + 3] Polynomial: -1X^4 - 1X^3 + 1X + 1 Derivative: [-4X^3 - 3X^2 + 1] Elapsed Time: 17.842 ms.
F#
// Polynomial derivative. Nigel Galloway: January 4th., 2023
let n=[[5];[4;-3];[-1;6;5];[-4;3;-2;1];[1;1;0;-1;-1]]|>List.iter((List.mapi(fun n g->n*g)>>List.skip 1>>printfn "%A"))
- Output:
[] [-3] [6; 10] [3; -4; 3] [1; 0; -3; -4]
Factor
USING: generalizations kernel math.polynomials prettyprint ;
{ 5 }
{ 4 -3 }
{ -1 6 5 }
{ -4 3 -2 1 }
{ 1 1 0 -1 -1 }
[ pdiff ] 5 napply .s clear
- Output:
{ } { -3 } { 6 10 } { 3 -4 3 } { 1 0 -3 -4 }
The implementation of pdiff
:
USING: kernel math.vectors sequences ;
IN: math.polynomials
: pdiff ( p -- p' ) dup length <iota> v* rest ;
FreeBASIC
sub polydiff( p() as integer )
'differentiates the polynomial
'p(0) + p(1)x + p(2)x^2 +... + p(n)x^n
'in place
dim as integer i, n = ubound(p)
if n=0 then
p(0)=0
return
end if
for i = 0 to n - 1
p(i) = (i+1)*p(i+1)
next i
redim preserve p(0 to n-1)
return
end sub
sub print_poly( p() as integer )
'quick and dirty display of the poly
if ubound(p)=0 and p(0)=0 then
print 0
return
end if
for i as integer = 0 to ubound(p)
if i = 0 then print p(i);" ";
if i = 1 and p(i)>0 then print using "+ #x";p(i);
if i = 1 and p(i)<0 then print using "- #x";-p(i);
if i > 1 and p(i)>0 then print using "+ #x^#";p(i);i;
if i > 1 and p(i)<0 then print using "- #x^#";-p(i);i;
next i
print
end sub
'test cases
redim as integer p(0)
p(0) = 5
print_poly(p())
print "Differentiates to "
polydiff(p())
print_poly(p()): print
redim as integer p(1)
p(0) = 4 : p(1) = -3
print_poly(p())
print "Differentiates to "
polydiff(p())
print_poly(p()): print
redim as integer p(2)
p(0) = -1 : p(1) = 6 : p(2) = 5
print_poly(p())
print "Differentiates to "
polydiff(p())
print_poly(p()): print
redim as integer p(3)
p(0) = 4 : p(1) = 3 : p(2) = -2 : p(3) = 1
print_poly(p())
print "Differentiates to "
polydiff(p())
print_poly(p()): print
redim as integer p(4)
p(0) = 1 : p(1) = 1 : p(2) = 0 : p(3) = -1 : p(4) = -1
print_poly(p())
print "Differentiates to "
polydiff(p())
print_poly(p()): print
- Output:
5 Differentiates to 0
4 - 3x Differentiates to -3
-1 + 6x+ 5x^2 Differentiates to 6 + %10x
4 + 3x- 2x^2+ 1x^3 Differentiates to 3 - 4x+ 3x^2
1 + 1x- 1x^3- 1x^4 Differentiates to
1 - 3x^2- 4x^3
Go
package main
import (
"fmt"
"strings"
)
func derivative(p []int) []int {
if len(p) == 1 {
return []int{0}
}
d := make([]int, len(p)-1)
copy(d, p[1:])
for i := 0; i < len(d); i++ {
d[i] = p[i+1] * (i + 1)
}
return d
}
var ss = []string{"", "", "\u00b2", "\u00b3", "\u2074", "\u2075", "\u2076", "\u2077", "\u2078", "\u2079"}
// for n <= 20
func superscript(n int) string {
if n < 10 {
return ss[n]
}
if n < 20 {
return ss[1] + ss[n-10]
}
return ss[2] + ss[0]
}
func abs(n int) int {
if n < 0 {
return -n
}
return n
}
func polyPrint(p []int) string {
if len(p) == 1 {
return fmt.Sprintf("%d", p[0])
}
var terms []string
for i := 0; i < len(p); i++ {
if p[i] == 0 {
continue
}
c := fmt.Sprintf("%d", p[i])
if i > 0 && abs(p[i]) == 1 {
c = ""
if p[i] != 1 {
c = "-"
}
}
x := "x"
if i <= 0 {
x = ""
}
terms = append(terms, fmt.Sprintf("%s%s%s", c, x, superscript(i)))
}
for i, j := 0, len(terms)-1; i < j; i, j = i+1, j-1 {
terms[i], terms[j] = terms[j], terms[i]
}
s := strings.Join(terms, "+")
return strings.Replace(s, "+-", "-", -1)
}
func main() {
fmt.Println("The derivatives of the following polynomials are:\n")
polys := [][]int{{5}, {4, -3}, {-1, 6, 5}, {-4, 3, -2, 1}, {1, 1, 0, -1, -1}}
for _, poly := range polys {
deriv := derivative(poly)
fmt.Printf("%v -> %v\n", poly, deriv)
}
fmt.Println("\nOr in normal mathematical notation:\n")
for _, poly := range polys {
deriv := derivative(poly)
fmt.Println("Polynomial : ", polyPrint(poly))
fmt.Println("Derivative : ", polyPrint(deriv), "\n")
}
}
- Output:
The derivatives of the following polynomials are: [5] -> [0] [4 -3] -> [-3] [-1 6 5] -> [6 10] [-4 3 -2 1] -> [3 -4 3] [1 1 0 -1 -1] -> [1 0 -3 -4] Or in normal mathematical notation: Polynomial : 5 Derivative : 0 Polynomial : -3x+4 Derivative : -3 Polynomial : 5x²+6x-1 Derivative : 10x+6 Polynomial : x³-2x²+3x-4 Derivative : 3x²-4x+3 Polynomial : -x⁴-x³+x+1 Derivative : -4x³-3x²+1
Haskell
deriv = zipWith (*) [1..] . tail
main = mapM_ (putStrLn . line) ps
where
line p = "\np = " ++ show p ++ "\np' = " ++ show (deriv p)
ps = [[5],[4,-3],[-1,6,5],[-4,3,-2,1],[1,1,0,-1,-1]]
main p = [5] p' = [] p = [4,-3] p' = [-3] p = [-1,6,5] p' = [6,10] p = [-4,3,-2,1] p' = [3,-4,3] p = [1,1,0,-1,-1] p' = [1,0,-3,-4]
With fancy output
{-# language LambdaCase #-}
showPoly [] = "0"
showPoly p = foldl1 (\r -> (r ++) . term) $
dropWhile null $
foldMap (\(c, n) -> [show c ++ expt n]) $
zip p [0..]
where
expt = \case 0 -> ""
1 -> "*x"
n -> "*x^" ++ show n
term = \case [] -> ""
'0':'*':t -> ""
'-':'1':'*':t -> " - " ++ t
'1':'*':t -> " + " ++ t
'-':t -> " - " ++ t
t -> " + " ++ t
main = mapM_ (putStrLn . line) ps
where
line p = "\np = " ++ showPoly p ++ "\np' = " ++ showPoly (deriv p)
ps = [[5],[4,-3],[-1,6,5],[-4,3,-2,1],[1,1,0,-1,-1]]
main p = 5 p' = 0 p = 4 - 3*x p' = -3 p = -1 + 6*x + 5*x^2 p' = 6 + 10*x p = -4 + 3*x - 2*x^2 + x^3 p' = 3 - 4*x + 3*x^2 p = 1 + 1*x - 1*x^3 - 1*x^4 p' = 1 - 3*x^2 - 4*x^
J
Implementation:
pderiv=: -@(1 >. _1+#) {. (* i.@#)
Task examples:
pderiv 5
0
pderiv 4 _3
_3
pderiv _1 6 5
6 10
pderiv _4 3 _2 1
3 _4 3
pderiv 1 1 _1 _1
1 _2 _3
Note also that J's p.
can be used to apply one of these polynomials to an argument. For example:
5 p. 2 3 5 7
5 5 5 5
(pderiv 5) p. 2 3 5 7
0 0 0 0
4 _3 p. 2 3 5 7
_2 _5 _11 _17
(pderiv 4 _3) p. 2 3 5 7
_3 _3 _3 _3
jq
Adapted from Wren (with corrections)
Works with gojq, the Go implementation of jq
The following definition of polyPrint has no restriction on the degree of the polynomial.
# The input should be a non-empty array of integers representing a polynomial.
# The output likewise represents its derivative.
def derivative:
. as $p
| if length == 1 then [0]
else reduce range(0; length-1) as $i (.[1:];
.[$i] = $p[$i+1] * ($i + 1) )
end;
def polyPrint:
def ss: ["\u2070", "\u00b9", "\u00b2", "\u00b3", "\u2074", "\u2075", "\u2076", "\u2077", "\u2078", "\u2079"];
def digits: tostring | explode[] | [.] | implode | tonumber;
ss as $ss
| def superscript:
if . <= 1 then ""
else reduce digits as $d (""; . + $ss[$d] )
end;
. as $p
| if length == 1 then .[0] | tostring
else reduce range(0; length) as $i ([];
if $p[$i] != 0
then (if $i > 0 then "x" else "" end) as $x
| ( if $i > 0 and ($p[$i]|length) == 1
then (if $p[$i] == 1 then "" else "-" end)
else ($p[$i]|tostring)
end ) as $c
| . + ["\($c)\($x)\($i|superscript)"]
else . end )
| reverse
| join("+")
| gsub("\\+-"; "-")
end ;
def task:
def polys: [ [5], [4, -3], [-1, 6, 5], [-4, 3, -2, 1], [1, 1, 0, -1, -1] ];
"Example polynomials and their derivatives:\n",
( polys[] | "\(.) -> \(derivative)" ),
"\nOr in normal mathematical notation:\n",
( polys[]
| "Polynomial : \(polyPrint)",
"Derivative : \(derivative|polyPrint)\n" ) ;
task
- Output:
Example polynomials and their derivatives: [5] -> [0] [4,-3] -> [-3] [-1,6,5] -> [6,10] [-4,3,-2,1] -> [3,-4,3] [1,1,0,-1,-1] -> [1,0,-3,-4] Or in normal mathematical notation: Polynomial : 5 Derivative : 0 Polynomial : -3x+4 Derivative : -3 Polynomial : 5x²+6x-1 Derivative : 10x+6 Polynomial : x³-2x²+3x-4 Derivative : 3x²-4x+3 Polynomial : -x⁴-x³+x+1 Derivative : -4x³-3x²+1
Julia
using Polynomials
testcases = [
("5", [5]),
("-3x+4", [4, -3]),
("5x2+6x-1", [-1, 6, 5]),
("x3-2x2+3x-4", [-4, 3, -2, 1]),
("-x4-x3+x+1", [1, 1, 0, -1, -1]),
]
for (s, coef) in testcases
println("Derivative of $s: ", derivative(Polynomial(coef)))
end
- Output:
Derivative of 5: 0 Derivative of -3x+4: -3 Derivative of 5x2+6x-1: 6 + 10*x Derivative of x3-2x2+3x-4: 3 - 4*x + 3*x^2 Derivative of -x4-x3+x+1: 1 - 3*x^2 - 4*x^3
Nim
import std/sequtils
type
Polynomial[T] = object
coeffs: seq[T]
Term = tuple[coeff, exp: int]
template `[]`[T](poly: Polynomial[T]; idx: Natural): T =
poly.coeffs[idx]
template `[]=`[T](poly: var Polynomial; idx: Natural; val: T) =
poly.coeffs[idx] = val
template degree(poly: Polynomial): int =
poly.coeffs.high
func newPolynomial[T](coeffs: openArray[T]): Polynomial[T] =
## Create a polynomial from a list of coefficients.
result.coeffs = coeffs.toSeq
func newPolynomial[T](degree: Natural = 0): Polynomial[T] =
## Create a polynomial with given degree.
## Coefficients are all zeroes.
result.coeffs = newSeq[T](degree + 1)
const Superscripts: array['0'..'9', string] = ["⁰", "¹", "²", "³", "⁴", "⁵", "⁶", "⁷", "⁸", "⁹"]
func superscript(n: Natural): string =
## Return the Unicode string to use to represent an exponent.
if n == 1:
return ""
for d in $n:
result.add Superscripts[d]
func `$`(term: Term): string =
## Return the string representation of a term.
if term.coeff == 0: "0"
elif term.exp == 0: $term.coeff
else:
let base = 'x' & superscript(term.exp)
if term.coeff == 1: base
elif term.coeff == -1: '-' & base
else: $term.coeff & base
func `$`[T](poly: Polynomial[T]): string =
## Return the string representation of a polynomial.
for idx in countdown(poly.degree, 0):
let coeff = poly[idx]
var term: Term = (coeff: coeff, exp: idx)
if result.len == 0:
result.add $term
elif coeff > 0:
result.add '+'
result.add $term
elif coeff < 0:
term.coeff = -term.coeff
result.add '-'
result.add $term
func derivative[T](poly: Polynomial[T]): Polynomial[T] =
## Return the derivative of a polynomial.
if poly.degree == 0: return newPolynomial[T]()
result = newPolynomial[T](poly.degree - 1)
for degree in 1..poly.degree:
result[degree - 1] = degree * poly[degree]
for coeffs in @[@[5], @[4, -3], @[-1, 6, 5], @[-4, 3, -2, 1], @[1, 1, 0, -1, -1]]:
let poly = newPolynomial(coeffs)
echo "Polynomial: ", poly
echo "Derivative: ", poly.derivative
echo()
- Output:
Polynomial: 5 Derivative: 0 Polynomial: -3x+4 Derivative: -3 Polynomial: 5x²+6x-1 Derivative: 10x+6 Polynomial: x³-2x²+3x-4 Derivative: 3x²-4x+3 Polynomial: -x⁴-x³+x+1 Derivative: -4x³-3x²+1
Perl
use strict;
use warnings;
use feature 'say';
use utf8;
binmode(STDOUT, ':utf8');
sub pp {
my(@p) = @_;
return 0 unless @p;
my @f = $p[0];
push @f, ($p[$_] != 1 and $p[$_]) . 'x' . ($_ != 1 and (qw<⁰ ¹ ² ³ ⁴ ⁵ ⁶ ⁷ ⁸ ⁹>)[$_])
for grep { $p[$_] != 0 } 1 .. $#p;
( join('+', reverse @f) =~ s/-1x/-x/gr ) =~ s/\+-/-/gr
}
for ([5], [4,-3], [-1,3,-2,1], [-1,6,5], [1,1,0,-1,-1]) {
my @poly = @$_;
say 'Polynomial: ' . join(', ', @poly) . ' ==> ' . pp @poly;
$poly[$_] *= $_ for 0 .. $#poly;
shift @poly;
say 'Derivative: ' . (@poly ? join', ', @poly : 0) . ' ==> ' . pp(@poly) . "\n";
}
- Output:
Polynomial: 5 ==> 5 Derivative: 0 ==> 0 Polynomial: 4, -3 ==> -3x+4 Derivative: -3 ==> -3 Polynomial: -1, 3, -2, 1 ==> x³-2x²+3x-1 Derivative: 3, -4, 3 ==> 3x²-4x+3 Polynomial: -1, 6, 5 ==> 5x²+6x-1 Derivative: 6, 10 ==> 10x+6 Polynomial: 1, 1, 0, -1, -1 ==> -x⁴-x³+x+1 Derivative: 1, 0, -3, -4 ==> -4x³-3x²+1
Phix
-- -- demo\rosetta\Polynomial_derivative.exw -- with javascript_semantics function derivative(sequence p) if p={} then return {} end if sequence r = repeat(0,length(p)-1) for i=1 to length(r) do r[i] = i*p[i+1] end for return r end function function poly(sequence si) -- display helper, copied from demo\rosetta\Polynomial_long_division.exw string r = "" for t=length(si) to 1 by -1 do integer sit = si[t] if sit!=0 then if sit=1 and t>1 then r &= iff(r=""? "":" + ") elsif sit=-1 and t>1 then r &= iff(r=""?"-":" - ") else if r!="" then r &= iff(sit<0?" - ":" + ") sit = abs(sit) end if r &= sprintf("%d",sit) end if r &= iff(t>1?"x"&iff(t>2?sprintf("^%d",t-1):""):"") end if end for if r="" then r="0" end if return r end function constant tests = {{5},{4,-3},{-1,6,5},{-4,3,-2,1},{1,1,0,-1,-1}} for i=1 to length(tests) do sequence t = tests[i], r = derivative(t) printf(1,"%20s ==> %16s (internally %v -> %v)\n",{poly(t),poly(r),t,r}) end for ?"done" {} = wait_key()
- Output:
5 ==> 0 (internally {5} -> {}) -3x + 4 ==> -3 (internally {4,-3} -> {-3}) 5x^2 + 6x - 1 ==> 10x + 6 (internally {-1,6,5} -> {6,10}) x^3 - 2x^2 + 3x - 4 ==> 3x^2 - 4x + 3 (internally {-4,3,-2,1} -> {3,-4,3}) -x^4 - x^3 + x + 1 ==> -4x^3 - 3x^2 + 1 (internally {1,1,0,-1,-1} -> {1,0,-3,-4})
Raku
use Lingua::EN::Numbers:ver<2.8+>;
sub pretty (@poly) {
join( '+', (^@poly).reverse.map: { @poly[$_] ~ "x{.&super}" } )\
.subst(/['+'|'-']'0x'<[⁰¹²³⁴⁵⁶⁷⁸⁹]>*/, '', :g).subst(/'x¹'<?before <-[⁰¹²³⁴⁵⁶⁷⁸⁹]>>/, 'x')\
.subst(/'x⁰'$/, '').subst(/'+-'/, '-', :g).subst(/(['+'|'-'|^])'1x'/, {"$0x"}, :g) || 0
}
for [5], [4,-3], [-1,3,-2,1], [-1,6,5], [1,1,0,-1,-1] -> $test {
say "Polynomial: " ~ "[{$test.join: ','}] ➡ " ~ pretty $test;
my @poly = |$test;
(^@poly).map: { @poly[$_] *= $_ };
shift @poly;
say "Derivative: " ~ "[{@poly.join: ','}] ➡ " ~ pretty @poly;
say '';
}
- Output:
Polynomial: [5] ➡ 5 Derivative: [] ➡ 0 Polynomial: [4,-3] ➡ -3x+4 Derivative: [-3] ➡ -3 Polynomial: [-1,3,-2,1] ➡ x³-2x²+3x-1 Derivative: [3,-4,3] ➡ 3x²-4x+3 Polynomial: [-1,6,5] ➡ 5x²+6x-1 Derivative: [6,10] ➡ 10x+6 Polynomial: [1,1,0,-1,-1] ➡ -x⁴-x³+x+1 Derivative: [1,0,-3,-4] ➡ -4x³-3x²+1
RPL
RPL can symbolically derivate many functions, including polynoms.
Built-in derivation
Formal derivation can be performed by the ∂
operator directly from the interpreter command line. Invoking then the COLCT
function allows to simplify the formula but sometimes changes the order of terms, as shown with the last example.
5 'x' ∂ COLCT '-3*x+4' 'x' ∂ COLCT '5x^2+6*x-1' 'x' ∂ COLCT 'x^3-2*x^2+3*x-4' 'x' ∂ COLCT '-x^4-x^3+x+1' 'x' ∂ DUP COLCT
- Output:
6: 0 5: -3 4: '10*x+6' 3: '3*x^2-4*x+3' 2: '-(4*x^3)-3*x^2+1' 1: '1-4*x^3-3*x^2'
Classical programming
Assuming we ignore the existence of the ∂
operator, here is a typical RPL program that handles polynoms as lists of scalars, to be completed by another program to display the list on a fancier way.
≪ → coeffs ≪ IF coeffs SIZE 1 - THEN { } 1 LAST FOR j coeffs j 1 + GET j 1 MAX * + NEXT ELSE { 0 } END ≫ ≫ 'DPDX' STO
{5} DPDX {4 -3} DPDX {-1 6 5} DPDX {-4 3 -2 1} DPDX {1 1 0 -1 -1} DPDX
- Output:
5: { 0 } 4: { -3 } 3: { 6 10 } 2: { 3 -4 3 } 1: { 1 0 -3 -4 }
Fancy output
≪ → coeffs ≪ coeffs 1 GET coeffs SIZE 2 FOR j coeffs j GET ‘x’ j 1 - ^ * SWAP + -1 STEP ≫ COLCT ≫ ‘→EQ’ STO
{1 1 0 -1 -1} DPDX DUP →EQ
- Output:
2: { 1 0 -3 -4 } 1: '1-3*x^2-4*x^3'
Sidef
func derivative(f) {
Poly(f.coeffs.map_2d{|e,k| [e-1, k*e] }.flat...)
}
var coeffs = [
[5],
[4,-3],
[-1,6,5],
[-4,3,-2,1],
[-1, 6, 5],
[1,1,0,-1,-1],
]
for c in (coeffs) {
var poly = Poly(c.flip)
var derv = derivative(poly)
var d = { derv.coeff(_) }.map(0..derv.degree)
say "Polynomial : #{'%20s' % c} = #{poly}"
say "Derivative : #{'%20s' % d} = #{derv || 0}\n"
}
- Output:
Polynomial : [5] = 5 Derivative : [0] = 0 Polynomial : [4, -3] = -3*x + 4 Derivative : [-3] = -3 Polynomial : [-1, 6, 5] = 5*x^2 + 6*x - 1 Derivative : [6, 10] = 10*x + 6 Polynomial : [-4, 3, -2, 1] = x^3 - 2*x^2 + 3*x - 4 Derivative : [3, -4, 3] = 3*x^2 - 4*x + 3 Polynomial : [-1, 6, 5] = 5*x^2 + 6*x - 1 Derivative : [6, 10] = 10*x + 6 Polynomial : [1, 1, 0, -1, -1] = -x^4 - x^3 + x + 1 Derivative : [1, 0, -3, -4] = -4*x^3 - 3*x^2 + 1
Wren
var derivative = Fn.new { |p|
if (p.count == 1) return [0]
var d = p[1..-1].toList
for (i in 0...d.count) d[i] = p[i+1] * (i + 1)
return d
}
var ss = ["", "", "\u00b2", "\u00b3", "\u2074", "\u2075", "\u2076", "\u2077", "\u2078", "\u2079"]
// for n <= 20
var superscript = Fn.new { |n| (n < 10) ? ss[n] : (n < 20) ? ss[1] + ss[n - 10] : ss[2] + ss[0] }
var polyPrint = Fn.new { |p|
if (p.count == 1) return p[0].toString
var terms = []
for (i in 0...p.count) {
if (p[i] == 0) continue
var c = p[i].toString
if (i > 0 && p[i].abs == 1) c = (p[i] == 1) ? "" : "-"
var x = (i > 0) ? "x" : ""
terms.add("%(c)%(x)%(superscript.call(i))")
}
return terms[-1..0].join("+").replace("+-", "-")
}
System.print("The derivatives of the following polynomials are:\n")
var polys = [ [5], [4, -3], [-1, 6, 5], [-4, 3, -2, 1], [1, 1, 0, -1, -1] ]
for (poly in polys) {
var deriv = derivative.call(poly)
System.print("%(poly) -> %(deriv)")
}
System.print("\nOr in normal mathematical notation:\n")
for (poly in polys) {
var deriv = derivative.call(poly)
System.print("Polynomial : %(polyPrint.call(poly))")
System.print("Derivative : %(polyPrint.call(deriv))\n")
}
- Output:
The derivatives of the following polynomials are: [5] -> [0] [4, -3] -> [-3] [-1, 6, 5] -> [6, 10] [-4, 3, -2, 1] -> [3, -4, 3] [1, 1, 0, -1, -1] -> [1, 0, -3, -4] Or in normal mathematical notation: Polynomial : 5 Derivative : 0 Polynomial : -3x+4 Derivative : -3 Polynomial : 5x²+6x-1 Derivative : 10x+6 Polynomial : x³-2x²+3x-4 Derivative : 3x²-4x+3 Polynomial : -x⁴-x³+x+1 Derivative : -4x³-3x²+1
XPL0
int IntSize, Cases, Case, Len, Deg, Coef;
[IntSize:= @Case - @Cases;
Cases:=[[ 5],
[ 4, -3],
[-1, 6, 5],
[-4, 3, -2, 1],
[ 1, 1, 0, -1, -1],
[ 0]];
for Case:= 0 to 5-1 do
[Len:= (Cases(Case+1) - Cases(Case)) / IntSize;
for Deg:= 0 to Len-1 do
[Coef:= Cases(Case, Deg);
if Deg = 0 then Text(0, "[")
else [IntOut(0, Coef*Deg);
if Deg < Len-1 then
Text(0, ", ");
];
];
Text(0, "]^M^J");
];
]
- Output:
[] [-3] [6, 10] [3, -4, 3] [1, 0, -3, -4]