numo-linalg-alt 0.2.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +10 -1
  3. data/README.md +3 -1
  4. data/ext/numo/linalg/blas/dot.c +59 -59
  5. data/ext/numo/linalg/blas/dot_sub.c +58 -58
  6. data/ext/numo/linalg/blas/gemm.c +157 -148
  7. data/ext/numo/linalg/blas/gemv.c +131 -127
  8. data/ext/numo/linalg/blas/nrm2.c +50 -50
  9. data/ext/numo/linalg/lapack/gees.c +276 -0
  10. data/ext/numo/linalg/lapack/gees.h +15 -0
  11. data/ext/numo/linalg/lapack/geev.c +127 -110
  12. data/ext/numo/linalg/lapack/gelsd.c +81 -70
  13. data/ext/numo/linalg/lapack/geqrf.c +52 -51
  14. data/ext/numo/linalg/lapack/gerqf.c +70 -0
  15. data/ext/numo/linalg/lapack/gerqf.h +15 -0
  16. data/ext/numo/linalg/lapack/gesdd.c +96 -86
  17. data/ext/numo/linalg/lapack/gesv.c +80 -78
  18. data/ext/numo/linalg/lapack/gesvd.c +140 -129
  19. data/ext/numo/linalg/lapack/getrf.c +51 -50
  20. data/ext/numo/linalg/lapack/getri.c +64 -63
  21. data/ext/numo/linalg/lapack/getrs.c +92 -88
  22. data/ext/numo/linalg/lapack/gges.c +214 -0
  23. data/ext/numo/linalg/lapack/gges.h +15 -0
  24. data/ext/numo/linalg/lapack/heev.c +54 -52
  25. data/ext/numo/linalg/lapack/heevd.c +54 -52
  26. data/ext/numo/linalg/lapack/heevr.c +109 -98
  27. data/ext/numo/linalg/lapack/hegv.c +77 -74
  28. data/ext/numo/linalg/lapack/hegvd.c +77 -74
  29. data/ext/numo/linalg/lapack/hegvx.c +132 -120
  30. data/ext/numo/linalg/lapack/hetrf.c +54 -50
  31. data/ext/numo/linalg/lapack/lange.c +45 -44
  32. data/ext/numo/linalg/lapack/orgqr.c +63 -62
  33. data/ext/numo/linalg/lapack/orgrq.c +78 -0
  34. data/ext/numo/linalg/lapack/orgrq.h +15 -0
  35. data/ext/numo/linalg/lapack/potrf.c +49 -48
  36. data/ext/numo/linalg/lapack/potri.c +49 -48
  37. data/ext/numo/linalg/lapack/potrs.c +74 -72
  38. data/ext/numo/linalg/lapack/syev.c +54 -52
  39. data/ext/numo/linalg/lapack/syevd.c +54 -52
  40. data/ext/numo/linalg/lapack/syevr.c +107 -98
  41. data/ext/numo/linalg/lapack/sygv.c +77 -73
  42. data/ext/numo/linalg/lapack/sygvd.c +77 -73
  43. data/ext/numo/linalg/lapack/sygvx.c +132 -120
  44. data/ext/numo/linalg/lapack/sytrf.c +54 -50
  45. data/ext/numo/linalg/lapack/trtrs.c +79 -75
  46. data/ext/numo/linalg/lapack/ungqr.c +63 -62
  47. data/ext/numo/linalg/lapack/ungrq.c +78 -0
  48. data/ext/numo/linalg/lapack/ungrq.h +15 -0
  49. data/ext/numo/linalg/linalg.c +21 -10
  50. data/ext/numo/linalg/linalg.h +5 -0
  51. data/ext/numo/linalg/util.c +8 -0
  52. data/ext/numo/linalg/util.h +1 -0
  53. data/lib/numo/linalg/version.rb +1 -1
  54. data/lib/numo/linalg.rb +322 -0
  55. metadata +14 -4
data/lib/numo/linalg.rb CHANGED
@@ -444,6 +444,54 @@ module Numo
444
444
  u.dot(vh[0...rank, true]).conj.transpose
445
445
  end
446
446
 
