Skip to content

Commit

Permalink
Merge 829b5c4 into ed6d93f
Browse files Browse the repository at this point in the history
  • Loading branch information
SergeStinckwich committed Aug 5, 2019
2 parents ed6d93f + 829b5c4 commit ed314c2
Show file tree
Hide file tree
Showing 9 changed files with 707 additions and 417 deletions.
15 changes: 15 additions & 0 deletions src/Math-AutomaticDifferenciation/Number.extension.st
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
Extension { #name : #Number }

{ #category : #'*Math-AutomaticDifferenciation' }
Number >> addDualNumber: aDualNumber [
^ aDualNumber class
value: self + aDualNumber value
eps: aDualNumber eps
]

{ #category : #'*Math-AutomaticDifferenciation' }
Number >> multiplyDualNumber: aDualNumber [
^ aDualNumber class
value: aDualNumber value * self
eps: aDualNumber eps * self
]
104 changes: 69 additions & 35 deletions src/Math-AutomaticDifferenciation/PMDualNumber.class.st
Original file line number Diff line number Diff line change
@@ -1,26 +1,28 @@
"
In linear algebra, dual numbers extend the real numbers by adjoining one new element ε with the property ε^2 = 0 (ε is nilpotent).
See here: https://en.wikipedia.org/wiki/Dual_number^
PMDualNumbers can be used to calculate the first derivative if one creates them this way:
PMDualNumber value: aNumber eps: derivativeOfaNumber (1 if the derivative with respect to aNumber is calculated, 0 otherwise)
PMDualNumbers can be mixed with Numbers.
"
Class {
#name : #PMDualNumber,
#superclass : #Magnitude,
#superclass : #Number,
#instVars : [
'value',
'eps'
],
#classVars : [
'ZeroApproximation'
],
#category : 'Math-AutomaticDifferenciation'
#category : #'Math-AutomaticDifferenciation'
}

{ #category : #'instance creation' }
PMDualNumber class >> value:aValue [
"for entering a constant"
^(self new value: aValue) eps: 0
PMDualNumber class >> value: aValue [
^ (self new value: aValue) eps: 0
]

{ #category : #'instance creation' }
Expand All @@ -41,31 +43,24 @@ PMDualNumber class >> zeroApproximation: aSmallNumber [
]

{ #category : #arithmetic }
PMDualNumber >> * aDualNumber [
^aDualNumber isDualNumber
ifFalse:[self class value: value * aDualNumber eps: eps *aDualNumber]
ifTrue:[self class value: value * aDualNumber value eps: eps * aDualNumber value + (aDualNumber eps *value)]
PMDualNumber >> * aNumber [
^ aNumber multiplyDualNumber: self
]

{ #category : #arithmetic }
PMDualNumber >> + aDualNumber [
^aDualNumber isDualNumber
ifFalse:[self class value: value + aDualNumber eps: eps]
ifTrue:[self class value: value + aDualNumber value eps: eps + aDualNumber eps]
PMDualNumber >> + aNumber [
^ aNumber addDualNumber: self
]

{ #category : #arithmetic }
PMDualNumber >> - aDualNumber [
^aDualNumber isDualNumber
ifFalse:[self class value: value - aDualNumber eps: eps]
ifTrue:[self class value: value - aDualNumber value eps: eps - aDualNumber eps]
PMDualNumber >> - aNumber [
^ aNumber negated addDualNumber: self
]

{ #category : #arithmetic }
PMDualNumber >> / aDualNumber [
^aDualNumber isDualNumber
ifFalse:[self class value: value / aDualNumber eps: eps /aDualNumber]
ifTrue:[self class value: value / aDualNumber value eps:( eps * aDualNumber value - (aDualNumber eps *value))/aDualNumber value squared]
PMDualNumber >> / aNumber [

^ aNumber reciprocal multiplyDualNumber: self
]

{ #category : #testing }
Expand All @@ -84,9 +79,26 @@ PMDualNumber >> abs [

]

{ #category : #arithmetic }
PMDualNumber >> absSquared [
^ (self conjugated * self) real
]

{ #category : #converting }
PMDualNumber >> adaptToNumber: rcvr andSend: selector [
^ (self class value:rcvr) perform: selector with: self
PMDualNumber >> adaptToFraction: rcvr andSend: selector [
^ (self class value: rcvr) perform: selector with: self
]

{ #category : #converting }
PMDualNumber >> adaptToInteger: rcvr andSend: selector [
^ (self class value: rcvr) perform: selector with: self
]

{ #category : #arithmetic }
PMDualNumber >> addDualNumber: aDualNumber [
^ self class
value: value + aDualNumber value
eps: eps + aDualNumber eps
]

{ #category : #'mathematical functions' }
Expand All @@ -105,9 +117,7 @@ PMDualNumber >> arcSin [

{ #category : #'mathematical functions' }
PMDualNumber >> arcTan [
^ self class
value: value arcTan
eps: eps / (1 + value squared)
^ self class value: value arcTan eps: eps / (1 + value squared)
]

{ #category : #converting }
Expand All @@ -120,11 +130,16 @@ PMDualNumber >> asInteger [
^ value asInteger
]

{ #category : #'mathematical functions' }
PMDualNumber >> conjugated [
^ self class
value: self value conjugated
eps: self eps asComplex conjugated
]

{ #category : #'mathematical functions' }
PMDualNumber >> cos [
^ self class
value: value cos
eps: eps * value sin negated
^ self class value: value cos eps: eps * value sin negated
]

{ #category : #accessing }
Expand All @@ -133,8 +148,8 @@ PMDualNumber >> eps [
]

{ #category : #accessing }
PMDualNumber >> eps: anObject [
eps := anObject
PMDualNumber >> eps: aNumber [
eps := aNumber
]

{ #category : #comparing }
Expand All @@ -154,7 +169,7 @@ PMDualNumber >> exp [
^ self class value: e eps: eps * e
]

{ #category : #hash }
{ #category : #comparing }
PMDualNumber >> hash [
^ value hash
]
Expand Down Expand Up @@ -193,6 +208,13 @@ PMDualNumber >> ln [
^ self class value: value ln eps: eps / v
]

{ #category : #arithmetic }
PMDualNumber >> multiplyDualNumber: aDualNumber [
^self class
value: value * aDualNumber value
eps: eps * aDualNumber value + (aDualNumber eps * value)
]

{ #category : #arithmetic }
PMDualNumber >> negated [
^self class value: value negated eps: eps negated
Expand Down Expand Up @@ -226,15 +248,22 @@ PMDualNumber >> printOn: aStream [
nextPutAll: ')'
]

{ #category : #printing }
PMDualNumber >> printOn: aStream base: base [
self printOn: aStream
]

{ #category : #'mathematical functions' }
PMDualNumber >> raisedTo: aDualNumber [
| v |
value = 0
ifTrue: [ ^ PMDualNumber value: 0 ].
ifTrue: [ ^ self class value: 0 ].
v := value raisedTo: aDualNumber value.
aDualNumber isDualNumber
ifFalse: [ ^ self class value: v eps: v / value * eps * aDualNumber ].
^ self class value: v eps: v * (eps * aDualNumber value / value + (aDualNumber eps * value ln))
^ self class
value: v
eps: v * (eps * aDualNumber value / value + (aDualNumber eps * value ln))
]

{ #category : #'mathematical functions' }
Expand All @@ -244,9 +273,14 @@ PMDualNumber >> raisedToInteger: anInteger [
ifFalse: [ self class value: (value raisedToInteger: anInteger) eps: anInteger * eps * (value raisedToInteger: anInteger - 1) ]
]

{ #category : #converting }
PMDualNumber >> real [
^ self class value: self value real eps: self eps asComplex real
]

{ #category : #arithmetic }
PMDualNumber >> reciprocal [
^self class value: 1/value eps: eps /value squared negated
^ self class value: 1 / value eps: eps / value squared negated
]

{ #category : #'mathematical functions' }
Expand Down
6 changes: 4 additions & 2 deletions src/Math-AutomaticDifferenciation/PMGradient.class.st
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
"
Gradient calcs the gradient of a function of a SequentialCollection of Numbers. example: f(x,y)=x^2 * y
Computes the gradient of a function of a Collection of Numbers.
Example: f(x,y)=x^2 * y
g := PMGradient of:[:x|x first squared * x second].
g value:#(3 2). ""-->#(12 9)""
g value:#(1 1). ""-->#(2 1)""
Expand All @@ -11,7 +13,7 @@ Class {
#instVars : [
'function'
],
#category : 'Math-AutomaticDifferenciation'
#category : #'Math-AutomaticDifferenciation'
}

{ #category : #'instance creation' }
Expand Down
Loading

0 comments on commit ed314c2

Please sign in to comment.