• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

PolyMathOrg / PolyMath / 4385132063

pending completion
4385132063

push

github

GitHub
Merge pull request #316 from jecisc/divers-cleanings

2977 of 2977 new or added lines in 214 files covered. (100.0%)

19725 of 24212 relevant lines covered (81.47%)

2.44 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

94.66
/src/Math-AutomaticDifferenciation/PMDualNumber.class.st
1
"
2
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](https://en.wikipedia.org/wiki/Dual_number)
3

4
`PMDualNumber`s can be used to calculate the first derivative if one  creates them this way:
5

6
```
7
PMDualNumber value: aNumber eps: derivativeOfANumber
8
```
9
 (1 if the derivative with respect to aNumber is calculated, 0 otherwise)
10

11
`PMDualNumber`s can be mixed with Numbers.
12
"
13
Class {
14
        #name : #PMDualNumber,
15
        #superclass : #Number,
16
        #instVars : [
17
                'value',
18
                'eps'
19
        ],
20
        #classVars : [
21
                'ZeroApproximation'
22
        ],
23
        #category : #'Math-AutomaticDifferenciation'
24
}
25

26
{ #category : #'instance creation' }
27
PMDualNumber class >> value: aValue [
3✔
28
        ^ (self new value: aValue) eps: 0
3✔
29
]
3✔
30

31
{ #category : #'instance creation' }
32
PMDualNumber class >> value:aValue eps: anEps [
3✔
33
^(self new value: aValue) eps: anEps
3✔
34
]
3✔
35

36
{ #category : #accessing }
37
PMDualNumber class >> zeroApproximation [
3✔
38
"so far only used experimentally where i think it should produce no real problems, but i guess it should be used in #/, #arcSin, #arcCos, #raisedTo: and perhaps in #tan. additionally i used it wrongly as it should in general cover the range of -1.0e-100 to 1.0e-100 and not only zero (but i have always these speed-problems <g> ). perhaps i should thow it out completely, i noticed that several other implementations simply ignore those special cases. anyway, one can also set it to 0 with self class zeroApproximation:0, so that one gets a divideByZero error. another alternative would be to return infinity in some cases and a specialized singularity error in other ones. dont know."
3✔
39
        ^ ZeroApproximation ifNil: [ZeroApproximation :=1.0e-100]
3✔
40
]
3✔
41

3✔
42
{ #category : #accessing }
3✔
43
PMDualNumber class >> zeroApproximation: aSmallNumber [
3✔
44
"see comment in zeroApproximation"
3✔
45
^ZeroApproximation := aSmallNumber
3✔
46
]
3✔
47

48
{ #category : #arithmetic }
49
PMDualNumber >> * aNumber [
3✔
50
        ^ aNumber multiplyDualNumber: self
3✔
51
]
3✔
52

53
{ #category : #arithmetic }
54
PMDualNumber >> + aNumber [
3✔
55
        ^ aNumber addDualNumber: self
3✔
56
]
3✔
57

58
{ #category : #arithmetic }
59
PMDualNumber >> - aNumber [
3✔
60
        ^ aNumber negated addDualNumber: self
3✔
61
]
3✔
62

63
{ #category : #arithmetic }
64
PMDualNumber >> / aNumber [
3✔
65

3✔
66
        ^ aNumber reciprocal multiplyDualNumber: self
3✔
67
]
3✔
68

69
{ #category : #testing }
70
PMDualNumber >> < aDualNumber [
3✔
71
        ^ value < aDualNumber value
3✔
72
]
3✔
73

74
{ #category : #comparing }
75
PMDualNumber >> = aMagnitude [
3✔
76
        ^ aMagnitude = value
3✔
77
]
3✔
78

79
{ #category : #arithmetic }
80
PMDualNumber >> abs [
3✔
81
^value<0 ifTrue:[self negated]ifFalse:[self]
3✔
82
]
3✔
83

84
{ #category : #arithmetic }
85
PMDualNumber >> absSquared [
3✔
86
        ^ (self conjugated * self) real
3✔
87
]
3✔
88

89
{ #category : #converting }
90
PMDualNumber >> adaptToFraction: rcvr andSend: selector [
3✔
91
        ^ (self class value: rcvr) perform: selector with: self
3✔
92
]
3✔
93

94
{ #category : #converting }
95
PMDualNumber >> adaptToInteger: rcvr andSend: selector [
3✔
96
        ^ (self class value: rcvr) perform: selector with: self
3✔
97
]
3✔
98

99
{ #category : #arithmetic }
100
PMDualNumber >> addDualNumber: aDualNumber [
3✔
101
        ^ self class
3✔
102
                value: value + aDualNumber value
3✔
103
                eps: eps + aDualNumber eps
3✔
104
]
3✔
105

106
{ #category : #'mathematical functions' }
107
PMDualNumber >> arcCos [
3✔
108
        ^ self class
3✔
109
                value: value arcCos
3✔
110
                eps: eps negated /  (1 - value squared)sqrt
3✔
111
]
3✔
112

113
{ #category : #'mathematical functions' }
114
PMDualNumber >> arcSin [
3✔
115
        ^ self class
3✔
116
                value: value arcSin
3✔
117
                eps: eps /  (1 - value squared)sqrt
3✔
118
]
3✔
119

120
{ #category : #'mathematical functions' }
121
PMDualNumber >> arcTan [
3✔
122
        ^ self class value: value arcTan eps: eps / (1 + value squared)
3✔
123
]
3✔
124

125
{ #category : #converting }
126
PMDualNumber >> asFloat [
3✔
127
        ^ value asFloat
3✔
128
]
3✔
129

130
{ #category : #converting }
131
PMDualNumber >> asInteger [
3✔
132
        ^ value asInteger
3✔
133
]
3✔
134

135
{ #category : #comparing }
136
PMDualNumber >> closeTo: aDualNumber [
3✔
137

3✔
138
        ^ (value closeTo: aDualNumber value) and: [
3✔
139
                  eps closeTo: aDualNumber eps ]
3✔
140
]
3✔
141

142
{ #category : #'mathematical functions' }
143
PMDualNumber >> conjugated [
3✔
144

3✔
145
        ^ self class
3✔
146
                  value: self value complexConjugate
3✔
147
                  eps: self eps asComplex complexConjugate
3✔
148
]
3✔
149

150
{ #category : #'mathematical functions' }
151
PMDualNumber >> cos [
3✔
152
        ^ self class value: value cos eps: eps * value sin negated
3✔
153
]
3✔
154

155
{ #category : #accessing }
156
PMDualNumber >> eps [
3✔
157
        ^ eps
3✔
158
]
3✔
159

160
{ #category : #accessing }
161
PMDualNumber >> eps: aNumber [
3✔
162
        eps := aNumber
3✔
163
]
3✔
164

165
{ #category : #comparing }
166
PMDualNumber >> equalsTo: aDualNumber [
×
167

×
168
        self
×
169
                deprecated: 'Use closeTo: instead'
×
170
                transformWith: '`@rec equalsTo: `@arg' -> '`@rec closeTo: `@arg'.
×
171

×
172
        ^ self closeTo: aDualNumber
×
173
]
×
174

175
{ #category : #testing }
176
PMDualNumber >> even [
3✔
177
        ^value \\ 2 = 0
3✔
178
]
3✔
179

180
{ #category : #'mathematical functions' }
181
PMDualNumber >> exp [
3✔
182
        | e |
3✔
183
        e := value exp.
3✔
184
        ^ self class value: e eps: eps * e
3✔
185
]
3✔
186

187
{ #category : #comparing }
188
PMDualNumber >> hash [
3✔
189
        ^ value hash
3✔
190
]
3✔
191

192
{ #category : #testing }
193
PMDualNumber >> isDualNumber [
3✔
194
        ^ true
3✔
195
]
3✔
196

197
{ #category : #testing }
198
PMDualNumber >> isInfinite [
3✔
199
        ^ value isInfinite
3✔
200
]
3✔
201

202
{ #category : #testing }
203
PMDualNumber >> isNaN [
3✔
204
        ^ value isNaN
3✔
205
]
3✔
206

207
{ #category : #testing }
208
PMDualNumber >> isZero [
3✔
209
        ^value = 0
3✔
210
]
3✔
211

212
{ #category : #'mathematical functions' }
213
PMDualNumber >> ln [
3✔
214
        | v |
3✔
215
        v := value.
3✔
216
        v = 0
3✔
217
                ifTrue: [ v := self class zeroApproximation ].
3✔
218
        ^ self class value: value ln eps: eps / v
3✔
219
]
3✔
220

221
{ #category : #arithmetic }
222
PMDualNumber >> multiplyDualNumber: aDualNumber [
3✔
223
        ^self class
3✔
224
                                value: value * aDualNumber value
3✔
225
                                eps: eps * aDualNumber value + (aDualNumber eps * value)
3✔
226
]
3✔
227

228
{ #category : #arithmetic }
229
PMDualNumber >> negated [
3✔
230
^self class value: value negated eps: eps negated
3✔
231
]
3✔
232

233
{ #category : #testing }
234
PMDualNumber >> negative [
3✔
235
        ^ value < 0
3✔
236
]
3✔
237

238
{ #category : #testing }
239
PMDualNumber >> odd [
3✔
240
        ^self even not
3✔
241
]
3✔
242

243
{ #category : #testing }
244
PMDualNumber >> positive [
3✔
245
        ^ value >= 0
3✔
246
]
3✔
247

248
{ #category : #printing }
249
PMDualNumber >> printOn: aStream [
3✔
250
        "Append a sequence of characters that identify the receiver to aStream."
3✔
251

3✔
252
        aStream
3✔
253
                nextPutAll: self class name;
3✔
254
                nextPutAll: '(value: ';
3✔
255
                print: value;
3✔
256
                nextPutAll: ' eps: ';
3✔
257
                print: eps;
3✔
258
                nextPutAll: ')'
3✔
259
]
3✔
260

261
{ #category : #printing }
262
PMDualNumber >> printOn: aStream base: base [
×
263
        self printOn: aStream
×
264
]
×
265

266
{ #category : #'mathematical functions' }
267
PMDualNumber >> raisedTo: aDualNumber [
3✔
268
        | v |
3✔
269
        value = 0
3✔
270
                ifTrue: [ ^ self class value: 0 ].
3✔
271
        v := value raisedTo: aDualNumber value.
3✔
272
        aDualNumber isDualNumber
3✔
273
                ifFalse: [ ^ self class value: v eps: v / value * eps * aDualNumber ].
3✔
274
        ^ self class
3✔
275
                value: v
3✔
276
                eps: v * (eps * aDualNumber value / value + (aDualNumber eps * value ln))
3✔
277
]
3✔
278

279
{ #category : #'mathematical functions' }
280
PMDualNumber >> raisedToInteger: anInteger [
3✔
281
        ^ anInteger = 0
3✔
282
                ifTrue: [ self class value: 1 eps: 0 ]
3✔
283
                ifFalse: [ self class value: (value raisedToInteger: anInteger) eps: anInteger * eps * (value raisedToInteger: anInteger - 1) ]
3✔
284
]
3✔
285

286
{ #category : #converting }
287
PMDualNumber >> real [
3✔
288
        ^ self class value: self value real eps: self eps asComplex real
3✔
289
]
3✔
290

291
{ #category : #arithmetic }
292
PMDualNumber >> reciprocal [
3✔
293
        ^ self class value: 1 / value eps: eps / value squared negated
3✔
294
]
3✔
295

296
{ #category : #'mathematical functions' }
297
PMDualNumber >> sin [
3✔
298
        ^ self class value: value sin eps: eps * value cos
3✔
299
]
3✔
300

301
{ #category : #'mathematical functions' }
302
PMDualNumber >> sqrt [
3✔
303
        | d |
3✔
304
        d := 2 * value sqrt.
3✔
305
        d = 0
3✔
306
                ifTrue: [ d := self class zeroApproximation ].
3✔
307
        ^ self class value: value sqrt eps: eps / d
3✔
308
]
3✔
309

310
{ #category : #'mathematical functions' }
311
PMDualNumber >> squared [
3✔
312
        ^ self class value: value squared eps: 2 * eps * value
3✔
313
]
3✔
314

315
{ #category : #'mathematical functions' }
316
PMDualNumber >> tan [
3✔
317
        ^ self class
3✔
318
                value: value tan
3✔
319
                eps: eps / value cos squared
3✔
320
]
3✔
321

322
{ #category : #accessing }
323
PMDualNumber >> value [
3✔
324
        ^ value
3✔
325
]
3✔
326

327
{ #category : #accessing }
328
PMDualNumber >> value: anObject [
3✔
329
value := anObject
3✔
330
]
3✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc