Skip to content

Commit 80571b7

Browse files
authored
fix(sin): Update to latest complex.js to improve sin(z) for small im(z) (#2525)
Resolves #2523
1 parent ac332e6 commit 80571b7

File tree

4 files changed

+64
-63
lines changed

4 files changed

+64
-63
lines changed

package-lock.json

Lines changed: 7 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
],
2727
"dependencies": {
2828
"@babel/runtime": "^7.17.8",
29-
"complex.js": "^2.1.0",
29+
"complex.js": "^2.1.1",
3030
"decimal.js": "^10.3.1",
3131
"escape-latex": "^1.2.0",
3232
"fraction.js": "^4.2.0",

test/unit-tests/function/probability/lgamma.test.js

Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ import approx from '../../../../tools/approx.js'
55
import math from '../../../../src/defaultInstance.js'
66
const lgamma = math.lgamma
77

8-
const EPSILON = 1e-10
9-
// lgamma for complex numbers is not quite as precies as lgamma for reals,
10-
// because `complex.js sin` doesn't have extremely high precision
8+
const EPSILON = 1e-11
9+
// TODO: lgamma for some cases of complex numbers is not quite as precise as
10+
// lgamma for reals
1111
const CEPSILON = 5e-8
1212

1313
describe('lgamma', () => {
@@ -50,135 +50,135 @@ describe('lgamma', () => {
5050
})
5151

5252
it('should calculate the lgamma of a complex number', () => {
53-
approx.deepEqual(lgamma(math.complex(0, 0)), math.complex(Infinity), CEPSILON)
53+
approx.deepEqual(lgamma(math.complex(0, 0)), math.complex(Infinity), EPSILON)
5454
approx.deepEqual(
5555
lgamma(math.complex(0.000000001, 0.000000001)),
5656
math.complex(20.3766922460892228366, -0.78539816397466397287),
57-
CEPSILON
57+
EPSILON
5858
)
5959
approx.deepEqual(
6060
lgamma(math.complex(0.000001, 0.000001)),
6161
math.complex(13.4689363904686365487, -0.78539874061146827788),
62-
CEPSILON
62+
EPSILON
6363
)
6464
approx.deepEqual(
6565
lgamma(math.complex(0.25, 0.25)),
6666
math.complex(0.90447450949333888977, -0.83887024394321281804),
67-
CEPSILON
67+
EPSILON
6868
)
6969
approx.deepEqual(
7070
lgamma(math.complex(-0.25, 0.25)),
7171
math.complex(1.16657203736087492865, -2.61462703865115551016),
72-
CEPSILON
72+
EPSILON
7373
)
7474
approx.deepEqual(
7575
lgamma(math.complex(0.8, -0.8)),
7676
math.complex(-0.41924081113642074879, 0.51623080213929827944),
77-
CEPSILON
77+
EPSILON
7878
)
7979
approx.deepEqual(
8080
lgamma(math.complex(-0.8, 0.8)),
8181
math.complex(-0.3775761850502096333, -3.80865021027588766567),
82-
CEPSILON
82+
EPSILON
8383
)
8484

8585
approx.deepEqual(
8686
lgamma(math.complex(1, 1)),
8787
math.complex(-0.65092319930185633889, -0.30164032046753319789),
88-
CEPSILON
88+
EPSILON
8989
)
9090
approx.deepEqual(
9191
lgamma(math.complex(1, -1)),
9292
math.complex(-0.65092319930185633889, 0.30164032046753319789),
93-
CEPSILON
93+
EPSILON
9494
)
9595
approx.deepEqual(
9696
lgamma(math.complex(-1, 1)),
9797
math.complex(-0.99749678958182899359, -4.22863113745477474597),
98-
CEPSILON
98+
EPSILON
9999
)
100100
approx.deepEqual(
101101
lgamma(math.complex(-1, -1)),
102102
math.complex(-0.99749678958182899359, 4.22863113745477474597),
103-
CEPSILON
103+
EPSILON
104104
)
105105

106106
approx.deepEqual(
107107
lgamma(math.complex(1.5, 1.5)),
108108
math.complex(-0.97915093918136435887, 0.38589477126715472436),
109-
CEPSILON
109+
EPSILON
110110
)
111111
approx.deepEqual(
112112
lgamma(math.complex(1.5, -1.5)),
113113
math.complex(-0.97915093918136435887, -0.38589477126715472436),
114-
CEPSILON
114+
EPSILON
115115
)
116116
approx.deepEqual(
117117
lgamma(math.complex(-1.5, 1.5)),
118118
math.complex(-2.64748036944365646074, -5.11189237251498344295),
119-
CEPSILON
119+
EPSILON
120120
)
121121
approx.deepEqual(
122122
lgamma(math.complex(-1.5, -1.5)),
123123
math.complex(-2.64748036944365646074, 5.11189237251498344295),
124-
CEPSILON
124+
EPSILON
125125
)
126126

127127
approx.deepEqual(
128128
lgamma(math.complex(2, -2)),
129129
math.complex(-1.07135983021387915393, -1.2367950341038788144),
130-
CEPSILON
130+
EPSILON
131131
)
132132
approx.deepEqual(
133133
lgamma(math.complex(-2.5, -2.5)),
134134
math.complex(-6.27685085148648571668, 6.42804393793984167867),
135-
CEPSILON
135+
EPSILON
136136
)
137137
approx.deepEqual(
138138
lgamma(math.complex(-12.5, 12.5)),
139139
math.complex(-53.3767553324096369866, -7.23008341760111500158),
140-
CEPSILON
140+
EPSILON
141141
)
142142
approx.deepEqual(
143143
lgamma(math.complex(125.5, 125.5)),
144144
math.complex(424.211719638964718426, 622.623796700622589246),
145-
CEPSILON
145+
EPSILON
146146
)
147147
approx.deepEqual(
148148
lgamma(math.complex(5555.5555, -5555.5555)),
149149
math.complex(39906.0402274967320859, -48635.8593112306908421),
150-
CEPSILON
150+
EPSILON
151151
)
152152
approx.deepEqual(
153153
lgamma(math.complex(-5000000.5, -5000000.5)),
154154
math.complex(-8.56385987850343162145e7, -6.20766433819965678363e7),
155-
CEPSILON
155+
EPSILON
156156
)
157157
approx.deepEqual(
158158
lgamma(math.complex(99999999999999.5, 99999999999999.5)),
159159
math.complex(3.07973667287988512101e15, 3.23681630555938897728e15),
160-
CEPSILON
160+
EPSILON
161161
)
162162
approx.deepEqual(
163163
lgamma(math.complex(-9.87654321e50, 1.23456789e70)),
164164
math.complex(-1.93925470679092599791e70, 1.98014414903993314695e72),
165-
CEPSILON
165+
EPSILON
166166
)
167167

168168
approx.deepEqual(
169169
lgamma(math.complex(0.000123, 123456789)),
170170
math.complex(-1.93925479073563285659e8, 2.17671624683482738475e9),
171-
CEPSILON
171+
EPSILON
172172
)
173173
approx.deepEqual(
174174
lgamma(math.complex(-0.000123, 123456789)),
175175
math.complex(-1.93925479078146610494e8, 2.17671624683444096885e9),
176-
CEPSILON
176+
EPSILON
177177
)
178178
approx.deepEqual(
179179
lgamma(math.complex(123456789, -0.000123)),
180180
math.complex(2.17671623922326999167e9, -0.00229166241674051621),
181-
CEPSILON
181+
EPSILON
182182
)
183183
approx.deepEqual(
184184
lgamma(math.complex(-123456789, -0.000123)),
@@ -188,7 +188,7 @@ describe('lgamma', () => {
188188
approx.deepEqual(
189189
lgamma(math.complex(123456789.123, 0.123456789)),
190190
math.complex(2.17671624151493240841e9, 2.30017303624303234065),
191-
CEPSILON
191+
EPSILON
192192
)
193193
})
194194

test/unit-tests/function/trigonometry/sin.test.js

Lines changed: 26 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import assert from 'assert'
22
import math from '../../../../src/defaultInstance.js'
33
import approx from '../../../../tools/approx.js'
4+
const EPSILON = 1e-13
45
const pi = math.pi
56
const complex = math.complex
67
const matrix = math.matrix
@@ -15,16 +16,16 @@ describe('sin', function () {
1516
})
1617

1718
it('should return the sine of a number', function () {
18-
approx.equal(sin(0), 0)
19-
approx.equal(sin(pi / 8), 0.382683432365090)
20-
approx.equal(sin(pi / 4), Math.SQRT1_2)
21-
approx.equal(sin(pi / 2), 1)
22-
approx.equal(sin(pi * 3 / 4), 0.707106781186548)
23-
approx.equal(sin(pi), 0)
24-
approx.equal(sin(pi * 5 / 4), -0.707106781186548)
25-
approx.equal(sin(pi * 3 / 2), -1)
26-
approx.equal(sin(pi * 7 / 4), -0.707106781186548)
27-
approx.equal(sin(pi * 2), 0)
19+
approx.equal(sin(0), 0, EPSILON)
20+
approx.equal(sin(pi / 8), 0.382683432365090, EPSILON)
21+
approx.equal(sin(pi / 4), Math.SQRT1_2, EPSILON)
22+
approx.equal(sin(pi / 2), 1, EPSILON)
23+
approx.equal(sin(pi * 3 / 4), 0.707106781186548, EPSILON)
24+
approx.equal(sin(pi), 0, EPSILON)
25+
approx.equal(sin(pi * 5 / 4), -0.707106781186548, EPSILON)
26+
approx.equal(sin(pi * 3 / 2), -1, EPSILON)
27+
approx.equal(sin(pi * 7 / 4), -0.707106781186548, EPSILON)
28+
approx.equal(sin(pi * 2), 0, EPSILON)
2829
})
2930

3031
it('should return the sine of a bignumber', function () {
@@ -49,7 +50,7 @@ describe('sin', function () {
4950

5051
// we've had a bug in reducing the period, affecting integer values around multiples of tau (like 6, 7)
5152
for (let x = -20; x < 20; x += 1) {
52-
approx.equal(bigmath2.sin(bigmath2.bignumber(x)).toNumber(), Math.sin(x))
53+
approx.equal(bigmath2.sin(bigmath2.bignumber(x)).toNumber(), Math.sin(x), EPSILON)
5354
}
5455

5556
const bigPi = bigmath2.pi
@@ -73,24 +74,24 @@ describe('sin', function () {
7374
it('should return the sine of a complex number', function () {
7475
const re = 9.15449914691143
7576
const im = 4.16890695996656
76-
approx.deepEqual(sin(complex('2+3i')), complex(re, -im))
77-
approx.deepEqual(sin(complex('2-3i')), complex(re, im))
78-
approx.deepEqual(sin(complex('-2+3i')), complex(-re, -im))
79-
approx.deepEqual(sin(complex('-2-3i')), complex(-re, im))
80-
approx.deepEqual(sin(complex('i')), complex(0, 1.175201193643801))
81-
approx.deepEqual(sin(complex('1')), complex(0.841470984807897, 0))
82-
approx.deepEqual(sin(complex('1+i')), complex(1.298457581415977, 0.634963914784736))
83-
approx.deepEqual(sin(complex('1e-10i')), complex('1e-10i'))
77+
approx.deepEqual(sin(complex('2+3i')), complex(re, -im), EPSILON)
78+
approx.deepEqual(sin(complex('2-3i')), complex(re, im), EPSILON)
79+
approx.deepEqual(sin(complex('-2+3i')), complex(-re, -im), EPSILON)
80+
approx.deepEqual(sin(complex('-2-3i')), complex(-re, im), EPSILON)
81+
approx.deepEqual(sin(complex('i')), complex(0, 1.175201193643801), EPSILON)
82+
approx.deepEqual(sin(complex('1')), complex(0.841470984807897, 0), EPSILON)
83+
approx.deepEqual(sin(complex('1+i')), complex(1.298457581415977, 0.634963914784736), EPSILON)
84+
approx.deepEqual(sin(complex('1e-10i')), complex('1e-10i'), EPSILON)
8485
})
8586

8687
it('should return the sine of an angle', function () {
87-
approx.equal(sin(unit('45deg')), 0.707106781186548)
88-
approx.equal(sin(unit('-45deg')), -0.707106781186548)
88+
approx.equal(sin(unit('45deg')), 0.707106781186548, EPSILON)
89+
approx.equal(sin(unit('-45deg')), -0.707106781186548, EPSILON)
8990

9091
assert(math.isBigNumber(sin(unit(math.bignumber(45), 'deg'))))
91-
approx.equal(sin(unit(math.bignumber(45), 'deg')).toNumber(), 0.707106781186548)
92+
approx.equal(sin(unit(math.bignumber(45), 'deg')).toNumber(), 0.707106781186548, EPSILON)
9293

93-
approx.deepEqual(sin(unit(complex('1+i'), 'rad')), complex(1.298457581415977, 0.634963914784736))
94+
approx.deepEqual(sin(unit(complex('1+i'), 'rad')), complex(1.298457581415977, 0.634963914784736), EPSILON)
9495
})
9596

9697
it('should throw an error if called with an invalid unit', function () {
@@ -104,11 +105,11 @@ describe('sin', function () {
104105
const sin123 = [0.84147098480789, 0.909297426825682, 0.141120008059867]
105106

106107
it('should return the sin of each element of an array', function () {
107-
approx.deepEqual(sin([1, 2, 3]), sin123)
108+
approx.deepEqual(sin([1, 2, 3]), sin123, EPSILON)
108109
})
109110

110111
it('should return the sin of each element of a matrix', function () {
111-
approx.deepEqual(sin(matrix([1, 2, 3])), matrix(sin123))
112+
approx.deepEqual(sin(matrix([1, 2, 3])), matrix(sin123), EPSILON)
112113
})
113114

114115
it('should throw an error in case of invalid number of arguments', function () {

0 commit comments

Comments
 (0)