Direct Short-and-Fat QR Currently, this is a quick hack for non-tall-and-skinny matrices which are one chunk tall and (unless they are one chunk wide) have chunks that are wider than they are tall Q [R_1 R_2 ...] = [A_1 A_2 ...] it computes the factorization Q R_1 = A_1, then
(data, name=None)
| 512 | |
| 513 | |
| 514 | def sfqr(data, name=None): |
| 515 | """Direct Short-and-Fat QR |
| 516 | |
| 517 | Currently, this is a quick hack for non-tall-and-skinny matrices which |
| 518 | are one chunk tall and (unless they are one chunk wide) have chunks |
| 519 | that are wider than they are tall |
| 520 | |
| 521 | Q [R_1 R_2 ...] = [A_1 A_2 ...] |
| 522 | |
| 523 | it computes the factorization Q R_1 = A_1, then computes the other |
| 524 | R_k's in parallel. |
| 525 | |
| 526 | Parameters |
| 527 | ---------- |
| 528 | data: Array |
| 529 | |
| 530 | See Also |
| 531 | -------- |
| 532 | dask.array.linalg.qr |
| 533 | Main user API that uses this function |
| 534 | dask.array.linalg.tsqr |
| 535 | Variant for tall-and-skinny case |
| 536 | """ |
| 537 | nr, nc = len(data.chunks[0]), len(data.chunks[1]) |
| 538 | cr, cc = data.chunks[0][0], data.chunks[1][0] |
| 539 | |
| 540 | if not ( |
| 541 | (data.ndim == 2) |
| 542 | and (nr == 1) # Is a matrix |
| 543 | and ( # Has exactly one block row |
| 544 | (cr <= cc) |
| 545 | or (nc == 1) # Chunking dimension on rows is at least that on cols or... |
| 546 | ) |
| 547 | ): # ... only one block col |
| 548 | raise ValueError( |
| 549 | "Input must have the following properties:\n" |
| 550 | " 1. Have two dimensions\n" |
| 551 | " 2. Have only one row of blocks\n" |
| 552 | " 3. Either one column of blocks or (first) chunk size on cols\n" |
| 553 | " is at most that on rows (e.g.: for a 5x20 matrix,\n" |
| 554 | " chunks=((5), (8,4,8)) is fine, but chunks=((5), (4,8,8)) is not;\n" |
| 555 | " still, prefer something simple like chunks=(5,10) or chunks=5)\n\n" |
| 556 | "Note: This function (sfqr) supports QR decomposition in the case\n" |
| 557 | "of short-and-fat matrices (single row chunk/block; see qr)" |
| 558 | ) |
| 559 | |
| 560 | prefix = name or "sfqr-" + tokenize(data) |
| 561 | prefix += "_" |
| 562 | |
| 563 | m, n = data.shape |
| 564 | |
| 565 | qq, rr = np.linalg.qr(np.ones(shape=(1, 1), dtype=data.dtype)) |
| 566 | |
| 567 | layers = data.__dask_graph__().layers.copy() |
| 568 | dependencies = data.__dask_graph__().dependencies.copy() |
| 569 | |
| 570 | # data = A = [A_1 A_rest] |
| 571 | name_A_1 = f"{prefix}A_1" |
searching dependent graphs…