447
+ # Computes the polar decomposition of a matrix.
448
+ #
449
+ # https://en.wikipedia.org/wiki/Polar_decomposition
450
+ #
451
+ # @example
452
+ # require 'numo/linalg'
453
+ #
454
+ # a = Numo::DFloat[[0.5, 1, 2], [1.5, 3, 4]]
455
+ # u, p = Numo::Linalg.polar(a)
456
+ # pp u.dot(p)
457
+ # # =>
458
+ # # Numo::DFloat#shape=[2,3]
459
+ # # [[0.5, 1, 2],
460
+ # # [1.5, 3, 4]]
461
+ # pp u.dot(u.transpose)
462
+ # # =>
463
+ # # Numo::DFloat#shape=[2,2]
464
+ # # [[1, -1.68043e-16],
465
+ # # [-1.68043e-16, 1]]
466
+ #
467
+ # u, p = Numo::Linalg.polar(a, side: 'left')
468
+ # pp p.dot(u)
469
+ # # =>
470
+ # # Numo::DFloat#shape=[2,3]
471
+ # # [[0.5, 1, 2],
472
+ # # [1.5, 3, 4]]
473
+ #
474
+ # @param a [Numo::NArray] The m-by-n matrix to be decomposed.
475
+ # @param side [String] The side of polar decomposition ('right' or 'left').
476
+ # @return [Array<Numo::NArray>] The unitary matrix `U` and the positive-semidefinite Hermitian matrix `P`
477
+ # such that `A = U * P` if side='right', or `A = P * U` if side='left'.
478
+ def polar(a, side: 'right')
479
+ raise Numo::NArray::ShapeError, 'input array a must be 2-dimensional' if a.ndim != 2
480
+ raise ArugumentError, "invalid side: #{side}" unless %w[left right].include?(side)
481
+
482
+ bchr = blas_char(a)
483
+ raise ArgumentError, "invalid array type: #{a.class}" if bchr == 'n'
484
+
485
+ s, w, vh = svd(a, driver: 'svd', job: 'S')
486
+ u = w.dot(vh)
487
+ p_mat = if side == 'right'
488
+ vh.transpose.conj.dot(s.diag).dot(vh)
489
+ else
490
+ w.dot(s.diag).dot(w.transpose.conj)
491
+ end
492
+ [u, p_mat]
493
+ end
494
+
447
495
  # Computes the QR decomposition of a matrix.
448
496
  #
449
497
  # @example
@@ -512,6 +560,186 @@ module Numo
512
560
  [q, r]
513
561
  end
514
562
 
