Skip to content

Commit 95afc49

Browse files
authored
feat: add blas/ext/base/dtril
PR-URL: #13863 Reviewed-by: Athan Reines <kgryte@gmail.com>
1 parent 54a33d7 commit 95afc49

34 files changed

Lines changed: 4722 additions & 0 deletions
Lines changed: 353 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,353 @@
1+
<!--
2+
3+
@license Apache-2.0
4+
5+
Copyright (c) 2026 The Stdlib Authors.
6+
7+
Licensed under the Apache License, Version 2.0 (the "License");
8+
you may not use this file except in compliance with the License.
9+
You may obtain a copy of the License at
10+
11+
http://www.apache.org/licenses/LICENSE-2.0
12+
13+
Unless required by applicable law or agreed to in writing, software
14+
distributed under the License is distributed on an "AS IS" BASIS,
15+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
See the License for the specific language governing permissions and
17+
limitations under the License.
18+
19+
-->
20+
21+
# dtril
22+
23+
> Copy the lower triangular part of a double-precision floating-point matrix `A` to another matrix `B`.
24+
25+
<section class="intro">
26+
27+
</section>
28+
29+
<!-- /.intro -->
30+
31+
<section class="usage">
32+
33+
## Usage
34+
35+
```javascript
36+
var dtril = require( '@stdlib/blas/ext/base/dtril' );
37+
```
38+
39+
#### dtril( order, M, N, k, A, LDA, B, LDB )
40+
41+
Copies the lower triangular part of a double-precision floating-point matrix `A` to another matrix `B`.
42+
43+
```javascript
44+
var Float64Array = require( '@stdlib/array/float64' );
45+
46+
var A = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] );
47+
var B = new Float64Array( [ 0.0, 0.0, 0.0, 0.0 ] );
48+
49+
dtril( 'row-major', 2, 2, 0, A, 2, B, 2 );
50+
// B => <Float64Array>[ 1.0, 0.0, 3.0, 4.0 ]
51+
```
52+
53+
The function has the following parameters:
54+
55+
- **order**: storage layout.
56+
- **M**: number of rows in `A`.
57+
- **N**: number of columns in `A`.
58+
- **k**: diagonal above which to ignore. A value of `k = 0` refers to the main diagonal, `k < 0` refers to a diagonal below the main diagonal, and `k > 0` refers to a diagonal above the main diagonal. Accordingly, when `k > 0`, the function copies the lower triangle **and** one or more super-diagonals (i.e., part of the upper triangle), and, when `k < 0`, the function copies only part of the lower triangle.
59+
- **A**: input matrix.
60+
- **LDA**: stride of the first dimension of `A` (a.k.a., leading dimension of the matrix `A`).
61+
- **B**: output matrix.
62+
- **LDB**: stride of the first dimension of `B` (a.k.a., leading dimension of the matrix `B`).
63+
64+
Setting the `k` parameter to a value other than `0` allows including and excluding super- and sub-diagonals, respectively. For example, to copy the lower triangle and the first super-diagonal,
65+
66+
```javascript
67+
var Float64Array = require( '@stdlib/array/float64' );
68+
69+
var A = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] );
70+
var B = new Float64Array( [ 0.0, 0.0, 0.0, 0.0 ] );
71+
72+
dtril( 'row-major', 2, 2, 1, A, 2, B, 2 );
73+
// B => <Float64Array>[ 1.0, 2.0, 3.0, 4.0 ]
74+
```
75+
76+
Note that indexing is relative to the first index. To introduce an offset, use [`typed array`][mdn-typed-array] views.
77+
78+
<!-- eslint-disable stdlib/capitalized-comments -->
79+
80+
```javascript
81+
var Float64Array = require( '@stdlib/array/float64' );
82+
83+
// Initial arrays...
84+
var A0 = new Float64Array( [ 1.0, 2.0, 3.0, 4.0, 5.0 ] );
85+
var B0 = new Float64Array( 5 );
86+
87+
// Create offset views...
88+
var A1 = new Float64Array( A0.buffer, A0.BYTES_PER_ELEMENT*1 ); // start at 2nd element
89+
var B1 = new Float64Array( B0.buffer, B0.BYTES_PER_ELEMENT*1 ); // start at 2nd element
90+
91+
dtril( 'row-major', 2, 2, 0, A1, 2, B1, 2 );
92+
// B0 => <Float64Array>[ 0.0, 2.0, 0.0, 4.0, 5.0 ]
93+
```
94+
95+
#### dtril.ndarray( M, N, k, A, sa1, sa2, oa, B, sb1, sb2, ob )
96+
97+
Copies the lower triangular part of a double-precision floating-point matrix `A` to another matrix `B` using alternative indexing semantics.
98+
99+
```javascript
100+
var Float64Array = require( '@stdlib/array/float64' );
101+
102+
var A = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] );
103+
var B = new Float64Array( [ 0.0, 0.0, 0.0, 0.0 ] );
104+
105+
dtril.ndarray( 2, 2, 0, A, 2, 1, 0, B, 2, 1, 0 );
106+
// B => <Float64Array>[ 1.0, 0.0, 3.0, 4.0 ]
107+
```
108+
109+
The function has the following parameters:
110+
111+
- **M**: number of rows in `A`.
112+
- **N**: number of columns in `A`.
113+
- **k**: diagonal above which to ignore.
114+
- **A**: input matrix.
115+
- **sa1**: stride of the first dimension of `A`.
116+
- **sa2**: stride of the second dimension of `A`.
117+
- **oa**: starting index for `A`.
118+
- **B**: output matrix.
119+
- **sb1**: stride of the first dimension of `B`.
120+
- **sb2**: stride of the second dimension of `B`.
121+
- **ob**: starting index for `B`.
122+
123+
While [`typed array`][mdn-typed-array] views mandate a view offset based on the underlying buffer, the offset parameters support indexing semantics based on starting indices. For example,
124+
125+
```javascript
126+
var Float64Array = require( '@stdlib/array/float64' );
127+
128+
var A = new Float64Array( [ 1.0, 2.0, 3.0, 4.0 ] );
129+
var B = new Float64Array( [ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 ] );
130+
131+
dtril.ndarray( 2, 2, 0, A, 2, 1, 0, B, 2, 1, 2 );
132+
// B => <Float64Array>[ 0.0, 0.0, 1.0, 0.0, 3.0, 4.0 ]
133+
```
134+
135+
</section>
136+
137+
<!-- /.usage -->
138+
139+
<section class="notes">
140+
141+
## Notes
142+
143+
- Elements outside of the copied region are left unchanged.
144+
145+
</section>
146+
147+
<!-- /.notes -->
148+
149+
<section class="examples">
150+
151+
## Examples
152+
153+
<!-- eslint no-undef: "error" -->
154+
155+
```javascript
156+
var ndarray2array = require( '@stdlib/ndarray/base/to-array' );
157+
var uniform = require( '@stdlib/random/array/discrete-uniform' );
158+
var numel = require( '@stdlib/ndarray/base/numel' );
159+
var shape2strides = require( '@stdlib/ndarray/base/shape2strides' );
160+
var dtril = require( '@stdlib/blas/ext/base/dtril' );
161+
162+
var shape = [ 5, 8 ];
163+
var order = 'row-major';
164+
var strides = shape2strides( shape, order );
165+
166+
var N = numel( shape );
167+
168+
var A = uniform( N, -10, 10, {
169+
'dtype': 'float64'
170+
});
171+
console.log( ndarray2array( A, shape, strides, 0, order ) );
172+
173+
var B = uniform( N, -10, 10, {
174+
'dtype': 'float64'
175+
});
176+
console.log( ndarray2array( B, shape, strides, 0, order ) );
177+
178+
dtril( order, shape[ 0 ], shape[ 1 ], 0, A, strides[ 0 ], B, strides[ 0 ] );
179+
console.log( ndarray2array( B, shape, strides, 0, order ) );
180+
```
181+
182+
</section>
183+
184+
<!-- /.examples -->
185+
186+
<!-- C interface documentation. -->
187+
188+
* * *
189+
190+
<section class="c">
191+
192+
## C APIs
193+
194+
<!-- Section to include introductory text. Make sure to keep an empty line after the intro `section` element and another before the `/section` close. -->
195+
196+
<section class="intro">
197+
198+
</section>
199+
200+
<!-- /.intro -->
201+
202+
<!-- C usage documentation. -->
203+
204+
<section class="usage">
205+
206+
### Usage
207+
208+
```c
209+
#include "stdlib/blas/ext/base/dtril.h"
210+
```
211+
212+
#### stdlib_strided_dtril( layout, M, N, k, \*A, LDA, \*B, LDB )
213+
214+
Copies the lower triangular part of a double-precision floating-point matrix `A` to another matrix `B`.
215+
216+
```c
217+
#include "stdlib/blas/base/shared.h"
218+
219+
const double A[] = { 1.0, 2.0, 3.0, 4.0 };
220+
double B[] = { 0.0, 0.0, 0.0, 0.0 };
221+
222+
stdlib_strided_dtril( CblasRowMajor, 2, 2, 0, A, 2, B, 2 );
223+
```
224+
225+
The function accepts the following arguments:
226+
227+
- **layout**: `[in] CBLAS_LAYOUT` storage layout.
228+
- **M**: `[in] CBLAS_INT` number of rows in `A`.
229+
- **N**: `[in] CBLAS_INT` number of columns in `A`.
230+
- **k**: `[in] CBLAS_INT` diagonal above which to ignore.
231+
- **A**: `[in] double*` input matrix.
232+
- **LDA**: `[in] CBLAS_INT` stride of the first dimension of `A` (a.k.a., leading dimension of the matrix `A`).
233+
- **B**: `[out] double*` output matrix.
234+
- **LDB**: `[in] CBLAS_INT` stride of the first dimension of `B` (a.k.a., leading dimension of the matrix `B`).
235+
236+
```c
237+
void API_SUFFIX(stdlib_strided_dtril)( const CBLAS_LAYOUT layout, const CBLAS_INT M, const CBLAS_INT N, const CBLAS_INT k, const double *A, const CBLAS_INT LDA, double *B, const CBLAS_INT LDB );
238+
```
239+
240+
#### stdlib_strided_dtril_ndarray( M, N, k, \*A, sa1, sa2, oa, \*B, sb1, sb2, ob )
241+
242+
Copies the lower triangular part of a double-precision floating-point matrix `A` to another matrix `B` using alternative indexing semantics.
243+
244+
```c
245+
#include "stdlib/blas/base/shared.h"
246+
247+
const double A[] = { 1.0, 2.0, 3.0, 4.0 };
248+
double B[] = { 0.0, 0.0, 0.0, 0.0 };
249+
250+
stdlib_strided_dtril_ndarray( 2, 2, 0, A, 2, 1, 0, B, 2, 1, 0 );
251+
```
252+
253+
The function accepts the following arguments:
254+
255+
- **M**: `[in] CBLAS_INT` number of rows in `A`.
256+
- **N**: `[in] CBLAS_INT` number of columns in `A`.
257+
- **k**: `[in] CBLAS_INT` diagonal above which to ignore.
258+
- **A**: `[in] double*` input matrix.
259+
- **sa1**: `[in] CBLAS_INT` stride of the first dimension of `A`.
260+
- **sa2**: `[in] CBLAS_INT` stride of the second dimension of `A`.
261+
- **oa**: `[in] CBLAS_INT` starting index for `A`.
262+
- **B**: `[out] double*` output matrix.
263+
- **sb1**: `[in] CBLAS_INT` stride of the first dimension of `B`.
264+
- **sb2**: `[in] CBLAS_INT` stride of the second dimension of `B`.
265+
- **ob**: `[in] CBLAS_INT` starting index for `B`.
266+
267+
```c
268+
void API_SUFFIX(stdlib_strided_dtril_ndarray)( const CBLAS_INT M, const CBLAS_INT N, const CBLAS_INT k, const double *A, const CBLAS_INT strideA1, const CBLAS_INT strideA2, const CBLAS_INT offsetA, double *B, const CBLAS_INT strideB1, const CBLAS_INT strideB2, const CBLAS_INT offsetB );
269+
```
270+
271+
</section>
272+
273+
<!-- /.usage -->
274+
275+
<!-- C API usage notes. Make sure to keep an empty line after the `section` element and another before the `/section` close. -->
276+
277+
<section class="notes">
278+
279+
</section>
280+
281+
<!-- /.notes -->
282+
283+
<!-- C API usage examples. -->
284+
285+
<section class="examples">
286+
287+
### Examples
288+
289+
```c
290+
#include "stdlib/blas/ext/base/dtril.h"
291+
#include "stdlib/blas/base/shared.h"
292+
#include <stdio.h>
293+
294+
int main( void ) {
295+
// Define a 3x3 input matrix stored in row-major order:
296+
const double A[ 3*3 ] = { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0 };
297+
298+
// Define a 3x3 output matrix:
299+
double B[ 3*3 ] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
300+
301+
// Specify the number of elements along each dimension of `A`:
302+
const CBLAS_INT M = 3;
303+
const CBLAS_INT N = 3;
304+
305+
// Copy the lower triangular part of `A` to `B`:
306+
stdlib_strided_dtril( CblasRowMajor, M, N, 0, A, N, B, N );
307+
308+
// Print the result:
309+
for ( int i = 0; i < M; i++ ) {
310+
for ( int j = 0; j < N; j++ ) {
311+
printf( "B[ %i,%i ] = %lf\n", i, j, B[ (i*N)+j ] );
312+
}
313+
}
314+
315+
// Copy the lower triangular part of `A`, including the first super-diagonal, to `B` using alternative indexing semantics:
316+
stdlib_strided_dtril_ndarray( M, N, 1, A, N, 1, 0, B, N, 1, 0 );
317+
318+
// Print the result:
319+
for ( int i = 0; i < M; i++ ) {
320+
for ( int j = 0; j < N; j++ ) {
321+
printf( "B[ %i,%i ] = %lf\n", i, j, B[ (i*N)+j ] );
322+
}
323+
}
324+
}
325+
```
326+
327+
</section>
328+
329+
<!-- /.examples -->
330+
331+
</section>
332+
333+
<!-- /.c -->
334+
335+
<section class="references">
336+
337+
</section>
338+
339+
<!-- /.references -->
340+
341+
<section class="related">
342+
343+
</section>
344+
345+
<!-- /.related -->
346+
347+
<section class="links">
348+
349+
[mdn-typed-array]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray
350+
351+
</section>
352+
353+
<!-- /.links -->

0 commit comments

Comments
 (0)