Skip to content

feat: add lapack/base/dlarf1f #7540

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 7 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
131 changes: 131 additions & 0 deletions lib/node_modules/@stdlib/lapack/base/dlarf1f/lib/base.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
/**
* @license Apache-2.0
*
* Copyright (c) 2025 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';

/* eslint-disable max-len */

// MODULES //

var iladlc = require( '@stdlib/lapack/base/iladlc' ).ndarray;
var iladlr = require( '@stdlib/lapack/base/iladlr' ).ndarray;
var dgemv = require( '@stdlib/blas/base/dgemv' ).ndarray;
var dger = require( '@stdlib/blas/base/dger' ).ndarray;
var daxpy = require( '@stdlib/blas/base/daxpy' ).ndarray;
var dscal = require( '@stdlib/blas/base/dscal' ).ndarray;


// MAIN //

/**
* Applies a real elementary reflector `H = I - tau * v * v ^ T` to a real M by N matrix `C`.
*
* ## Notes
*
* - `work` should have `N` indexed elements if side = `left` and `M` indexed elements if side = `right`.
* - `V` should have `1 + (M-1) * abs(strideV)` indexed elements if side = `left` and `1 + (N-1) * abs(strideV)` indexed elements if side = `right`.
* - `C` is overwritten by `H * C` if side = `left` and `C * H` if side = `right`.
*
* @private
* @param {string} side - use `left` to form `H * C` and `right` to from `C * H`
* @param {NonNegativeInteger} M - number of rows in `C`
* @param {NonNegativeInteger} N - number of columns in `C`
* @param {Float64Array} V - the vector `v` in the representation of `H`
* @param {integer} strideV - stride length for `V`
* @param {NonNegativeInteger} offsetV - starting index for `V`
* @param {number} tau - the value of `tau` in representation of `H`
* @param {Float64Array} C - input matrix
* @param {integer} strideC1 - stride of the first dimension of `C`
* @param {integer} strideC2 - stride of the second dimension of `C`
* @param {NonNegativeInteger} offsetC - starting index for `C`
* @param {Float64Array} work - workspace array
* @param {integer} strideWork - stride length for `work`
* @param {NonNegativeInteger} offsetWork - starting index for `work`
* @returns {Float64Array} `C * H` or `H * C`
*
* @example
* var Float64Array = require( '@stdlib/array/float64' );
*
* var C = new Float64Array( [ 1.0, 5.0, 9.0, 2.0, 6.0, 10.0, 3.0, 7.0, 11.0, 4.0, 8.0, 12.0 ] );
* var V = new Float64Array( [ 0.5, 0.5, 0.5, 0.5 ] );
* var work = new Float64Array( 3 );
*
* var out = dlarf1f( 'left', 4, 3, V, 1, 0, 1.0, C, 3, 1, 0, work, 1, 0 );
* // returns <Float64Array>[ -4.5, -10.5, -16.5, -0.75, -1.75, -2.75, 0.25, -0.75, -1.75, 1.25, 0.25, -0.75 ]
*/
function dlarf1f( side, M, N, V, strideV, offsetV, tau, C, strideC1, strideC2, offsetC, work, strideWork, offsetWork ) { // eslint-disable-line max-params
var lastv;
var lastc;
var i;

lastv = 1;
lastc = 0;
if ( tau !== 0.0 ) {
if ( side === 'left' ) {
lastv = M;
} else {
lastv = N;
}

// check here

Check warning on line 85 in lib/node_modules/@stdlib/lapack/base/dlarf1f/lib/base.js

View workflow job for this annotation

GitHub Actions / Lint Changed Files

Comments should begin with an uppercase character
if ( strideV > 0 ) {
i = offsetV + ( ( lastv - 1 ) * strideV );
} else {
i = offsetV;
}

while ( lastv > 0 && V[ i ] === 0.0 ) {
lastv -= 1;
i -= strideV;
}
if ( side === 'left' ) {
lastc = iladlc( lastv + 1, N, C, strideC1, strideC2, offsetC ) + 1; // to account for the difference between zero-based and one-based indexing
} else {
lastc = iladlr( M, lastv + 1, C, strideC1, strideC2, offsetC ) + 1; // to account for the difference between zero-based and one-based indexing
}
// lastc is zero if a matrix is filled with zeros

Check warning on line 101 in lib/node_modules/@stdlib/lapack/base/dlarf1f/lib/base.js

View workflow job for this annotation

GitHub Actions / Lint Changed Files

Unknown word: "lastc"
}
if ( lastc === 0 ) {
// Returns C unchanged if tau is zero or all elements in C are zero
return C;
}
if ( side === 'left' ) {
if ( lastv === 0 ) {
dscal( lastc, 1.0 - tau, C, strideC2, offsetC ); // scale the first row
} else {
dgemv( 'transpose', lastv-1, lastc, 1.0, C, strideC1, strideC2, offsetC + strideC1, V, strideV, offsetV + strideV, 0.0, work, strideWork, offsetWork ); // C( 1, 0 ) is accessed here
daxpy( lastc, 1.0, C, strideC2, offsetC, work, strideWork, offsetWork ); // operates on the first row of C
daxpy( lastc, -tau, work, strideWork, offsetWork, C, strideC2, offsetC ); // operates on the first row of C
dger( lastv-1, lastc, -tau, V, strideV, offsetV + strideV, work, strideWork, offsetWork, C, strideC1, strideC2, offsetC + strideC1 ); // C( 1, 0 ) is accessed here
}
} else if ( lastv === 0 ) {
dscal( lastc, 1.0 - tau, C, strideC1, offsetC ); // scale the first column
} else {
dgemv( 'no-transpose', lastc, lastv-1, 1.0, C, strideC1, strideC2, offsetC + strideC2, V, strideV, offsetV + strideV, 0.0, work, strideWork, offsetWork ); // C( 0, 1 ) is accessed here
daxpy( lastc, 1.0, C, strideC1, offsetC, work, strideWork, offsetWork ); // operates on the first column of C
daxpy( lastc, -tau, work, strideWork, offsetWork, C, strideC1, offsetC ); // operates on the first column of C
dger( lastc, lastv-1, -tau, work, strideWork, offsetWork, V, strideV, offsetV + strideV, C, strideC1, strideC2, offsetC + strideC2 ); // C( 0, 1 ) is accessed here
}

return C;
}