563
+ # Computes the RQ decomposition of a matrix.
564
+ #
565
+ # @example
566
+ # require 'numo/linalg'
567
+ #
568
+ # a = Numo::DFloat.new(2, 3).rand
569
+ # r, q = Numo::Linalg.rq(a)
570
+ # pp r
571
+ # # =>
572
+ # # Numo::DFloat#shape=[2,3]
573
+ # # [[0, -0.381748, -0.79309],
574
+ # # [0, 0, -0.41502]]
575
+ # pp q
576
+ # # =>
577
+ # # Numo::DFloat#shape=[3,3]
578
+ # # [[0.227957, 0.874475, -0.428169],
579
+ # # [0.844617, -0.396377, -0.359872],
580
+ # # [-0.484416, -0.279603, -0.828953]]
581
+ # puts (a - r.dot(q)).abs.max
582
+ # # => 5.551115123125783e-17
583
+ #
584
+ # r, q = Numo::Linalg.rq(a, mode: 'economic')
585
+ # pp r
586
+ # # =>
587
+ # # Numo::DFloat#shape=[2,2]
588
+ # # [[-0.381748, -0.79309],
589
+ # # [0, -0.41502]]
590
+ # pp q
591
+ # # =>
592
+ # # Numo::DFloat#shape=[2,3]
593
+ # # [[0.844617, -0.396377, -0.359872],
594
+ # # [-0.484416, -0.279603, -0.828953]]
595
+ # puts (a - r.dot(q)).abs.max
596
+ # # => 5.551115123125783e-17
597
+ #
598
+ # @param a [Numo::NArray] The m-by-n matrix to be decomposed.
599
+ # @param mode [String] The mode of decomposition.
600
+ # - "full" -- returns both R [m, n] and Q [n, n],
601
+ # - "r" -- returns only R,
602
+ # - "economic" -- returns both R [m, k] and Q [k, n], where k = min(m, n).
603
+ # @return [Array<Numo::NArray>/Numo::NArray]
604
+ # if mode='full' or 'economic', returns [R, Q].
605
+ # if mode='r', returns R.
606
+ def rq(a, mode: 'full') # rubocop:disable Metrics/AbcSize
607
+ raise Numo::NArray::ShapeError, 'input array a must be 2-dimensional' if a.ndim != 2
608
+ raise ArgumentError, "invalid mode: #{mode}" unless %w[full r economic].include?(mode)
609
+
610
+ bchr = blas_char(a)
611
+ raise ArgumentError, "invalid array type: #{a.class}" if bchr == 'n'
612
+
613
+ fnc = :"#{bchr}gerqf"
614
+ rq, tau, info = Numo::Linalg::Lapack.send(fnc, a.dup)
615
+ raise "the #{-info}-th argument of #{fnc} had illegal value" if info.negative?
616
+
617
+ m, n = rq.shape
618
+ r = rq.triu(n - m).dup
619
+ r = r[true, (n - m)...n].dup if mode == 'economic' && n > m
620
+
621
+ return r if mode == 'r'
622
+
623
+ fnc = %w[d s].include?(bchr) ? :"#{bchr}orgrq" : :"#{bchr}ungrq"
624
+ tmp = if n < m
625
+ rq[(m - n)...m, 0...n].dup
626
+ elsif mode == 'economic'
627
+ rq.dup
628
+ else
629
+ rq.class.zeros(n, n).tap { |mat| mat[(n - m)...n, true] = rq }
630
+ end
631
+
632
+ q, info = Numo::Linalg::Lapack.send(fnc, tmp, tau)
633
+ raise "the #{-info}-th argument of #{fnc} had illegal value" if info.negative?
634
+
635
+ [r, q]
636
+ end
637
+
638
+ # Computes the QZ decomposition (generalized Schur decomposition) of a pair of square matrices.
639
+ #
640
+ # The QZ decomposition is given by `A = Q * AA * Z^H` and `B = Q * BB * Z^H`,
641
+ # where `A` and `B` are the input matrices, `Q` and `Z` are unitary matrices,
642
+ # and `AA` and `BB` are upper triangular matrices (or quasi-upper triangular matrices in real case).
643
+ #
644
+ # @example
645
+ # require 'numo/linalg'
646
+ #
647
+ # a = Numo::DFloat.new(5, 5).rand
648
+ # b = Numo::DFloat.new(5, 5).rand
649
+ #
650
+ # aa, bb, q, z = Numo::Linalg.qz(a, b)
651
+ #
652
+ # pp (a - q.dot(aa).dot(z.transpose)).abs.max
653
+ # # => 1.7763568394002505e-15
654
+ # pp (b - q.dot(bb).dot(z.transpose)).abs.max
655
+ # # => 1.1102230246251565e-15
656
+ #
657
+ # @param a [Numo::NArray] The n-by-n square matrix.
658
+ # @param b [Numo::NArray] The n-by-n square matrix.
659
+ # @return [Array<Numo::NArray, Numo::NArray, Numo::NArray, Numo::NArray>]
660
+ # The matrices `AA`, `BB`, `Q`, and `Z` such that `A = Q * AA * Z^H` and `B = Q * BB * Z^H`.
661
+ def qz(a, b) # rubocop:disable Metrics/AbcSize
662
+ raise Numo::NArray::ShapeError, 'input array a must be 2-dimensional' if a.ndim != 2
663
+ raise Numo::NArray::ShapeError, 'input array b must be 2-dimensional' if b.ndim != 2
664
+ raise Numo::NArray::ShapeError, 'input array a must be square' if a.shape[0] != a.shape[1]
665
+ raise Numo::NArray::ShapeError, 'input array b must be square' if b.shape[0] != b.shape[1]
666
+ raise Numo::NArray::ShapeError, "incompatible dimensions: a.shape = #{a.shape} != b.shape = #{b.shape}" if a.shape != b.shape
667
+
668
+ bchr = blas_char(a, b)
669
+ raise ArgumentError, "invalid array type: #{a.class}, #{b.class}" if bchr == 'n'
670
+
671
+ fnc = :"#{bchr}gges"
672
+ if %w[d s].include?(bchr)
673
+ aa, bb, _ar, _ai, _beta, q, z, _sdim, info = Numo::Linalg::Lapack.send(fnc, a.dup, b.dup)
674
+ else
675
+ aa, bb, _alpha, _beta, q, z, _sdim, info = Numo::Linalg::Lapack.send(fnc, a.dup, b.dup)
676
+ end
677
+
678
+ raise "the #{-info}-th argument of #{fnc} had illegal value" if info.negative?
679
+ raise 'the QZ algorithm failed.' if info.positive?
680
+
681
+ [aa, bb, q, z]
682
+ end
683
+
684
+ # Computes the Schur decomposition of a square matrix.
685
+ # The Schur decomposition is given by `A = Z * T * Z^H`,
686
+ # where `A` is the input matrix, `Z` is a unitary matrix,
687
+ # and `T` is an upper triangular matrix (or quasi-upper triangular matrix in real case).
688
+ #
689
+ # @example
690
+ # require 'numo/linalg'
691
+ #
692
+ # a = Numo::DFloat[[0, 2, 3], [4, 5, 6], [7, 8, 9]]
693
+ # t, z, sdim = Numo::Linalg.schur(a)
694
+ # pp t
695
+ # # =>
696
+ # # Numo::DFloat#shape=[3,3]
697
+ # # [[16.0104, 4.81155, 0.920982],
698
+ # # [0, -1.91242, 0.0274406],
699
+ # # [0, 0, -0.0979794]]
700
+ # pp z
701
+ # # =>
702
+ # # Numo::DFloat#shape=[3,3]
703
+ # # [[-0.219668, -0.94667, 0.235716],
704
+ # # [-0.527141, -0.0881306, -0.845195],
705
+ # # [-0.820895, 0.309918, 0.479669]]
706
+ # pp sdim
707
+ # # => 0
708
+ # pp (a - z.dot(t).dot(z.transpose)).abs.max
709
+ # # => 1.0658141036401503e-14
710
+ #
711
+ # @param a [Numo::NArray] The n-by-n square matrix.
712
+ # @param sort [String/Nil] The option for sorting eigenvalues ('lhp', 'rhp', 'iuc', 'ouc', or nil).
713
+ # - 'lhp': eigenvalue.real < 0
714
+ # - 'rhp': eigenvalue.real >= 0
715
+ # - 'iuc': eigenvalue.abs <= 1
716
+ # - 'ouc': eigenvalue.abs > 1
717
+ # @return [Array<Numo::NArray, Numo::NArray, Integer>] The Schur form `T`, the unitary matrix `Z`,
718
+ # and the number of eigenvalues for which the sorting condition is true.
719
+ def schur(a, sort: nil)
720
+ raise Numo::NArray::ShapeError, 'input array a must be 2-dimensional' if a.ndim != 2
721
+ raise Numo::NArray::ShapeError, 'input array a must be square' if a.shape[0] != a.shape[1]
722
+ raise ArgumentError, "invalid sort: #{sort}" unless sort.nil? || %w[lhp rhp iuc ouc].include?(sort)
723
+
724
+ bchr = blas_char(a)
725
+ raise ArgumentError, "invalid array type: #{a.class}" if bchr == 'n'
726
+
727
+ fnc = :"#{bchr}gees"
728
+ if %w[d s].include?(bchr)
729
+ b, _wr, _wi, v, sdim, info = Numo::Linalg::Lapack.send(fnc, a.dup, jobvs: 'V', sort: sort)
730
+ else
731
+ b, _w, v, sdim, info = Numo::Linalg::Lapack.send(fnc, a.dup, jobvs: 'V', sort: sort)
732
+ end
733
+
734
+ n = a.shape[0]
735
+ raise "the #{-info}-th argument of #{fnc} had illegal value" if info.negative?
736
+ raise 'the QR algorithm failed to compute all the eigenvalues.' if info.positive? && info <= n
737
+ raise 'the eigenvalues could not be reordered.' if info == n + 1
738
+ raise 'after reordering, roundoff changed values of some complex eigenvalues.' if info == n + 2
739
+
740
+ [b, v, sdim]
741
+ end
742
+
515
743
  # Solves linear equation `A * x = b` or `A * X = B` for `x` from square matrix `A`.
