Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 | 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 38x 38x 38x 70x 70x 70x 70x 38x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 4x 4x 4x 4x 6x 6x 6x 6x 6x 6x 4x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 27x 27x 27x 27x 27x 27x 27x 27x 27x 27x 27x 27x 27x 27x 27x 27x 27x 2x 2x 25x 25x 25x 25x 25x 25x 25x 25x 23x 23x 2x 2x 21x 21x 21x 21x 25x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 23x 23x 23x 23x 23x 23x 27x 21x 19x 2x 2x 17x 17x 17x 21x 2x 2x 2x 2x 2x 2x 2x 21x 21x 21x 27x 2x 2x 19x 27x 17x 17x 17x 27x 32x 32x 32x 32x 30x 30x 30x 32x 32x 32x 32x 32x 32x 32x 40x 40x 40x 40x 40x 40x 40x 40x 32x 19x 27x 3x 3x 3x 3x 3x | /**
* @license Apache-2.0
*
* Copyright (c) 2026 The Stdlib Authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
'use strict';
// MODULES //
var abs = require( '@stdlib/math/base/special/abs' );
// FUNCTIONS //
/**
* Eliminates a row across all right-hand sides (i.e., `B[iy] -= fact * B[ix]`).
*
* @private
* @param {Float64Array} B - input matrix
* @param {integer} ix - index of the row to subtract
* @param {integer} iy - index of the row to update
* @param {integer} stride - stride between columns of `B`
* @param {NonNegativeInteger} NRHS - number of right-hand sides
* @param {number} fact - elimination multiplier
*/
function eliminate( B, ix, iy, stride, NRHS, fact ) {
var j;
for ( j = 0; j < NRHS; j++ ) {
B[ iy ] -= fact * B[ ix ];
ix += stride;
iy += stride;
}
}
/**
* Interchanges two rows across all right-hand sides and eliminates the second row.
*
* @private
* @param {Float64Array} B - input matrix
* @param {integer} ix - index of the first row
* @param {integer} iy - index of the second row
* @param {integer} stride - stride between columns of `B`
* @param {NonNegativeInteger} NRHS - number of right-hand sides
* @param {number} fact - elimination multiplier
*/
function interchange( B, ix, iy, stride, NRHS, fact ) {
var temp;
var j;
for ( j = 0; j < NRHS; j++ ) {
temp = B[ ix ];
B[ ix ] = B[ iy ];
B[ iy ] = temp - ( fact*B[ iy ] );
ix += stride;
iy += stride;
}
}
// MAIN //
/**
* Solves a system of linear equations `A * X = B`, where `A` is an `N`-by-`N` tridiagonal matrix, using Gaussian elimination with partial pivoting.
*
* @private
* @param {NonNegativeInteger} N - number of rows/columns in `A`
* @param {NonNegativeInteger} NRHS - number of right-hand sides (i.e., number of columns in `B`)
* @param {Float64Array} DL - the first sub-diagonal of `A`
* @param {integer} strideDL - stride length for `DL`
* @param {NonNegativeInteger} offsetDL - starting index for `DL`
* @param {Float64Array} D - the diagonal of `A`
* @param {integer} strideD - stride length for `D`
* @param {NonNegativeInteger} offsetD - starting index for `D`
* @param {Float64Array} DU - the first super-diagonal of `A`
* @param {integer} strideDU - stride length for `DU`
* @param {NonNegativeInteger} offsetDU - starting index for `DU`
* @param {Float64Array} B - input matrix
* @param {integer} strideB1 - stride of the first dimension of `B`
* @param {integer} strideB2 - stride of the second dimension of `B`
* @param {NonNegativeInteger} offsetB - starting index for `B`
* @returns {integer} status code
*
* @example
* var Float64Array = require( '@stdlib/array/float64' );
*
* var DL = new Float64Array( [ 1.0, 1.0 ] );
* var D = new Float64Array( [ 2.0, 3.0, 1.0 ] );
* var DU = new Float64Array( [ 1.0, 1.0 ] );
* var B = new Float64Array( [ 4.0, 10.0, 5.0 ] );
*
* dgtsv( 3, 1, DL, 1, 0, D, 1, 0, DU, 1, 0, B, 1, 3, 0 );
* // B => <Float64Array>[ 1.0, 2.0, 3.0 ]
*/
function dgtsv( N, NRHS, DL, strideDL, offsetDL, D, strideD, offsetD, DU, strideDU, offsetDU, B, strideB1, strideB2, offsetB ) { // eslint-disable-line stdlib/jsdoc-doctest-decimal-point, max-len, max-params
var dun1;
var fact;
var temp;
var dn1;
var idl;
var idu;
var ib1;
var ib2;
var ibr;
var dn;
var id;
var ib;
var i;
var j;
if ( N === 0 ) {
return 0;
}
idl = offsetDL;
id = offsetD;
idu = offsetDU;
ibr = offsetB;
// Forward elimination over the first `N-2` rows...
for ( i = 0; i < N-2; i++ ) {
if ( abs( D[ id ] ) >= abs( DL[ idl ] ) ) {
// No row interchange required...
if ( D[ id ] === 0.0 ) {
return i + 1;
}
fact = DL[ idl ] / D[ id ];
D[ id+strideD ] -= fact * DU[ idu ];
eliminate( B, ibr, ibr+strideB1, strideB2, NRHS, fact );
DL[ idl ] = 0.0;
} else {
// Interchange rows `i` and `i+1` and store the fill-in in `DL`...
fact = D[ id ] / DL[ idl ];
D[ id ] = DL[ idl ];
temp = D[ id+strideD ];
D[ id+strideD ] = DU[ idu ] - ( fact*temp );
DL[ idl ] = DU[ idu+strideDU ];
DU[ idu+strideDU ] = -fact * DL[ idl ];
DU[ idu ] = temp;
interchange( B, ibr, ibr+strideB1, strideB2, NRHS, fact );
}
idl += strideDL;
id += strideD;
idu += strideDU;
ibr += strideB1;
}
// Perform the final elimination step for the last two rows...
if ( N > 1 ) {
if ( abs( D[ id ] ) >= abs( DL[ idl ] ) ) {
if ( D[ id ] === 0.0 ) {
return i + 1;
}
fact = DL[ idl ] / D[ id ];
D[ id+strideD ] -= fact * DU[ idu ];
eliminate( B, ibr, ibr+strideB1, strideB2, NRHS, fact );
} else {
fact = D[ id ] / DL[ idl ];
D[ id ] = DL[ idl ];
temp = D[ id+strideD ];
D[ id+strideD ] = DU[ idu ] - ( fact*temp );
DU[ idu ] = temp;
interchange( B, ibr, ibr+strideB1, strideB2, NRHS, fact );
}
}
// Check for a zero pivot in the last diagonal element of `U`...
dn = D[ offsetD+( (N-1)*strideD ) ];
if ( dn === 0.0 ) {
return N;
}
// Back substitution with the upper triangular matrix `U`...
if ( N > 1 ) {
dn1 = D[ offsetD+( (N-2)*strideD ) ];
dun1 = DU[ offsetDU+( (N-2)*strideDU ) ];
}
for ( j = 0; j < NRHS; j++ ) {
ibr = offsetB + ( j*strideB2 );
ib = ibr + ( (N-1)*strideB1 );
B[ ib ] /= dn;
if ( N > 1 ) {
ib1 = ib - strideB1;
B[ ib1 ] = ( B[ ib1 ]-( dun1*B[ ib ] ) ) / dn1;
}
id = offsetD + ( (N-3)*strideD );
idl = offsetDL + ( (N-3)*strideDL );
idu = offsetDU + ( (N-3)*strideDU );
ib = ibr + ( (N-3)*strideB1 );
ib1 = ib + strideB1;
ib2 = ib + ( 2*strideB1 );
for ( i = N-3; i >= 0; i-- ) {
B[ ib ] = ( B[ ib ]-( DU[ idu ]*B[ ib1 ] )-( DL[ idl ]*B[ ib2 ] ) ) / D[ id ]; // eslint-disable-line max-len
id -= strideD;
idl -= strideDL;
idu -= strideDU;
ib -= strideB1;
ib1 -= strideB1;
ib2 -= strideB1;
}
}
return 0;
}
// EXPORTS //
module.exports = dgtsv;
|