Skip to content

Commit

Permalink
Merge pull request #323 from PolyMathOrg/refactor-polynomials
Browse files Browse the repository at this point in the history
Refactor polynomials
  • Loading branch information
hernanmd authored Jan 3, 2024
2 parents 761fb9a + 85c2398 commit 11c8e01
Show file tree
Hide file tree
Showing 3 changed files with 163 additions and 111 deletions.
7 changes: 7 additions & 0 deletions src/Math-Numerical/PMNewtonZeroFinder.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,13 @@ PMNewtonZeroFinder >> initialize [
^ self
]

{ #category : #operation }
PMNewtonZeroFinder >> rootOf: function [
self setFunction: function;
setDerivative: function derivative.
^ self evaluate.
]

{ #category : #initialization }
PMNewtonZeroFinder >> setDerivative: aBlock [
"Defines the derivative of the function for which zeroes will be found.
Expand Down
15 changes: 6 additions & 9 deletions src/Math-Polynomials/PMPolynomial.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -239,20 +239,17 @@ PMPolynomial >> roots [
{ #category : #information }
PMPolynomial >> roots: aNumber [

| pol roots root rootFinder |
| polynomial roots root rootFinder |
rootFinder := PMNewtonZeroFinder with: aNumber.
pol := self class coefficients:
(coefficients reverse collect: [ :each | each asFloat ]).
polynomial := self class coefficients:
(coefficients reverse collect: [ :each | each asFloat ]).
roots := OrderedCollection new: self degree.
[
rootFinder
setFunction: pol;
setDerivative: pol derivative.
root := rootFinder evaluate.
root := rootFinder rootOf: polynomial.
rootFinder hasConverged ] whileTrue: [
roots add: root.
pol := pol deflatedAt: root.
pol degree > 0 ifFalse: [ ^ roots ] ].
polynomial := polynomial deflatedAt: root.
polynomial degree strictlyPositive ifFalse: [ ^ roots ] ].
^ roots
]

Expand Down
252 changes: 150 additions & 102 deletions src/Math-Tests-Polynomials/PMPolynomialTest.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Class {
#category : #'Math-Tests-Polynomials'
}

{ #category : #comparing }
{ #category : #'testing - comparing' }
PMPolynomialTest >> testIsZero [
| p1 p2 |
p1 := PMPolynomial coefficients: #(0 0 0 0 0).
Expand All @@ -13,32 +13,50 @@ PMPolynomialTest >> testIsZero [
self shouldnt: [ p2 isZero ]
]

{ #category : #'function evaluation' }
{ #category : #'testing - addition' }
PMPolynomialTest >> testPolynomialAddition [
| polynomial |
polynomial := (PMPolynomial coefficients: #(2 -3 1))
+ (PMPolynomial coefficients: #(-3 7 2 1)).
self assert: (polynomial at: 0) equals: -1.
self assert: (polynomial at: 1) equals: 4.
self assert: (polynomial at: 2) equals: 3.
self assert: (polynomial at: 3) equals: 1.

| polynomial expected p q |
p := PMPolynomial coefficients: #( 2 -3 1 ).
q := PMPolynomial coefficients: #( -3 7 2 1 ).
polynomial := p + q.
expected := PMPolynomial coefficients: #( -1 4 3 1 ).
self assert: polynomial equals: expected.
self assert: (polynomial at: 4) equals: 0
]

{ #category : #'function evaluation' }
{ #category : #'testing - addition' }
PMPolynomialTest >> testPolynomialAdditionIsCommutative [

| p q expected |
p := PMPolynomial coefficients: #(1 2 4 8).
q := PMPolynomial coefficients: #(-1 3 7 -4).

expected := PMPolynomial coefficients: #(0 5 11 4).
self assert: p + q equals: expected.
self assert: q + p equals: expected
]

{ #category : #'testing - algebra' }
PMPolynomialTest >> testPolynomialDerivative [
"Code example 2.3"
"
p(x) = x^3 + 2x^2 + 7x - 3, therefore:
p'(x) = 3x^2 + 4x + 7
"

| polynomial |
polynomial := (PMPolynomial coefficients: #(-3 7 2 1)) derivative.
self assert: (polynomial at: 0) equals: 7.
self assert: (polynomial at: 1) equals: 4.
self assert: (polynomial at: 2) equals: 3.
self assert: (polynomial at: 3) equals: 0.
self assert: (polynomial at: 4) equals: 0
| p derivative expectedDerivative |
p := PMPolynomial coefficients: #( -3 7 2 1 ).

derivative := p derivative.

expectedDerivative := PMPolynomial coefficients: #( 7 4 3 ).
self assert: derivative equals: expectedDerivative.
self assert: (derivative at: 3) equals: 0.
self assert: (derivative at: 4) equals: 0
]

{ #category : #'function evaluation' }
{ #category : #'testing - division' }
PMPolynomialTest >> testPolynomialDivision [
| pol1 pol2 polynomial |
pol1 := PMPolynomial coefficients: #(2 -3 1).
Expand All @@ -53,7 +71,7 @@ PMPolynomialTest >> testPolynomialDivision [
self assert: (polynomial at: 6) equals: 0
]

{ #category : #'function evaluation' }
{ #category : #'testing - division' }
PMPolynomialTest >> testPolynomialDivisionBug [
"identify an error when trying to create a zero dividend"

Expand All @@ -63,7 +81,7 @@ PMPolynomialTest >> testPolynomialDivisionBug [
self shouldnt: [ pol1 / pol2 ] raise: Error
]

{ #category : #arithmetic }
{ #category : #'testing - arithmetic' }
PMPolynomialTest >> testPolynomialDoubleDispatch [
| n p |
n := 3.2.
Expand All @@ -80,7 +98,7 @@ PMPolynomialTest >> testPolynomialDoubleDispatch [
self assert: n - p equals: (p - n) negated
]

{ #category : #'function evaluation' }
{ #category : #'testing - algebra' }
PMPolynomialTest >> testPolynomialEvaluation [
"Code example 2.2"

Expand All @@ -89,7 +107,7 @@ PMPolynomialTest >> testPolynomialEvaluation [
self assert: 0 equals: (polynomial value: 1)
]

{ #category : #comparing }
{ #category : #'testing - comparing' }
PMPolynomialTest >> testPolynomialHash [
"polynomial hash is hash of coefficient array"

Expand All @@ -105,118 +123,148 @@ PMPolynomialTest >> testPolynomialHash [
self assert: p3 hash equals: p2 hash
]

{ #category : #'function evaluation' }
{ #category : #'testing - algebra' }
PMPolynomialTest >> testPolynomialIntegral [
"Code example 2.3"

| polynomial |
polynomial := (PMPolynomial coefficients: #(-3 7 2 1)) integral.
self assert: (polynomial at: 0) equals: 0.
self assert: (polynomial at: 1) equals: -3.
self assert: (polynomial at: 2) equals: 7 / 2.
self assert: (polynomial at: 3) equals: 2 / 3.
self assert: (polynomial at: 4) equals: 1 / 4.
"
Given p(x) = x^3 + 2x^2 + 7x - 3
then the integral is I(x) = 1/4 x^4 + 2/3 x^3 + 7/2 x^2 - 3x + C, where C is an arbitary
constant.
"

| polynomial expectedCoefficients expected |
polynomial := (PMPolynomial coefficients: #( -3 7 2 1 )) integral.
expectedCoefficients := Array
with: 0
with: -3
with: 7 / 2
with: 2 / 3
with: 1 / 4.
expected := PMPolynomial coefficients: expectedCoefficients.
self assert: polynomial equals: expected .
self assert: (polynomial at: 5) equals: 0
]

{ #category : #'function evaluation' }
{ #category : #'testing - algebra' }
PMPolynomialTest >> testPolynomialIntegralWithConstant [
"Code example 2.3"

| polynomial |
polynomial := (PMPolynomial coefficients: #(-3 7 2 1)) integral: 5.
self assert: (polynomial at: 0) equals: 5.
self assert: (polynomial at: 1) equals: -3.
self assert: (polynomial at: 2) equals: 7 / 2.
self assert: (polynomial at: 3) equals: 2 / 3.
self assert: (polynomial at: 4) equals: 1 / 4.
| polynomial arbitraryConstant integrand expectedCoefficients expected |
arbitraryConstant := 5.
integrand := PMPolynomial coefficients: #( -3 7 2 1 ).
polynomial := integrand integral: arbitraryConstant.
expectedCoefficients := Array
with: arbitraryConstant
with: -3
with: 7 / 2
with: 2 / 3
with: 1 / 4.
expected := PMPolynomial coefficients: expectedCoefficients.
self assert: polynomial equals: expected.
self assert: (polynomial at: 5) equals: 0
]

{ #category : #'function evaluation' }
{ #category : #'testing - multiplication' }
PMPolynomialTest >> testPolynomialMultiplication [
"Code example 2.3"

| pol1 pol2 polynomial |
pol1 := PMPolynomial coefficients: #(2 -3 1).
pol2 := PMPolynomial coefficients: #(-3 7 2 1).
polynomial := pol1 * pol2.
self assert: (polynomial at: 0) equals: -6.
self assert: (polynomial at: 1) equals: 23.
self assert: (polynomial at: 2) equals: -20.
self assert: (polynomial at: 3) equals: 3.
self assert: (polynomial at: 4) equals: -1.
self assert: (polynomial at: 5) equals: 1.
self assert: (polynomial at: 6) equals: 0
| p q product expected |
p := PMPolynomial coefficients: #( 2 -3 1 ).
q := PMPolynomial coefficients: #( -3 7 2 1 ).
product := p * q.
expected := PMPolynomial coefficients: #( -6 23 -20 3 -1 1 ).
self assert: product equals: expected.
]

{ #category : #'testing - multiplication' }
PMPolynomialTest >> testPolynomialMultiplicationIsCommutative [

| expected p q |
"p(x) = (x - 3) (x - 4), q(x) = x^3 + 1 therefore:
p(x) * q(x) = q(x) * p(x) = x^5 - 7 x^4 + 12 x^3 + x^2 - 7x + 12"
p := PMPolynomial coefficients: #( 12 -7 1 ).
q := PMPolynomial coefficients: #( 1 0 0 1 ).

expected := PMPolynomial coefficients: #( 12 -7 1 12 -7 1 ).
self assert: p * q equals: expected.
self assert: q * p equals: expected
]

{ #category : #'function evaluation' }
{ #category : #'testing - addition' }
PMPolynomialTest >> testPolynomialNumberAddition [
| polynomial |
polynomial := 2 + (PMPolynomial coefficients: #(2 -3 1)).
self assert: (polynomial at: 0) equals: 4.
self assert: (polynomial at: 1) equals: -3.
self assert: (polynomial at: 2) equals: 1.

| polynomial expected p |
p := PMPolynomial coefficients: #( 2 -3 1 ).
polynomial := 2 + p.
expected := PMPolynomial coefficients: #( 4 -3 1 ).
self assert: polynomial equals: expected.
self assert: (polynomial at: 3) equals: 0
]

{ #category : #'function evaluation' }
{ #category : #'testing - addition' }
PMPolynomialTest >> testPolynomialNumberAdditionInverse [
| polynomial |
polynomial := (PMPolynomial coefficients: #(2 -3 1)) + 2.
self assert: (polynomial at: 0) equals: 4.
self assert: (polynomial at: 1) equals: -3.
self assert: (polynomial at: 2) equals: 1.

| polynomial expected p |
p := PMPolynomial coefficients: #( 2 -3 1 ).
polynomial := p + 2.
expected := PMPolynomial coefficients: #( 4 -3 1 ).
self assert: polynomial equals: expected.
self assert: (polynomial at: 3) equals: 0
]

{ #category : #'function evaluation' }
{ #category : #'testing - division' }
PMPolynomialTest >> testPolynomialNumberDivision [
| polynomial |
polynomial := (PMPolynomial coefficients: #(2 -3 1)) / 2.
self assert: (polynomial at: 0) equals: 1.
self assert: (polynomial at: 1) equals: -3 / 2.
self assert: (polynomial at: 2) equals: 1 / 2.

| polynomial expected expectedCoefficients p |
p := PMPolynomial coefficients: #( 2 -3 1 ).
polynomial := p / 2.
expectedCoefficients := Array with: 1 with: -3 / 2 with: 1 / 2.
expected := PMPolynomial coefficients: expectedCoefficients.
self assert: polynomial equals: expected.
self assert: (polynomial at: 3) equals: 0
]

{ #category : #'function evaluation' }
{ #category : #'testing - multiplication' }
PMPolynomialTest >> testPolynomialNumberMultiplication [
| polynomial |
polynomial := 2 * (PMPolynomial coefficients: #(2 -3 1)).
self assert: (polynomial at: 0) equals: 4.
self assert: (polynomial at: 1) equals: -6.
self assert: (polynomial at: 2) equals: 2.
self assert: (polynomial at: 3) equals: 0

| product expected p |
p := PMPolynomial coefficients: #( 2 -3 1 ).
product := 2 * p.

expected := PMPolynomial coefficients: #( 4 -6 2 ).
self assert: product equals: expected
]

{ #category : #'function evaluation' }
{ #category : #'testing - multiplication' }
PMPolynomialTest >> testPolynomialNumberMultiplicationInverse [
| polynomial |
polynomial := (PMPolynomial coefficients: #(2 -3 1)) * 2.
self assert: (polynomial at: 0) equals: 4.
self assert: (polynomial at: 1) equals: -6.
self assert: (polynomial at: 2) equals: 2.
self assert: (polynomial at: 3) equals: 0

| product expected p |
p := PMPolynomial coefficients: #( 2 -3 1 ).
product := p * 2.

expected := PMPolynomial coefficients: #( 4 -6 2 ).
self assert: product equals: expected
]

{ #category : #'function evaluation' }
{ #category : #'testing - subtraction' }
PMPolynomialTest >> testPolynomialNumberSubtraction [
| polynomial |
polynomial := 2 - (PMPolynomial coefficients: #(2 -3 1)).
self assert: (polynomial at: 0) equals: 0.
self assert: (polynomial at: 1) equals: 3.
self assert: (polynomial at: 2) equals: -1.

| polynomial expected |
polynomial := 2 - (PMPolynomial coefficients: #( 2 -3 1 )).
expected := PMPolynomial coefficients: #( 0 3 -1 ).
self assert: polynomial equals: expected.
self assert: (polynomial at: 3) equals: 0
]

{ #category : #'function evaluation' }
{ #category : #'testing - subtraction' }
PMPolynomialTest >> testPolynomialNumberSubtractionInverse [
| polynomial |
polynomial := (PMPolynomial coefficients: #(2 -3 1)) - 2.
self assert: (polynomial at: 0) equals: 0.
self assert: (polynomial at: 1) equals: -3.
self assert: (polynomial at: 2) equals: 1.

| polynomial expected |
polynomial := (PMPolynomial coefficients: #( 2 -3 1 )) - 2.
expected := PMPolynomial coefficients: #( 0 -3 1 ).
self assert: polynomial equals: expected.
self assert: (polynomial at: 3) equals: 0
]

Expand Down Expand Up @@ -265,15 +313,15 @@ PMPolynomialTest >> testPolynomialRootsForLinear [
self assert: (roots at: 1) closeTo: -0.5
]

{ #category : #'function evaluation' }
{ #category : #'testing - subtraction' }
PMPolynomialTest >> testPolynomialSubtraction [
| polynomial |
polynomial := (PMPolynomial coefficients: #(2 -3 1))
- (PMPolynomial coefficients: #(-3 7 2 1)).
self assert: (polynomial at: 0) equals: 5.
self assert: (polynomial at: 1) equals: -10.
self assert: (polynomial at: 2) equals: -1.
self assert: (polynomial at: 3) equals: -1.

| polynomial p q expected |
p := PMPolynomial coefficients: #( 2 -3 1 ).
q := PMPolynomial coefficients: #( -3 7 2 1 ).
polynomial := p - q.
expected := PMPolynomial coefficients: #( 5 -10 -1 -1 ).
self assert: polynomial equals: expected.
self assert: (polynomial at: 4) equals: 0
]

Expand Down

0 comments on commit 11c8e01

Please sign in to comment.