2121// MODULES //
2222
2323var tape = require ( 'tape' ) ;
24+ var Float64Array = require ( '@stdlib/array/float64' ) ;
25+ var Int32Array = require ( '@stdlib/array/int32' ) ;
26+ var EPS = require ( '@stdlib/constants/float64/eps' ) ;
27+ var abs = require ( '@stdlib/math/base/special/abs' ) ;
2428var dgttrf = require ( './../lib/ndarray.js' ) ;
2529
2630
31+ // FUNCTIONS //
32+
33+ /**
34+ * Tests for element-wise approximate equality.
35+ *
36+ * @private
37+ * @param {Object } t - test object
38+ * @param {Collection } actual - actual values
39+ * @param {Collection } expected - expected values
40+ * @param {number } rtol - relative tolerance
41+ */
42+ function isApprox ( t , actual , expected , rtol ) {
43+ var delta ;
44+ var tol ;
45+ var i ;
46+
47+ t . strictEqual ( actual . length , expected . length , 'returns expected value' ) ;
48+ for ( i = 0 ; i < expected . length ; i ++ ) {
49+ if ( actual [ i ] === expected [ i ] ) {
50+ t . strictEqual ( actual [ i ] , expected [ i ] , 'returns expected value' ) ;
51+ } else {
52+ delta = abs ( actual [ i ] - expected [ i ] ) ;
53+ tol = rtol * EPS * abs ( expected [ i ] ) ;
54+ t . ok ( delta <= tol , 'within tolerance. actual: ' + actual [ i ] + '. expected: ' + expected [ i ] + '. delta: ' + delta + '. tol: ' + tol + '.' ) ;
55+ }
56+ }
57+ }
58+
59+
2760// TESTS //
2861
2962tape ( 'main export is a function' , function test ( t ) {
@@ -36,3 +69,159 @@ tape( 'the function has an arity of 16', function test( t ) {
3669 t . strictEqual ( dgttrf . length , 16 , 'returns expected value' ) ;
3770 t . end ( ) ;
3871} ) ;
72+
73+ tape ( 'the function throws an error if provided a first argument which is less than zero' , function test ( t ) {
74+ var values ;
75+ var IPIV ;
76+ var DU2 ;
77+ var DU ;
78+ var DL ;
79+ var D ;
80+ var i ;
81+
82+ DL = new Float64Array ( [ 1.0 , 1.0 ] ) ;
83+ D = new Float64Array ( [ 2.0 , 3.0 , 1.0 ] ) ;
84+ DU = new Float64Array ( [ 1.0 , 1.0 ] ) ;
85+ DU2 = new Float64Array ( 1 ) ;
86+ IPIV = new Int32Array ( 3 ) ;
87+
88+ values = [
89+ - 1 ,
90+ - 2 ,
91+ - 3
92+ ] ;
93+
94+ for ( i = 0 ; i < values . length ; i ++ ) {
95+ t . throws ( badValue ( values [ i ] ) , RangeError , 'throws an error when provided ' + values [ i ] ) ;
96+ }
97+ t . end ( ) ;
98+
99+ function badValue ( value ) {
100+ return function badValue ( ) {
101+ dgttrf ( value , DL , 1 , 0 , D , 1 , 0 , DU , 1 , 0 , DU2 , 1 , 0 , IPIV , 1 , 0 ) ;
102+ } ;
103+ }
104+ } ) ;
105+
106+ tape ( 'the function performs the `LU` factorization of a real tri diagonal matrix `A` using elimination with partial pivoting and row interchanges' , function test ( t ) {
107+ var expectedIPIV ;
108+ var expectedDU2 ;
109+ var expectedDU ;
110+ var expectedDL ;
111+ var expectedD ;
112+ var info ;
113+ var IPIV ;
114+ var DU2 ;
115+ var DU ;
116+ var DL ;
117+ var D ;
118+ var N ;
119+
120+ N = 3 ;
121+
122+ DL = new Float64Array ( [ 1.0 , 1.0 ] ) ;
123+ D = new Float64Array ( [ 2.0 , 3.0 , 1.0 ] ) ;
124+ DU = new Float64Array ( [ 1.0 , 1.0 ] ) ;
125+ DU2 = new Float64Array ( N - 2 ) ;
126+ IPIV = new Int32Array ( N ) ;
127+
128+ expectedDL = new Float64Array ( [ 0.5 , 0.4 ] ) ;
129+ expectedD = new Float64Array ( [ 2.0 , 2.5 , 0.6 ] ) ;
130+ expectedDU = new Float64Array ( [ 1.0 , 1.0 ] ) ;
131+ expectedDU2 = new Float64Array ( [ 0.0 ] ) ;
132+ expectedIPIV = new Int32Array ( [ 0 , 1 , 2 ] ) ;
133+
134+ info = dgttrf ( N , DL , 1 , 0 , D , 1 , 0 , DU , 1 , 0 , DU2 , 1 , 0 , IPIV , 1 , 0 ) ;
135+ t . strictEqual ( info , 0 , 'returns expected value' ) ;
136+ t . deepEqual ( IPIV , expectedIPIV , 'returns expected value' ) ;
137+ isApprox ( t , D , expectedD , 1.0 ) ;
138+ isApprox ( t , DU , expectedDU , 1.0 ) ;
139+ isApprox ( t , DU2 , expectedDU2 , 1.0 ) ;
140+ isApprox ( t , DL , expectedDL , 1.0 ) ;
141+
142+ N = 9 ;
143+
144+ DL = new Float64Array ( [ 3.0 , 3.0 , 3.0 , 3.0 , 3.0 , 3.0 , 3.0 , 3.0 ] ) ;
145+ D = new Float64Array ( [ 1.0 , 1.0 , 1.0 , 1.0 , 1.0 , 1.0 , 1.0 , 1.0 , 1.0 ] ) ;
146+ DU = new Float64Array ( [ 4.0 , 4.0 , 4.0 , 4.0 , 4.0 , 4.0 , 4.0 , 4.0 ] ) ;
147+ DU2 = new Float64Array ( N - 2 ) ;
148+ IPIV = new Int32Array ( N ) ;
149+
150+ expectedDL = new Float64Array ( [ 0.3333333333333333 , 0.8181818181818182 , 0.6969696969696969 , 0.9082568807339449 , 0.8493506493506494 , - 0.7991341991341993 , 0.6251127548259066 , - 0.3327319742618318 ] ) ; // eslint-disable-line max-len
151+ expectedD = new Float64Array ( [ 3.0 , 3.6666666666666665 , 3.0 , 3.3030303030303032 , 3.5321100917431192 , 3.0 , 4.7991341991341994 , 3.0 , 4.3327319742618320 ] ) ; // eslint-disable-line max-len
152+ expectedDU = new Float64Array ( [ 1.0 , - 1.3333333333333333 , 1.0 , - 2.7878787878787876 , 4.0 , 1.0 , 3.1965367965367970 , 1.0 ] ) ; // eslint-disable-line max-len
153+ expectedDU2 = new Float64Array ( [ 4.0 , 0.0 , 4.0 , 0.0 , 0.0 , 4.0 , 0.0 ] ) ;
154+ expectedIPIV = new Int32Array ( [ 1 , 1 , 3 , 3 , 4 , 6 , 6 , 8 , 8 ] ) ;
155+
156+ info = dgttrf ( N , DL , 1 , 0 , D , 1 , 0 , DU , 1 , 0 , DU2 , 1 , 0 , IPIV , 1 , 0 ) ;
157+ t . strictEqual ( info , 0 , 'returns expected value' ) ;
158+ t . deepEqual ( IPIV , expectedIPIV , 'returns expected value' ) ;
159+ isApprox ( t , D , expectedD , 1.0 ) ;
160+ isApprox ( t , DU , expectedDU , 1.0 ) ;
161+ isApprox ( t , DU2 , expectedDU2 , 1.0 ) ;
162+ isApprox ( t , DL , expectedDL , 1.0 ) ;
163+
164+ t . end ( ) ;
165+ } ) ;
166+
167+ tape ( 'the function leaves the input arrays unchanged when `N` is equal to zero' , function test ( t ) {
168+ var expectedIPIV ;
169+ var expectedDU2 ;
170+ var expectedDU ;
171+ var expectedDL ;
172+ var expectedD ;
173+ var info ;
174+ var IPIV ;
175+ var DU2 ;
176+ var DU ;
177+ var DL ;
178+ var D ;
179+ var N ;
180+
181+ N = 0 ;
182+
183+ DL = new Float64Array ( [ 1.0 , 1.0 ] ) ;
184+ D = new Float64Array ( [ 2.0 , 3.0 , 1.0 ] ) ;
185+ DU = new Float64Array ( [ 1.0 , 1.0 ] ) ;
186+ DU2 = new Float64Array ( 1 ) ;
187+ IPIV = new Int32Array ( 3 ) ;
188+
189+ expectedDL = new Float64Array ( [ 1.0 , 1.0 ] ) ;
190+ expectedD = new Float64Array ( [ 2.0 , 3.0 , 1.0 ] ) ;
191+ expectedDU = new Float64Array ( [ 1.0 , 1.0 ] ) ;
192+ expectedDU2 = new Float64Array ( [ 0.0 ] ) ;
193+ expectedIPIV = new Int32Array ( [ 0 , 0 , 0 ] ) ;
194+
195+ info = dgttrf ( N , DL , 1 , 0 , D , 1 , 0 , DU , 1 , 0 , DU2 , 1 , 0 , IPIV , 1 , 0 ) ;
196+ t . strictEqual ( info , 0 , 'returns expected value' ) ;
197+ t . deepEqual ( DU , expectedDU , 'returns expected value' ) ;
198+ t . deepEqual ( DU2 , expectedDU2 , 'returns expected value' ) ;
199+ t . deepEqual ( D , expectedD , 'returns expected value' ) ;
200+ t . deepEqual ( DL , expectedDL , 'returns expected value' ) ;
201+ t . deepEqual ( IPIV , expectedIPIV , 'returns expected value' ) ;
202+
203+ t . end ( ) ;
204+ } ) ;
205+
206+ tape ( 'the function returns a non zero status code when a diagonal element is equal to zero' , function test ( t ) {
207+ var info ;
208+ var IPIV ;
209+ var DU2 ;
210+ var DU ;
211+ var DL ;
212+ var D ;
213+ var N ;
214+
215+ N = 3 ;
216+
217+ DL = new Float64Array ( [ 0.0 , 0.0 ] ) ;
218+ D = new Float64Array ( [ 1.0 , 1.0 , 0.0 ] ) ;
219+ DU = new Float64Array ( [ 2.0 , 3.0 ] ) ;
220+ DU2 = new Float64Array ( 1 ) ;
221+ IPIV = new Int32Array ( 3 ) ;
222+
223+ info = dgttrf ( N , DL , 1 , 0 , D , 1 , 0 , DU , 1 , 0 , DU2 , 1 , 0 , IPIV , 1 , 0 ) ;
224+ t . strictEqual ( info , 2 , 'returns expected value' ) ;
225+
226+ t . end ( ) ;
227+ } ) ;
0 commit comments