516
744
  #
517
745
  # @example
@@ -921,6 +1149,46 @@ module Numo
921
1149
  c
922
1150
  end
923
1151
 
1152
+ # Computes the orthogonal Procrustes problem.
1153
+ #
1154
+ # https://en.wikipedia.org/wiki/Orthogonal_Procrustes_problem
1155
+ #
1156
+ # @example
1157
+ # require 'numo/linalg'
1158
+ #
1159
+ # a = Numo::DFloat[[2, 0, 1], [-2, 0, 0]]
1160
+ # b = a.fliplr
1161
+ # r, scale = Numo::Linalg.orthogonal_procrustes(a, b)
1162
+ #
1163
+ # pp b
1164
+ # # =>
1165
+ # # Numo::DFloat(view)#shape=[2,3]
1166
+ # # [[1, 0, 2],
1167
+ # # [0, 0, -2]]
1168
+ # pp a.dot(r)
1169
+ # # =>
1170
+ # # Numo::DFloat#shape=[2,3]
1171
+ # # [[1, 0, 2],
1172
+ # # [1.58669e-16, 0, -2]]
1173
+ # pp (b - a.dot(r)).abs.max
1174
+ # # =>
1175
+ # # 2.220446049250313e-16
1176
+ #
1177
+ # @param a [Numo::NArray] The first input matrix.
1178
+ # @param b [Numo::NArray] The second input matrix.
1179
+ # @return [Array<Numo::NArray, Float>] The orthogonal matrix `R` and the scale factor `scale`.
1180
+ def orthogonal_procrustes(a, b)
1181
+ raise Numo::NArray::ShapeError, 'input array a must be 2-dimensional' if a.ndim != 2
1182
+ raise Numo::NArray::ShapeError, 'input array b must be 2-dimensional' if b.ndim != 2
1183
+ raise Numo::NArray::ShapeError, "incompatible dimensions: a.shape = #{a.shape} != b.shape = #{b.shape}" if a.shape != b.shape
1184
+
1185
+ m = b.transpose.dot(a.conj).transpose
1186
+ s, u, vt = svd(m, driver: 'svd', job: 'S')
1187
+ r = u.dot(vt)
1188
+ scale = s.sum
1189
+ [r, scale]
1190
+ end
1191
+
924
1192
  # Computes the eigenvalues and right and/or left eigenvectors of a general square matrix.