// EXPORTS //

module.exports = dlarf1f;
104 changes: 104 additions & 0 deletions lib/node_modules/@stdlib/lapack/base/dlarf1f/lib/dlarf1f.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
/**
* @license Apache-2.0
*
* Copyright (c) 2025 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 isLayout = require( '@stdlib/blas/base/assert/is-layout' );
var isRowMajor = require( '@stdlib/ndarray/base/assert/is-row-major-string' );
var isColumnMajor = require( '@stdlib/ndarray/base/assert/is-column-major-string' );
var max = require( '@stdlib/math/base/special/max' );
var format = require( '@stdlib/string/format' );
var stride2offset = require( '@stdlib/strided/base/stride2offset' );
var base = require( './base.js' );


// MAIN //

/**
* Applies a real elementary reflector `H = I - tau * v * v ^ T` to a real M by N matrix `C`.
*
* ## Notes
*
* - `work` should have `N` indexed elements if side = `left` and `M` indexed elements if side = `right`.
* - `V` should have `1 + (M-1) * abs(incv)` indexed elements if side = `left` and `1 + (N-1) * abs(incv)` indexed elements if side = `right`.
* - `C` is overwritten by `H * C` if side = `left` and `C * H` if side = `right`.
*
* @param {string} order - storage layout
* @param {string} side - use `left` to form `H * C` and `right` to from `C * H`
* @param {NonNegativeInteger} M - number of rows in `C`
* @param {NonNegativeInteger} N - number of columns in `C`
* @param {Float64Array} V - the vector `v` in the representation of `H`
* @param {integer} incv - stride length for `V`
* @param {number} tau - the value of `tau` in representation of `H`
* @param {Float64Array} C - input matrix
* @param {PositiveInteger} LDC - stride of the first dimension of `C` (a.k.a., leading dimension of the matrix `C`)
* @param {Float64Array} work - workspace array
* @throws {TypeError} first argument must be a valid order
* @throws {TypeError} second argument must be a valid side
* @throws {RangeError} ninth argument must be greater than or equal to max(1,N)
* @throws {RangeError} fifth argument must not be zero
* @returns {Float64Array} `C * H` or `H * C`
*
* @example
* var Float64Array = require( '@stdlib/array/float64' );
*
* var C = new Float64Array( [ 1.0, 5.0, 9.0, 2.0, 6.0, 10.0, 3.0, 7.0, 11.0, 4.0, 8.0, 12.0 ] );
* var V = new Float64Array( [ 0.5, 0.5, 0.5, 0.5 ] );
* var work = new Float64Array( 3 );
*
* var out = dlarf1f( 'row-major', 'left', 4, 3, V, 1, 1.0, C, 3, work );
* // returns <Float64Array>[ -4.5, -10.5, -16.5, -0.75, -1.75, -2.75, 0.25, -0.75, -1.75, 1.25, 0.25, -0.75 ]
*/
function dlarf1f( order, side, M, N, V, incv, tau, C, LDC, work ) {
var sc1;
var sc2;
var ov;

if ( !isLayout( order ) ) {
throw new TypeError( format( 'invalid argument. First argument must be a valid order. Value: `%s`.', order ) );
}
if ( isRowMajor( order ) && LDC < max( 1, N ) ) {
throw new RangeError( format( 'invalid argument. Fourth argument must be greater than or equal to max(1,%d). Value: `%d`.', N, LDC ) );
}
if ( side !== 'left' && side !== 'right' ) { // TODO - refactor this to make use of an array if needed

Check warning on line 80 in lib/node_modules/@stdlib/lapack/base/dlarf1f/lib/dlarf1f.js

View workflow job for this annotation

GitHub Actions / Lint Changed Files

Unexpected 'todo' comment: 'TODO - refactor this to make use of an...'
throw new TypeError( format( 'invalid argument. Second argument must be a valid side (left or right). Value: `%s`.', side ) );
}
if ( incv === 0 ) {
throw new RangeError( format( 'invalid argument. Fifth argument must not be zero' ) );
}
if ( isColumnMajor( order ) ) {
sc1 = 1;
sc2 = LDC;
} else { // order === 'row-major'
sc1 = LDC;
sc2 = 1;
}
if ( side === 'left' ) {
ov = stride2offset( M, incv );
} else {
ov = stride2offset( N, incv );
}
return base( side, M, N, V, incv, ov, tau, C, sc1, sc2, 0, work, 1, 0 );
}


