Skip to content

Commit fdff657

Browse files
committed
feat: add lib
--- type: pre_commit_static_analysis_report description: Results of running static analysis checks when committing changes. report: - task: lint_filenames status: passed - task: lint_editorconfig status: passed - task: lint_markdown status: na - task: lint_package_json status: na - task: lint_repl_help status: na - task: lint_javascript_src status: passed - task: lint_javascript_cli status: na - task: lint_javascript_examples status: na - task: lint_javascript_tests status: na - task: lint_javascript_benchmarks status: na - task: lint_python status: na - task: lint_r status: na - task: lint_c_src status: na - task: lint_c_examples status: na - task: lint_c_benchmarks status: na - task: lint_c_tests_fixtures status: na - task: lint_shell status: na - task: lint_typescript_declarations status: passed - task: lint_typescript_tests status: na - task: lint_license_headers status: passed ---
1 parent 6ad37f9 commit fdff657

5 files changed

Lines changed: 604 additions & 0 deletions

File tree

Lines changed: 246 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,246 @@
1+
/**
2+
* @license Apache-2.0
3+
*
4+
* Copyright (c) 2026 The Stdlib Authors.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
/* eslint-disable max-params */
20+
21+
'use strict';
22+
23+
// MODULES //
24+
25+
var isRowMajor = require( '@stdlib/ndarray/base/assert/is-row-major' );
26+
var zfill = require( '@stdlib/blas/ext/base/zfill' ).ndarray;
27+
var zscal = require( '@stdlib/blas/base/zscal' ).ndarray;
28+
var realf = require( '@stdlib/complex/float64/real' );
29+
var imagf = require( '@stdlib/complex/float64/imag' );
30+
var reinterpret = require( '@stdlib/strided/base/reinterpret-complex128' );
31+
var muladd = require( '@stdlib/complex/float64/base/mul-add' ).assign;
32+
var max = require( '@stdlib/math/base/special/max' );
33+
var min = require( '@stdlib/math/base/special/min' );
34+
35+
36+
// FUNCTIONS //
37+
38+
/**
39+
* Tests whether a provided string indicates to transpose a matrix.
40+
*
41+
* @private
42+
* @param {string} str - input string
43+
* @returns {boolean} boolean indicating whether to transpose a matrix
44+
*
45+
* @example
46+
* var bool = isTransposed( 'transpose' );
47+
* // returns true
48+
*
49+
* @example
50+
* var bool = isTransposed( 'conjugate-transpose' );
51+
* // returns true
52+
*
53+
* @example
54+
* var bool = isTransposed( 'no-transpose' );
55+
* // returns false
56+
*/
57+
function isTransposed( str ) { // TODO: consider moving to a separate helper utility package
58+
return ( str !== 'no-transpose' );
59+
}
60+
61+
62+
// MAIN //
63+
64+
/**
65+
* Performs one of the matrix-vector operations `y = α*A*x + β*y` or `y = α*A^T*x + β*y` or `y = α*A^H*x + β*y`, where `α` and `β` are scalars, `x` and `y` are vectors, and `A` is an `M` by `N` band matrix with `KL` sub-diagonals and `KU` super-diagonals.
66+
*
67+
* @private
68+
* @param {string} trans - specifies whether `A` should be transposed, conjugate-transposed, or not transposed
69+
* @param {NonNegativeInteger} M - number of rows in the matrix `A`
70+
* @param {NonNegativeInteger} N - number of columns in the matrix `A`
71+
* @param {NonNegativeInteger} KL - number of sub-diagonals of matrix `A`
72+
* @param {NonNegativeInteger} KU - number of super-diagonals of matrix `A`
73+
* @param {Complex128} alpha - scalar constant
74+
* @param {Complex128Array} A - input banded matrix (compact band storage)
75+
* @param {integer} strideA1 - stride of first dimension of `A`
76+
* @param {integer} strideA2 - stride of second dimension of `A`
77+
* @param {NonNegativeInteger} offsetA - starting index into `A`
78+
* @param {Complex128Array} x - first input vector `x`
79+
* @param {integer} strideX - `x` stride length
80+
* @param {NonNegativeInteger} offsetX - starting index for `x`
81+
* @param {Complex128} beta - scalar constant
82+
* @param {Complex128Array} y - second input vector y
83+
* @param {integer} strideY - `y` stride length
84+
* @param {NonNegativeInteger} offsetY - starting index for `y`
85+
* @returns {Complex128Array} `y`
86+
*
87+
* @example
88+
* var Complex128Array = require( '@stdlib/array/complex128' );
89+
* var Complex128 = require( '@stdlib/complex/float64/ctor' );
90+
*
91+
* var A = new Complex128Array( [ 0.0, 0.0, 1.0, 1.0, 3.0, 3.0, 2.0, 2.0, 4.0, 4.0, 6.0, 6.0, 5.0, 5.0, 7.0, 7.0, 0.0, 0.0 ] );
92+
* var x = new Complex128Array( [ 1.0, 1.0, 2.0, 2.0, 3.0, 3.0 ] );
93+
* var y = new Complex128Array( [ 3.0, 3.0, 2.0, 2.0, 1.0, 1.0 ] );
94+
* var alpha = new Complex128( 0.5, 0.5 );
95+
* var beta = new Complex128( 0.5, -0.5 );
96+
*
97+
* zgbmv( 'no-transpose', 3, 3, 1, 1, alpha, A, 3, 1, 0, x, 1, 0, beta, y, 1, 0 );
98+
* // y => <Complex128Array>[ -4.0, 7.0, -26.0, 28.0, -30.0, 31.0 ]
99+
*/
100+
function zgbmv( trans, M, N, KL, KU, alpha, A, strideA1, strideA2, offsetA, x, strideX, offsetX, beta, y, strideY, offsetY ) { // eslint-disable-line max-len
101+
var i0start;
102+
var realpha;
103+
var imalpha;
104+
var rebeta;
105+
var imbeta;
106+
var i0end;
107+
var viewA;
108+
var viewX;
109+
var viewY;
110+
var retmp;
111+
var imtmp;
112+
var isrm;
113+
var xlen;
114+
var ylen;
115+
var sign;
116+
var doa2;
117+
var sa0;
118+
var sa1;
119+
var rea;
120+
var ima;
121+
var rex;
122+
var imx;
123+
var oa2;
124+
var oa;
125+
var ox;
126+
var oy;
127+
var sx;
128+
var sy;
129+
var i0;
130+
var i1;
131+
var ia;
132+
var ix;
133+
var iy;
134+
135+
// Note on variable naming convention: sa#, ix#, i# where # corresponds to the loop number, with `0` being the innermost loop...
136+
137+
isrm = isRowMajor( [ strideA1, strideA2 ] );
138+
if ( isrm ) {
139+
// For row-major matrices, the last dimension has the fastest changing index...
140+
sa0 = strideA2 * 2; // stride for innermost loop
141+
sa1 = strideA1 * 2; // stride for outermost loop
142+
} else { // isColMajor
143+
// For column-major matrices, the first dimension has the fastest changing index...
144+
sa0 = strideA1 * 2; // stride for innermost loop
145+
sa1 = strideA2 * 2; // stride for outermost loop
146+
}
147+
if ( isTransposed( trans ) ) {
148+
xlen = M;
149+
ylen = N;
150+
} else {
151+
xlen = N;
152+
ylen = M;
153+
}
154+
// Decompose scalars into real and imaginary components:
155+
rebeta = realf( beta );
156+
imbeta = imagf( beta );
157+
realpha = realf( alpha );
158+
imalpha = imagf( alpha );
159+
160+
// y = beta*y
161+
if ( rebeta === 0.0 && imbeta === 0.0 ) {
162+
zfill( ylen, alpha, y, strideY, offsetY );
163+
} else if ( rebeta !== 1.0 || imbeta !== 0.0 ) {
164+
zscal( ylen, beta, y, strideY, offsetY );
165+
}
166+
if ( realpha === 0.0 && imalpha === 0.0 ) {
167+
return y;
168+
}
169+
// Reinterpret arrays as real-valued views of interleaved real and imaginary components:
170+
viewA = reinterpret( A, 0 );
171+
viewX = reinterpret( x, 0 );
172+
viewY = reinterpret( y, 0 );
173+
if ( trans === 'conjugate-transpose' ) {
174+
sign = -1;
175+
} else {
176+
sign = 1;
177+
}
178+
oa = offsetA * 2;
179+
ox = offsetX * 2;
180+
oy = offsetY * 2;
181+
sx = strideX * 2;
182+
sy = strideY * 2;
183+
doa2 = sa1 - sa0;
184+
185+
// Form: y = α*A*x + y
186+
if (
187+
( !isrm && !isTransposed( trans ) ) ||
188+
( isrm && isTransposed( trans ) )
189+
) {
190+
ix = ox;
191+
oa2 = oa + (KU*sa0);
192+
for ( i1 = 0; i1 < xlen; i1++ ) {
193+
ix = ox + (i1*sx);
194+
rex = viewX[ ix ];
195+
imx = viewX[ ix+1 ];
196+
retmp = (realpha*rex) - (imalpha*imx);
197+
imtmp = (realpha*imx) + (imalpha*rex);
198+
i0start = max(0, i1-KU);
199+
i0end = min(ylen, i1+KL+1);
200+
ia = oa2 + (i0start*sa0);
201+
iy = oy + (i0start*sy);
202+
for ( i0 = i0start; i0 < i0end; i0++ ) {
203+
rea = viewA[ ia ];
204+
ima = sign * viewA[ ia+1 ];
205+
muladd( rea, ima, retmp, imtmp, viewY[ iy ], viewY[ iy+1 ], viewY, 1, iy ); // eslint-disable-line max-len
206+
ia += sa0;
207+
iy += sy;
208+
}
209+
ix += sx;
210+
oa2 += doa2;
211+
}
212+
return y;
213+
}
214+
// Form: y = α*A^T*x + y
215+
216+
// ( !isrm && isTransposed( trans ) ) || ( isrm && !isTransposed( trans ) )
217+
iy = oy;
218+
oa2 = oa + (KL*sa0);
219+
for ( i1 = 0; i1 < ylen; i1++ ) {
220+
retmp = 0.0;
221+
imtmp = 0.0;
222+
i0start = max(0, i1-KL);
223+
i0end = min(xlen, i1+KU+1);
224+
ia = oa2 + (i0start*sa0);
225+
ix = ox + (i0start*sx);
226+
for ( i0 = i0start; i0 < i0end; i0++ ) {
227+
rea = viewA[ ia ];
228+
ima = sign * viewA[ ia+1 ];
229+
rex = viewX[ ix ];
230+
imx = viewX[ ix+1 ];
231+
retmp += (rea*rex) - (ima*imx);
232+
imtmp += (rea*imx) + (ima*rex);
233+
ia += sa0;
234+
ix += sx;
235+
}
236+
muladd( realpha, imalpha, retmp, imtmp, viewY[ iy ], viewY[ iy+1 ], viewY, 1, iy ); // eslint-disable-line max-len
237+
iy += sy;
238+
oa2 += doa2;
239+
}
240+
return y;
241+
}
242+
243+
244+
// EXPORTS //
245+
246+
module.exports = zgbmv;
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/**
2+
* @license Apache-2.0
3+
*
4+
* Copyright (c) 2026 The Stdlib Authors.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
'use strict';
20+
21+
/**
22+
* BLAS level 2 routine to performs one of the matrix-vector operations `y = α*A*x + β*y` or `y = α*A^T*x + β*y` or `y = α*A^H*x + β*y`, where `α` and `β` are scalars, `x` and `y` are vectors, and `A` is an `M` by `N` band matrix with `KL` sub-diagonals and `KU` super-diagonals.
23+
*
24+
* @module @stdlib/blas/base/zgbmv
25+
*
26+
* @example
27+
* var Complex128Array = require( '@stdlib/array/complex128' );
28+
* var Complex128 = require( '@stdlib/complex/float64/ctor' );
29+
* var zgbmv = require( '@stdlib/blas/base/zgbmv' );
30+
*
31+
* var A = new Complex128Array( [ 0.0, 0.0, 1.0, 1.0, 3.0, 3.0, 2.0, 2.0, 4.0, 4.0, 6.0, 6.0, 5.0, 5.0, 7.0, 7.0, 0.0, 0.0 ] );
32+
* var x = new Complex128Array( [ 1.0, 1.0, 2.0, 2.0, 3.0, 3.0 ] );
33+
* var y = new Complex128Array( [ 3.0, 3.0, 2.0, 2.0, 1.0, 1.0 ] );
34+
* var alpha = new Complex128( 0.5, 0.5 );
35+
* var beta = new Complex128( 0.5, -0.5 );
36+
*
37+
* zgbmv( 'row-major', 'no-transpose', 3, 3, 1, 1, alpha, A, 3, x, 1, beta, y, 1 );
38+
* // y => <Complex128Array>[ -4.0, 7.0, -26.0, 28.0, -30.0, 31.0 ]
39+
*
40+
* @example
41+
* var Complex128Array = require( '@stdlib/array/complex128' );
42+
* var Complex128 = require( '@stdlib/complex/float64/ctor' );
43+
* var zgbmv = require( '@stdlib/blas/base/zgbmv' );
44+
*
45+
* var A = new Complex128Array( [ 0.0, 0.0, 1.0, 1.0, 3.0, 3.0, 2.0, 2.0, 4.0, 4.0, 6.0, 6.0, 5.0, 5.0, 7.0, 7.0, 0.0, 0.0 ] );
46+
* var x = new Complex128Array( [ 1.0, 1.0, 2.0, 2.0, 3.0, 3.0 ] );
47+
* var y = new Complex128Array( [ 3.0, 3.0, 2.0, 2.0, 1.0, 1.0 ] );
48+
* var alpha = new Complex128( 0.5, 0.5 );
49+
* var beta = new Complex128( 0.5, -0.5 );
50+
*
51+
* zgbmv.ndarray( 'no-transpose', 3, 3, 1, 1, alpha, A, 3, 1, 0, x, 1, 0, beta, y, 1, 0 );
52+
* // y => <Complex128Array>[ -4.0, 7.0, -26.0, 28.0, -30.0, 31.0 ]
53+
*/
54+
55+
// MODULES //
56+
57+
var join = require( 'path' ).join;
58+
var tryRequire = require( '@stdlib/utils/try-require' );
59+
var isError = require( '@stdlib/assert/is-error' );
60+
var main = require( './main.js' );
61+
62+
63+
// MAIN //
64+
65+
var zgbmv;
66+
var tmp = tryRequire( join( __dirname, './native.js' ) );
67+
if ( isError( tmp ) ) {
68+
zgbmv = main;
69+
} else {
70+
zgbmv = tmp;
71+
}
72+
73+
74+
// EXPORTS //
75+
76+
module.exports = zgbmv;
77+
78+
// exports: { "ndarray": "zgbmv.ndarray" }
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/**
2+
* @license Apache-2.0
3+
*
4+
* Copyright (c) 2026 The Stdlib Authors.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
'use strict';
20+
21+
// MODULES //
22+
23+
var setReadOnly = require( '@stdlib/utils/define-nonenumerable-read-only-property' );
24+
var zgbmv = require( './zgbmv.js' );
25+
var ndarray = require( './ndarray.js' );
26+
27+
28+
// MAIN //
29+
30+
setReadOnly( zgbmv, 'ndarray', ndarray );
31+
32+
33+
// EXPORTS //
34+
35+
module.exports = zgbmv;

0 commit comments

Comments
 (0)