925
1193
  #
926
1194
  # @example
@@ -1195,6 +1463,60 @@ module Numo
1195
1463
  a_expm
1196
1464
  end
1197
1465
 
1466
+ # Computes the matrix sine using the matrix exponential.
1467
+ #
1468
+ # @param a [Numo::NArray] The n-by-n square matrix.
1469
+ # @return [Numo::NArray] The matrix sine of `a`.
1470
+ def sinm(a)
1471
+ raise Numo::NArray::ShapeError, 'input array a must be 2-dimensional' if a.ndim != 2
1472
+ raise Numo::NArray::ShapeError, 'input array a must be square' if a.shape[0] != a.shape[1]
1473
+
1474
+ bchr = blas_char(a)
1475
+ raise ArgumentError, "invalid array type: #{a.class}" if bchr == 'n'
1476
+
1477
+ b = a * 1.0i
1478
+ if %w[z c].include?(bchr)
1479
+ -0.5i * (expm(b) - expm(-b))
1480
+ else
1481
+ expm(b).imag
1482
+ end
1483
+ end
1484
+
1485
+ # Computes the matrix cosine using the matrix exponential.
1486
+ #
1487
+ # @param a [Numo::NArray] The n-by-n square matrix.
1488
+ # @return [Numo::NArray] The matrix cosine of `a`.
1489
+ def cosm(a)
1490
+ raise Numo::NArray::ShapeError, 'input array a must be 2-dimensional' if a.ndim != 2
1491
+ raise Numo::NArray::ShapeError, 'input array a must be square' if a.shape[0] != a.shape[1]
1492
+
1493
+ bchr = blas_char(a)
1494
+ raise ArgumentError, "invalid array type: #{a.class}" if bchr == 'n'
1495
+
1496
+ b = a * 1.0i
1497
+ if %w[z c].include?(bchr)
1498
+ 0.5 * (expm(b) + expm(-b))
1499
+ else
1500
+ expm(b).real
1501
+ end
1502
+ end
1503
+
1504
+ # Computes the matrix tangent.
1505
+ #
1506
+ # @param a [Numo::NArray] The n-by-n square matrix.
1507
+ # @return [Numo::NArray] The matrix tangent of `a`.
1508
+ def tanm(a)
1509
+ raise Numo::NArray::ShapeError, 'input array a must be 2-dimensional' if a.ndim != 2
1510
+ raise Numo::NArray::ShapeError, 'input array a must be square' if a.shape[0] != a.shape[1]
1511
+
1512
+ bchr = blas_char(a)
1513
+ raise ArgumentError, "invalid array type: #{a.class}" if bchr == 'n'
1514
+
1515
+ a_sin = sinm(a)
1516
+ a_cos = cosm(a)
1517
+ a_sin.dot(Numo::Linalg.inv(a_cos))
1518
+ end
1519
+
1198
1520
  # Computes the inverse of a matrix using its LU decomposition.