// EXPORTS //

module.exports = dlarf1f;
65 changes: 65 additions & 0 deletions lib/node_modules/@stdlib/lapack/base/dlarf1f/lib/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/**
* @license Apache-2.0
*
* Copyright (c) 2025 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';

/**
* LAPACK routine to apply a real elementary reflector `H = I - tau * v * v ^ T` to a real M by N matrix `C`.
*
* ## Notes
*
* - `work` should have `N` indexed elements if side = `left` and `M` indexed elements if side = `right`.
* - `V` should have `1 + (M-1) * abs(incv)` indexed elements if side = `left` and `1 + (N-1) * abs(incv)` indexed elements if side = `right`.
* - `C` is overwritten by `H * C` if side = `left` and `C * H` if side = `right`.
*
* @module @stdlib/lapack/base/dlarf1f
*
* @example
* var Float64Array = require( '@stdlib/array/float64' );
* var dlarf1f = require( '@stdlib/lapack/base/dlarf1f' );
*
* var C = new Float64Array( [ 1.0, 5.0, 9.0, 2.0, 6.0, 10.0, 3.0, 7.0, 11.0, 4.0, 8.0, 12.0 ] );
* var V = new Float64Array( [ 0.5, 0.5, 0.5, 0.5 ] );
* var work = new Float64Array( 3 );
*
* var out = dlarf1f( 'left', 4, 3, V, 1, 1.0, C, 3, work );
* // returns <Float64Array>[ -4.5, -10.5, -16.5, -0.75, -1.75, -2.75, 0.25, -0.75, -1.75, 1.25, 0.25, -0.75 ]
*/

// MODULES //

var join = require( 'path' ).join;
var tryRequire = require( '@stdlib/utils/try-require' );
var isError = require( '@stdlib/assert/is-error' );
var main = require( './main.js' );


// MAIN //

var dlarf1f;
var tmp = tryRequire( join( __dirname, './native.js' ) );
if ( isError( tmp ) ) {
dlarf1f = main;
} else {
dlarf1f = tmp;
}


// EXPORTS //

module.exports = dlarf1f;
35 changes: 35 additions & 0 deletions lib/node_modules/@stdlib/lapack/base/dlarf1f/lib/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/**
* @license Apache-2.0
*
* Copyright (c) 2025 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 setReadOnly = require( '@stdlib/utils/define-nonenumerable-read-only-property' );
var dlarf1f = require( './dlarf1f.js' );
var ndarray = require( './ndarray.js' );


// MAIN //

setReadOnly( dlarf1f, 'ndarray', ndarray );


// EXPORTS //

module.exports = dlarf1f;
Loading
Loading