Skip to content

Commit 126ff36

Browse files
aayush0325kgrytestdlib-bot
authored
feat: add lapack/base/dlarf1f
PR-URL: #7540 Co-authored-by: Athan Reines <[email protected]> Reviewed-by: Athan Reines <[email protected]> Co-authored-by: stdlib-bot <[email protected]>
1 parent 3174a3b commit 126ff36

File tree

57 files changed

+7178
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+7178
-0
lines changed
Lines changed: 337 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,337 @@
1+
<!--
2+
3+
@license Apache-2.0
4+
5+
Copyright (c) 2025 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+
# dlarf1f
22+
23+
> Apply a real elementary reflector `H = I - tau * v * v^T` to a real M by N matrix `C`.
24+
25+
<section class="intro">
26+
27+
A **Householder transformation** (or an **elementary reflector**) is a linear transformation that describes a reflection about a plane or a hyperplane containing the origin.
28+
29+
</section>
30+
31+
<!-- /.intro -->
32+
33+
<section class="usage">
34+
35+
## Usage
36+
37+
```javascript
38+
var dlarf1f = require( '@stdlib/lapack/base/dlarf1f' );
39+
```
40+
41+
#### dlarf1f( order, side, M, N, V, strideV, tau, C, LDC, work )
42+
43+
Applies a real elementary reflector `H = I - tau * v * v^T` to a real M by N matrix `C`.
44+
45+
<!-- eslint-disable max-len -->
46+
47+
```javascript
48+
var Float64Array = require( '@stdlib/array/float64' );
49+
50+
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 ] );
51+
var V = new Float64Array( [ 0.5, 0.5, 0.5, 0.5 ] );
52+
var work = new Float64Array( 3 );
53+
54+
var out = dlarf1f( 'row-major', 'left', 4, 3, V, 1, 1.0, C, 3, work );
55+
// 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 ]
56+
```
57+
58+
The function has the following parameters:
59+
60+
- **order**: storage layout.
61+
- **side**: specifies the side of multiplication with `C`.
62+
- **M**: number of rows in `C`.
63+
- **N**: number of columns in `C`.
64+
- **V**: the vector `v` as a [`Float64Array`][mdn-float64array].
65+
- **strideV**: stride length for `V`. If `strideV` is negative, the elements of `V` are accessed in reverse order.
66+
- **tau**: scalar constant.
67+
- **C**: input matrix stored in linear memory as a [`Float64Array`][mdn-float64array].
68+
- **LDC**: stride of the first dimension of `C` (a.k.a., leading dimension of the matrix `C`).
69+
- **work**: workspace [`Float64Array`][mdn-float64array].
70+
71+
When `side` is `'left'`,
72+
73+
- `work` should have `N` indexed elements.
74+
- `V` should have `1 + (M-1) * abs(strideV)` indexed elements.
75+
- `C` is overwritten by `H * C`.
76+
77+
When `side` is `'right'`,
78+
79+
- `work` should have `M` indexed elements.
80+
- `V` should have `1 + (N-1) * abs(strideV)` indexed elements.
81+
- `C` is overwritten by `C * H`.
82+
83+
The sign of the increment parameter `strideV` determines the order in which elements of `V` are accessed. For example, to access elements in reverse order,
84+
85+
<!-- eslint-disable max-len -->
86+
87+
```javascript
88+
var Float64Array = require( '@stdlib/array/float64' );
89+
90+
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 ] );
91+
var V = new Float64Array( [ 0.5, 0.4, 0.3, 0.2 ] );
92+
var work = new Float64Array( 3 );
93+
94+
var out = dlarf1f( 'row-major', 'left', 4, 3, V, -1, 1.0, C, 3, work );
95+
// returns <Float64Array>[ ~-3.80, -8.6, ~-13.4, ~0.56, 1.92, ~3.28, ~1.08, ~1.56, ~2.04, ~1.60, ~1.20, ~0.80 ]
96+
```
97+
98+
To perform strided access over `V`, provide an `abs(strideV)` value greater than one. For example, to access every other element in `V`,
99+
100+
<!-- eslint-disable max-len -->
101+
102+
```javascript
103+
var Float64Array = require( '@stdlib/array/float64' );
104+
105+
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 ] );
106+
var V = new Float64Array( [ 0.5, 999, 0.5, 999, 0.5, 999, 0.5 ] );
107+
var work = new Float64Array( 3 );
108+
109+
var out = dlarf1f( 'row-major', 'left', 4, 3, V, 2, 1.0, C, 3, work );
110+
// 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 ]
111+
```
112+
113+
Note that indexing is relative to the first index. To introduce an offset, use [`typed array`][mdn-typed-array] views.
114+
115+
<!-- eslint-disable stdlib/capitalized-comments, max-len -->
116+
117+
```javascript
118+
var Float64Array = require( '@stdlib/array/float64' );
119+
120+
// Initial arrays...
121+
var C0 = new Float64Array( [ 0.0, 1.0, 5.0, 9.0, 2.0, 6.0, 10.0, 3.0, 7.0, 11.0, 4.0, 8.0, 12.0 ] );
122+
var V0 = new Float64Array( [ 0.0, 0.5, 0.5, 0.5, 0.5 ] );
123+
var work0 = new Float64Array( [ 0.0, 0.0, 0.0, 0.0 ] );
124+
125+
// Create offset views...
126+
var C1 = new Float64Array( C0.buffer, C0.BYTES_PER_ELEMENT*1 ); // start at 2nd element
127+
var V1 = new Float64Array( V0.buffer, V0.BYTES_PER_ELEMENT*1 ); // start at 2nd element
128+
var work1 = new Float64Array( work0.buffer, work0.BYTES_PER_ELEMENT*1 ); // start at 2nd element
129+
130+
var our = dlarf1f( 'row-major', 'left', 4, 3, V1, 1, 1.0, C1, 3, work1 );
131+
// C0 => <Float64Array>[ 0.0, -4.5, -10.5, -16.5, -0.75, -1.75, -2.75, 0.25, -0.75, -1.75, 1.25, 0.25, -0.75 ]
132+
```
133+
134+
#### dlarf1f.ndarray( side, M, N, V, sv, ov, tau, C, sc1, sc2, oc, work, sw, ow )
135+
136+
Applies a real elementary reflector `H = I - tau * v * v^T` to a real M by N matrix `C` using alternative indexing semantics.
137+
138+
<!-- eslint-disable max-len -->
139+
140+
```javascript
141+
var Float64Array = require( '@stdlib/array/float64' );
142+
143+
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 ] );
144+
var V = new Float64Array( [ 0.5, 0.5, 0.5, 0.5 ] );
145+
var work = new Float64Array( 3 );
146+
147+
var out = dlarf1f.ndarray( 'left', 4, 3, V, 1, 0, 1.0, C, 3, 1, 0, work, 1, 0 );
148+
// 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 ]
149+
```
150+
151+
The function has the following additional parameters:
152+
153+
- **side**: specifies the side of multiplication with `C`.
154+
- **M**: number of rows in `C`.
155+
- **N**: number of columns in `C`.
156+
- **V**: the vector `v` as a [`Float64Array`][mdn-float64array].
157+
- **sv**: stride length for `V`.
158+
- **ov**: starting index for `V`.
159+
- **tau**: scalar constant.
160+
- **C**: input matrix as a [`Float64Array`][mdn-float64array].
161+
- **sc1**: stride of the first dimension of `C`.
162+
- **sc2**: stride of the second dimension of `C`.
163+
- **oc**: starting index for `C`.
164+
- **work**: workspace array as a [`Float64Array`][mdn-float64array].
165+
- **sw**: stride length for `work`.
166+
- **ow**: starting index for `work`.
167+
168+
When `side` is `'left'`,
169+
170+
- `work` should have `N` indexed elements.
171+
- `V` should have `1 + (M-1) * abs(sv)` indexed elements.
172+
- `C` is overwritten by `H * C`.
173+
174+
When `side` is `'right'`,
175+
176+
- `work` should have `M` indexed elements.
177+
- `V` should have `1 + (N-1) * abs(sv)` indexed elements.
178+
- `C` is overwritten by `C * H`.
179+
180+
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,
181+
182+
<!-- eslint-disable max-len -->
183+
184+
```javascript
185+
var Float64Array = require( '@stdlib/array/float64' );
186+
187+
var C = new Float64Array( [ 0.0, 0.0, 0.0, 0.0, 1.0, 5.0, 9.0, 2.0, 6.0, 10.0, 3.0, 7.0, 11.0, 4.0, 8.0, 12.0 ] );
188+
var V = new Float64Array( [ 0.0, 0.0, 0.5, 0.5, 0.5, 0.5 ] );
189+
var work = new Float64Array( [ 0.0, 0.0, 0.0, 0.0 ] );
190+
191+
var out = dlarf1f.ndarray( 'left', 4, 3, V, 1, 2, 1.0, C, 3, 1, 4, work, 1, 0 );
192+
// C => <Float64Array>[ 0.0, 0.0, 0.0, 0.0, -4.5, -10.5, -16.5, -0.75, -1.75, -2.75, 0.25, -0.75, -1.75, 1.25, 0.25, -0.75 ]
193+
```
194+
195+
</section>
196+
197+
<!-- /.usage -->
198+
199+
<section class="notes">
200+
201+
## Notes
202+
203+
- `dlarf1f()` corresponds to the [LAPACK][LAPACK] function [`dlarf1f`][lapack-dlarf1f].
204+
205+
</section>
206+
207+
<!-- /.notes -->
208+
209+
<section class="examples">
210+
211+
## Examples
212+
213+
<!-- eslint no-undef: "error" -->
214+
215+
<!-- eslint-disable max-len -->
216+
217+
```javascript
218+
var Float64Array = require( '@stdlib/array/float64' );
219+
var ndarray2array = require( '@stdlib/ndarray/base/to-array' );
220+
var shape2strides = require( '@stdlib/ndarray/base/shape2strides' );
221+
var dlarf1f = require( '@stdlib/lapack/base/dlarf1f' );
222+
223+
// Specify matrix meta data:
224+
var shape = [ 4, 3 ];
225+
var order = 'row-major';
226+
var strides = shape2strides( shape, order );
227+
228+
// Create a matrix stored in linear memory:
229+
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 ] );
230+
console.log( ndarray2array( C, shape, strides, 0, order ) );
231+
232+
// Define the vector `v` and a workspace array:
233+
var V = new Float64Array( [ 0.5, 0.5, 0.5, 0.5 ] );
234+
var work = new Float64Array( 3 );
235+
236+
// Apply the elementary reflector:
237+
dlarf1f( order, 'left', shape[ 0 ], shape[ 1 ], V, 1, 1.0, C, strides[ 0 ], work );
238+
console.log( ndarray2array( C, shape, strides, 0, order ) );
239+
```
240+
241+
</section>
242+
243+
<!-- /.examples -->
244+
245+
<!-- C interface documentation. -->
246+
247+
* * *
248+
249+
<section class="c">
250+
251+
## C APIs
252+
253+
<!-- Section to include introductory text. Make sure to keep an empty line after the intro `section` element and another before the `/section` close. -->
254+
255+
<section class="intro">
256+
257+
</section>
258+
259+
<!-- /.intro -->
260+
261+
<!-- C usage documentation. -->
262+
263+
<section class="usage">
264+
265+
### Usage
266+
267+
```c
268+
TODO
269+
```
270+
271+
#### TODO
272+
273+
TODO.
274+
275+
```c
276+
TODO
277+
```
278+
279+
TODO
280+
281+
```c
282+
TODO
283+
```
284+
285+
</section>
286+
287+
<!-- /.usage -->
288+
289+
<!-- C API usage notes. Make sure to keep an empty line after the `section` element and another before the `/section` close. -->
290+
291+
<section class="notes">
292+
293+
</section>
294+
295+
<!-- /.notes -->
296+
297+
<!-- C API usage examples. -->
298+
299+
<section class="examples">
300+
301+
### Examples
302+
303+
```c
304+
TODO
305+
```
306+
307+
</section>
308+
309+
<!-- /.examples -->
310+
311+
</section>
312+
313+
<!-- /.c -->
314+
315+
<!-- Section for related `stdlib` packages. Do not manually edit this section, as it is automatically populated. -->
316+
317+
<section class="related">
318+
319+
</section>
320+
321+
<!-- /.related -->
322+
323+
<!-- Section for all links. Make sure to keep an empty line after the `section` element and another before the `/section` close. -->
324+
325+
<section class="links">
326+
327+
[lapack]: https://www.netlib.org/lapack/explore-html/
328+
329+
[lapack-dlarf1f]: https://netlib.org/lapack/explore-html/d2/d97/group__larf_ga3b4608752c4f72758c2d297e1e7cf3f0.html#ga3b4608752c4f72758c2d297e1e7cf3f0
330+
331+
[mdn-float64array]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Float64Array
332+
333+
[mdn-typed-array]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray
334+
335+
</section>
336+
337+
<!-- /.links -->

0 commit comments

Comments
 (0)