All files dorgbr.js

97.74% Statements 130/133
96.29% Branches 26/27
100% Functions 1/1
97.74% Lines 130/133

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 1342x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 62x 62x 62x 62x 62x 62x 13x 13x 62x 15x 15x 34x 62x 3x 3x 62x 23x 5x 5x 62x 5x 5x 62x 3x 3x 62x 15x 3x 3x 12x 12x 62x 3x 3x 3x       62x 3x 3x 9x 62x 2x 2x 2x 2x 2x  
/**
* @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 isLayout = require( '@stdlib/blas/base/assert/is-layout' );
var format = require( '@stdlib/string/format' );
var max = require( '@stdlib/math/base/special/fast/max' );
var min = require( '@stdlib/math/base/special/min' );
var base = require( './base.js' );
 
 
// MAIN //
 
/**
* Generates one of the real orthogonal matrices `Q` or `P^T` determined by `DGEBRD` when reducing a real matrix `A` to bidiagonal form: `A = Q * B * P^T`.
*
* ## Notes
*
* -   `Q` and `P^T` are defined as products of elementary reflectors `H(i)` or `G(i)` respectively.
*
* -   If `vect = 'Q'`,
*
*     -   `A` is assumed to have been an `M-by-K` matrix, and `Q` is of order `M`.
*     -   if `m >= k`, `Q = H(1) H(2) . . . H(k)` and `dorgbr` returns the first `n` columns of `Q`, where `m >= n >= k`.
*     -   if `m < k`, `Q = H(1) H(2) . . . H(m-1)` and `dorgbr` returns `Q` as an `M-by-M` matrix.
*
* -   If `vect = 'P'`,
*
*     -   `A` is assumed to have been a `K-by-N` matrix, and `P^T` is of order `N`.
*     -   if `k < n`, `P^T = G(k) . . . G(2) G(1)` and `dorgbr` returns the first `m` rows of `P^T`, where `n >= m >= k`.
*     -   if `k >= n`, `P^T = G(n-1) . . . G(2) G(1)` and `dorgbr` returns `P^T` as an `N-by-N` matrix.
*
* -   `WORK` must have length, `LWORK >= max(1,min(M,N))`. For optimum performance `LWORK >= min(M,N)*NB`, where `NB` is the optimal blocksize.
*
* -   If `LWORK = -1`, then a workspace query is assumed; the routine only calculates the optimal size of the `WORK` array, returns this value as the first entry of the `WORK` array, and no error message related to `LWORK` is issued.
*
* @param {string} order - storage layout
* @param {string} vect - specifies whether the matrix `Q` or the matrix `P^T` is returned in `A`
* @param {NonNegativeInteger} M - number of rows of `Q` or `P^T`
* @param {NonNegativeInteger} N - number of columns of `Q` or `P^T`
* @param {NonNegativeInteger} K - number of elementary reflectors
* @param {Float64Array} A - input/output matrix
* @param {integer} LDA - stride of the first dimension of `A` (a.k.a., leading dimension of the matrix `A`)
* @param {Float64Array} TAU - scalar factors of elementary reflectors
* @param {Float64Array} WORK - workspace array
* @param {NonNegativeInteger} LWORK - dimension of the array `WORK`
* @throws {TypeError} first argument must be a valid order
* @throws {TypeError} second argument must be either `'Q'` or `'P'`
* @throws {RangeError} third argument must be a non-negative integer
* @throws {RangeError} fourth argument must be a non-negative integer satisfying the constraints for the given `vect` argument
* @throws {RangeError} fifth argument must be a non-negative integer
* @throws {RangeError} seventh argument must be a valid `LDA` value
* @throws {RangeError} tenth argument must be a valid `LWORK` value
* @returns {integer} status code
*
* @example
* var Float64Array = require( '@stdlib/array/float64' );
*
* var A = new Float64Array( [ 1, 0.2, -0.1, 0.3, 0, 1, 0.4, -0.2, 0, 0, 1, 0.5 ] );
* var TAU = new Float64Array( [ 1.3, 0.9, 1.1 ] );
* var WORK = new Float64Array( 10 );
*
* var info = dorgbr( 'column-major', 'Q', 4, 3, 3, A, 4, TAU, WORK, 10 );
* // A => <Float64Array>[ -0.3, -0.26, 0.13, -0.39, -0.143, 0.0714, -0.3457, 0.1371, ~0.21, ~-0.021, ~-0.146, ~-0.474 ]
* // info => 0
* // WORK[ 0 ] => 64
*/
function dorgbr( order, vect, M, N, K, A, LDA, TAU, WORK, LWORK ) { // eslint-disable-line stdlib/jsdoc-doctest-decimal-point
	var wantq;
	var sa1;
	var sa2;
 
	if ( !isLayout( order ) ) {
		throw new TypeError( format( 'invalid argument. First argument must be a valid order. Value: `%s`.', order ) );
	}
	if ( vect !== 'Q' && vect !== 'P' ) {
		throw new TypeError( format( 'invalid argument. Second argument must be either `\'Q\'` or `\'P\'`. Value: `%s`.', vect ) );
	}
	wantq = ( vect === 'Q' );
	if ( M < 0 ) {
		throw new RangeError( format( 'invalid argument. Third argument must be a nonnegative integer. Value: `%d`.', M ) );
	}
	if ( wantq ) {
		if ( N < min( M, K ) || N > M ) {
			throw new RangeError( format( 'invalid argument. Fourth argument must be greater than or equal to `min(M,K)` and smaller than or equal to `M`. Value: `%d`.', N ) );
		}
	} else if ( N < M || M < min( N, K ) ) {
		throw new RangeError( format( 'invalid argument. Fourth argument must be greater than or equal to `M`, and `M` must be greater than or equal to `min(N,K)`. Value: `%d`.', N ) );
	}
	if ( K < 0 ) {
		throw new RangeError( format( 'invalid argument. Fifth argument must be a nonnegative integer. Value: `%d`.', K ) );
	}
	if ( order === 'column-major' ) {
		if ( LDA < max( 1, M ) ) {
			throw new RangeError( format( 'invalid argument. Seventh argument must be greater than or equal to `max(1,M)`. Value: `%d`.', LDA ) );
		}
		sa1 = 1;
		sa2 = LDA;
	} else { // row-major
		if ( LDA < max( 1, N ) ) {
			throw new RangeError( format( 'invalid argument. Seventh argument must be greater than or equal to `max(1,N)`. Value: `%d`.', LDA ) );
		}
		sa1 = LDA;
		sa2 = 1;
	}
	if ( LWORK < max( 1, min( M, N ) ) && LWORK !== -1 ) {
		throw new RangeError( format( 'invalid argument. Tenth argument must be greater than or equal to `max(1,min(M,N))` except when equal to -1. Value: `%d`.', LWORK ) );
	}
	return base( vect, M, N, K, A, sa1, sa2, 0, TAU, 1, 0, WORK, 1, 0, LWORK );
}
 
 
// EXPORTS //
 
module.exports = dorgbr;