Polynomial derivative

From Rosetta Code
Polynomial derivative is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

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

Works with: Delphi version 6.0


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

Translation of: Wren
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: jq

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})

Python

def polynomial_derivative(list_coeff):
    derivative = []
    for i, val in enumerate(list_coeff):
        derivative.append(i*val)
    return derivative[1:]
        

print(polynomial_derivative([5]))
print(polynomial_derivative([4,-3]))
print(polynomial_derivative([-1,6,5]))
print(polynomial_derivative([-4,3,-2,1]))
print(polynomial_derivative([1,1,0,-1,-1]))

Output

[]
[-3]
[6, 10]
[3, -4, 3]
[1, 0, -3, -4]


R

polynomial_derivative<- function(list_coeff){
  derivative = c()
  if (length(list_coeff)>1){
  i <- 1
  for (val in list_coeff[2:length(list_coeff)]){
    derivative <- c(derivative,i*val)
    i <- i+1
  }
  }
derivative
}

print(polynomial_derivative(c(5)))
print(polynomial_derivative(c(4,-3)))
print(polynomial_derivative(c(-1,6,5)))
print(polynomial_derivative(c(-4,3,-2,1)))
print(polynomial_derivative(c(1,1,0,-1,-1)))

Output

NULL
[1] -3
[1]  6 10
[1]  3 -4  3
[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.

Works with: Halcyon Calc version 4.2.7

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]