1199
1521
  #
1200
1522
  # @param lu [Numo::NArray] The LU decomposition of the n-by-n matrix `A`.
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: numo-linalg-alt
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - yoshoku
@@ -13,14 +13,14 @@ dependencies:
13
13
  name: numo-narray-alt
14
14
  requirement: !ruby/object:Gem::Requirement
15
15
  requirements:
16
- - - ">="
16
+ - - "~>"
17
17
  - !ruby/object:Gem::Version
18
18
  version: 0.9.3
19
19
  type: :runtime
20
20
  prerelease: false
21
21
  version_requirements: !ruby/object:Gem::Requirement
22
22
  requirements:
23
- - - ">="
23
+ - - "~>"
24
24
  - !ruby/object:Gem::Version
25
25
  version: 0.9.3
26
26
  description: |
@@ -50,12 +50,16 @@ files:
50
50
  - ext/numo/linalg/converter.c
51
51
  - ext/numo/linalg/converter.h
52
52
  - ext/numo/linalg/extconf.rb
53
+ - ext/numo/linalg/lapack/gees.c
54
+ - ext/numo/linalg/lapack/gees.h
53
55
  - ext/numo/linalg/lapack/geev.c
54
56
  - ext/numo/linalg/lapack/geev.h
55
57
  - ext/numo/linalg/lapack/gelsd.c
56
58
  - ext/numo/linalg/lapack/gelsd.h
57
59
  - ext/numo/linalg/lapack/geqrf.c
58
60
  - ext/numo/linalg/lapack/geqrf.h
61
+ - ext/numo/linalg/lapack/gerqf.c
62
+ - ext/numo/linalg/lapack/gerqf.h
59
63
  - ext/numo/linalg/lapack/gesdd.c
60
64
  - ext/numo/linalg/lapack/gesdd.h
61
65
  - ext/numo/linalg/lapack/gesv.c
@@ -68,6 +72,8 @@ files:
68
72
  - ext/numo/linalg/lapack/getri.h
69
73
  - ext/numo/linalg/lapack/getrs.c
70
74
  - ext/numo/linalg/lapack/getrs.h
75
+ - ext/numo/linalg/lapack/gges.c
76
+ - ext/numo/linalg/lapack/gges.h
71
77
  - ext/numo/linalg/lapack/heev.c
72
78
  - ext/numo/linalg/lapack/heev.h
73
79
  - ext/numo/linalg/lapack/heevd.c
@@ -86,6 +92,8 @@ files:
86
92
  - ext/numo/linalg/lapack/lange.h
87
93
  - ext/numo/linalg/lapack/orgqr.c
88
94
  - ext/numo/linalg/lapack/orgqr.h
95
+ - ext/numo/linalg/lapack/orgrq.c
96
+ - ext/numo/linalg/lapack/orgrq.h
89
97
  - ext/numo/linalg/lapack/potrf.c
90
98
  - ext/numo/linalg/lapack/potrf.h
91
99
  - ext/numo/linalg/lapack/potri.c
@@ -110,6 +118,8 @@ files:
110
118
  - ext/numo/linalg/lapack/trtrs.h
111
119
  - ext/numo/linalg/lapack/ungqr.c
112
120
  - ext/numo/linalg/lapack/ungqr.h
121
+ - ext/numo/linalg/lapack/ungrq.c
122
+ - ext/numo/linalg/lapack/ungrq.h
113
123
  - ext/numo/linalg/linalg.c
114
124
  - ext/numo/linalg/linalg.h
115
125
  - ext/numo/linalg/util.c
@@ -124,7 +134,7 @@ metadata:
124
134
  homepage_uri: https://github.com/yoshoku/numo-linalg-alt
125
135
  source_code_uri: https://github.com/yoshoku/numo-linalg-alt
126
136
  changelog_uri: https://github.com/yoshoku/numo-linalg-alt/blob/main/CHANGELOG.md
127
- documentation_uri: https://gemdocs.org/gems/numo-linalg-alt/0.2.0/
137
+ documentation_uri: https://gemdocs.org/gems/numo-linalg-alt/0.4.0/
128
138
  rubygems_mfa_required: 'true'
129
139
  rdoc_options: []
130
140
  require_paths: