numo-linalg-alt 0.5.0 → 0.7.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +38 -0
- data/README.md +47 -5
- data/ext/numo/linalg/blas/blas_common.h +30 -0
- data/ext/numo/linalg/blas/blas_util.c +39 -0
- data/ext/numo/linalg/blas/blas_util.h +11 -0
- data/ext/numo/linalg/{converter.h → blas/converter.h} +0 -2
- data/ext/numo/linalg/blas/dot.c +1 -1
- data/ext/numo/linalg/blas/dot.h +1 -6
- data/ext/numo/linalg/blas/dot_sub.c +1 -1
- data/ext/numo/linalg/blas/dot_sub.h +1 -6
- data/ext/numo/linalg/blas/gemm.c +21 -21
- data/ext/numo/linalg/blas/gemm.h +3 -9
- data/ext/numo/linalg/blas/gemv.c +10 -10
- data/ext/numo/linalg/blas/gemv.h +3 -9
- data/ext/numo/linalg/blas/nrm2.c +1 -1
- data/ext/numo/linalg/blas/nrm2.h +1 -6
- data/ext/numo/linalg/extconf.rb +33 -6
- data/ext/numo/linalg/lapack/gebal.h +1 -1
- data/ext/numo/linalg/lapack/gees.c +4 -4
- data/ext/numo/linalg/lapack/gees.h +1 -1
- data/ext/numo/linalg/lapack/geev.c +8 -24
- data/ext/numo/linalg/lapack/geev.h +1 -1
- data/ext/numo/linalg/lapack/gehrd.h +1 -1
- data/ext/numo/linalg/lapack/gelsd.h +1 -1
- data/ext/numo/linalg/lapack/geqrf.h +1 -1
- data/ext/numo/linalg/lapack/gerqf.h +1 -1
- data/ext/numo/linalg/lapack/gesdd.h +1 -1
- data/ext/numo/linalg/lapack/gesv.h +1 -1
- data/ext/numo/linalg/lapack/gesvd.h +1 -1
- data/ext/numo/linalg/lapack/getrf.h +1 -1
- data/ext/numo/linalg/lapack/getri.h +1 -1
- data/ext/numo/linalg/lapack/getrs.h +1 -1
- data/ext/numo/linalg/lapack/gges.c +4 -4
- data/ext/numo/linalg/lapack/gges.h +1 -1
- data/ext/numo/linalg/lapack/heev.c +1 -1
- data/ext/numo/linalg/lapack/heev.h +1 -1
- data/ext/numo/linalg/lapack/heevd.c +1 -1
- data/ext/numo/linalg/lapack/heevd.h +1 -1
- data/ext/numo/linalg/lapack/heevr.c +1 -1
- data/ext/numo/linalg/lapack/heevr.h +1 -1
- data/ext/numo/linalg/lapack/hegv.c +1 -1
- data/ext/numo/linalg/lapack/hegv.h +1 -1
- data/ext/numo/linalg/lapack/hegvd.c +1 -1
- data/ext/numo/linalg/lapack/hegvd.h +1 -1
- data/ext/numo/linalg/lapack/hegvx.c +1 -1
- data/ext/numo/linalg/lapack/hegvx.h +1 -1
- data/ext/numo/linalg/lapack/hetrf.h +1 -1
- data/ext/numo/linalg/lapack/lange.h +1 -1
- data/ext/numo/linalg/lapack/lapack_util.c +57 -0
- data/ext/numo/linalg/lapack/lapack_util.h +27 -0
- data/ext/numo/linalg/lapack/orghr.h +1 -1
- data/ext/numo/linalg/lapack/orgqr.h +1 -1
- data/ext/numo/linalg/lapack/orgrq.h +1 -1
- data/ext/numo/linalg/lapack/potrf.h +1 -1
- data/ext/numo/linalg/lapack/potri.h +1 -1
- data/ext/numo/linalg/lapack/potrs.h +1 -1
- data/ext/numo/linalg/lapack/syev.c +1 -1
- data/ext/numo/linalg/lapack/syev.h +1 -1
- data/ext/numo/linalg/lapack/syevd.c +1 -1
- data/ext/numo/linalg/lapack/syevd.h +1 -1
- data/ext/numo/linalg/lapack/syevr.c +1 -1
- data/ext/numo/linalg/lapack/syevr.h +1 -1
- data/ext/numo/linalg/lapack/sygv.c +1 -1
- data/ext/numo/linalg/lapack/sygv.h +1 -1
- data/ext/numo/linalg/lapack/sygvd.c +1 -1
- data/ext/numo/linalg/lapack/sygvd.h +1 -1
- data/ext/numo/linalg/lapack/sygvx.c +1 -1
- data/ext/numo/linalg/lapack/sygvx.h +1 -1
- data/ext/numo/linalg/lapack/sytrf.h +1 -1
- data/ext/numo/linalg/lapack/trtrs.h +1 -1
- data/ext/numo/linalg/lapack/unghr.h +1 -1
- data/ext/numo/linalg/lapack/ungqr.h +1 -1
- data/ext/numo/linalg/lapack/ungrq.h +1 -1
- data/ext/numo/linalg/linalg.c +2 -0
- data/ext/numo/linalg/linalg.h +14 -6
- data/lib/numo/linalg/version.rb +1 -1
- data/lib/numo/linalg.rb +148 -56
- metadata +10 -7
- data/ext/numo/linalg/util.c +0 -103
- data/ext/numo/linalg/util.h +0 -18
- /data/ext/numo/linalg/{converter.c → blas/converter.c} +0 -0
data/ext/numo/linalg/linalg.c
CHANGED
|
@@ -224,8 +224,10 @@ void Init_linalg(void) {
|
|
|
224
224
|
*/
|
|
225
225
|
rb_mLinalgLapack = rb_define_module_under(rb_mLinalg, "Lapack");
|
|
226
226
|
|
|
227
|
+
#ifdef HAVE_OPENBLAS_CONFIG_H
|
|
227
228
|
/* The version of OpenBLAS used in background library. */
|
|
228
229
|
rb_define_const(rb_mLinalg, "OPENBLAS_VERSION", rb_str_new_cstr(OPENBLAS_VERSION));
|
|
230
|
+
#endif
|
|
229
231
|
|
|
230
232
|
/**
|
|
231
233
|
* Returns BLAS char ([sdcz]) defined by data-type of arguments.
|
data/ext/numo/linalg/linalg.h
CHANGED
|
@@ -35,15 +35,23 @@
|
|
|
35
35
|
|
|
36
36
|
#include <ruby.h>
|
|
37
37
|
|
|
38
|
-
#include <cblas.h>
|
|
39
|
-
#include <lapacke.h>
|
|
40
|
-
#include <openblas_config.h>
|
|
41
|
-
|
|
42
38
|
#include <numo/narray.h>
|
|
43
39
|
#include <numo/template.h>
|
|
44
40
|
|
|
45
|
-
#
|
|
46
|
-
#
|
|
41
|
+
#ifndef _DEFINED_SCOMPLEX
|
|
42
|
+
#define _DEFINED_SCOMPLEX 1
|
|
43
|
+
#endif
|
|
44
|
+
#ifndef _DEFINED_DCOMPLEX
|
|
45
|
+
#define _DEFINED_DCOMPLEX 1
|
|
46
|
+
#endif
|
|
47
|
+
|
|
48
|
+
#include <cblas.h>
|
|
49
|
+
#include <lapacke.h>
|
|
50
|
+
|
|
51
|
+
#include "extconf.h"
|
|
52
|
+
#ifdef HAVE_OPENBLAS_CONFIG_H
|
|
53
|
+
#include <openblas_config.h>
|
|
54
|
+
#endif
|
|
47
55
|
|
|
48
56
|
#include "blas/dot.h"
|
|
49
57
|
#include "blas/dot_sub.h"
|
data/lib/numo/linalg/version.rb
CHANGED
data/lib/numo/linalg.rb
CHANGED
|
@@ -8,6 +8,9 @@ require_relative 'linalg/linalg'
|
|
|
8
8
|
module Numo
|
|
9
9
|
# Numo::Linalg Alternative (numo-linalg-alt) is an alternative to Numo::Linalg.
|
|
10
10
|
module Linalg # rubocop:disable Metrics/ModuleLength
|
|
11
|
+
# Exception class for errors occurred in LAPACK functions.
|
|
12
|
+
class LapackError < StandardError; end
|
|
13
|
+
|
|
11
14
|
module_function
|
|
12
15
|
|
|
13
16
|
# Computes the eigenvalues and eigenvectors of a symmetric / Hermitian matrix
|
|
@@ -340,7 +343,9 @@ module Numo
|
|
|
340
343
|
raise ArgumentError, "invalid array type: #{a.class}" if bchr == 'n'
|
|
341
344
|
|
|
342
345
|
fnc = :"#{bchr}potrs"
|
|
343
|
-
x,
|
|
346
|
+
x, info = Numo::Linalg::Lapack.send(fnc, a, b.dup, uplo: uplo)
|
|
347
|
+
raise LapackError, "the #{-info}-th argument of potrs had illegal value" if info.negative?
|
|
348
|
+
|
|
344
349
|
x
|
|
345
350
|
end
|
|
346
351
|
|
|
@@ -364,17 +369,17 @@ module Numo
|
|
|
364
369
|
|
|
365
370
|
getrf = :"#{bchr}getrf"
|
|
366
371
|
lu, piv, info = Numo::Linalg::Lapack.send(getrf, a.dup)
|
|
372
|
+
raise LapackError, "the #{-info}-th argument of getrf had illegal value" if info.negative?
|
|
367
373
|
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
end
|
|
374
|
+
# info > 0 means the factor U has a zero diagonal element and is singular.
|
|
375
|
+
# In this case, the determinant is zero. The method should simply return 0.0.
|
|
376
|
+
# Therefore, the error is not raised here.
|
|
377
|
+
# raise 'the factor U is singular, ...' if info.positive?
|
|
378
|
+
|
|
379
|
+
det_l = 1
|
|
380
|
+
det_u = lu.diagonal.prod
|
|
381
|
+
det_p = piv.map_with_index { |v, i| v == i + 1 ? 1 : -1 }.prod
|
|
382
|
+
det_l * det_u * det_p
|
|
378
383
|
end
|
|
379
384
|
|
|
380
385
|
# Computes the inverse matrix of a square matrix.
|
|
@@ -407,13 +412,13 @@ module Numo
|
|
|
407
412
|
getri = :"#{bchr}getri"
|
|
408
413
|
|
|
409
414
|
lu, piv, info = Numo::Linalg::Lapack.send(getrf, a.dup)
|
|
410
|
-
if info.
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
415
|
+
raise LapackError, "the #{-info}-th argument of getrf had illegal value" if info.negative?
|
|
416
|
+
|
|
417
|
+
a_inv, info = Numo::Linalg::Lapack.send(getri, lu, piv)
|
|
418
|
+
raise LapackError, "the #{-info}-th argument of getrf had illegal value" if info.negative?
|
|
419
|
+
raise LapackError, 'The matrix is singular, and the inverse matrix could not be computed.' if info.positive?
|
|
420
|
+
|
|
421
|
+
a_inv
|
|
417
422
|
end
|
|
418
423
|
|
|
419
424
|
# Computes the (Moore-Penrose) pseudo-inverse of a matrix using singular value decomposition.
|
|
@@ -441,7 +446,7 @@ module Numo
|
|
|
441
446
|
rank = s.gt(rcond * s[0]).count
|
|
442
447
|
|
|
443
448
|
u = u[true, 0...rank] / s[0...rank]
|
|
444
|
-
u.dot(vh[0...rank, true]).conj.transpose
|
|
449
|
+
u.dot(vh[0...rank, true]).conj.transpose.dup
|
|
445
450
|
end
|
|
446
451
|
|
|
447
452
|
# Computes the polar decomposition of a matrix.
|
|
@@ -612,7 +617,7 @@ module Numo
|
|
|
612
617
|
|
|
613
618
|
fnc = :"#{bchr}gerqf"
|
|
614
619
|
rq, tau, info = Numo::Linalg::Lapack.send(fnc, a.dup)
|
|
615
|
-
raise "the #{-info}-th argument of #{fnc} had illegal value" if info.negative?
|
|
620
|
+
raise LapackError, "the #{-info}-th argument of #{fnc} had illegal value" if info.negative?
|
|
616
621
|
|
|
617
622
|
m, n = rq.shape
|
|
618
623
|
r = rq.triu(n - m).dup
|
|
@@ -630,7 +635,7 @@ module Numo
|
|
|
630
635
|
end
|
|
631
636
|
|
|
632
637
|
q, info = Numo::Linalg::Lapack.send(fnc, tmp, tau)
|
|
633
|
-
raise "the #{-info}-th argument of #{fnc} had illegal value" if info.negative?
|
|
638
|
+
raise LapackError, "the #{-info}-th argument of #{fnc} had illegal value" if info.negative?
|
|
634
639
|
|
|
635
640
|
[r, q]
|
|
636
641
|
end
|
|
@@ -675,8 +680,21 @@ module Numo
|
|
|
675
680
|
aa, bb, _alpha, _beta, q, z, _sdim, info = Numo::Linalg::Lapack.send(fnc, a.dup, b.dup)
|
|
676
681
|
end
|
|
677
682
|
|
|
678
|
-
|
|
679
|
-
raise
|
|
683
|
+
n = a.shape[0]
|
|
684
|
+
raise LapackError, "the #{-info}-th argument of #{fnc} had illegal value" if info.negative?
|
|
685
|
+
raise LapackError, 'something other than QZ iteration failed.' if info == n + 1
|
|
686
|
+
raise LapackError, "reordering failed in #{bchr}tgsen" if info == n + 3
|
|
687
|
+
|
|
688
|
+
if info == n + 2
|
|
689
|
+
raise LapackError, 'after reordering, roundoff changed values of some eigenvalues ' \
|
|
690
|
+
'so that leading eigenvalues in the Generalized Schur form no ' \
|
|
691
|
+
'longer satisfy the sorting condition.'
|
|
692
|
+
end
|
|
693
|
+
|
|
694
|
+
if info.positive? && info <= n
|
|
695
|
+
warn('the QZ iteration failed. (a, b) are not in Schur form, ' \
|
|
696
|
+
"but alpha[i] and beta[i] for i = #{info},...,n are correct.")
|
|
697
|
+
end
|
|
680
698
|
|
|
681
699
|
[aa, bb, q, z]
|
|
682
700
|
end
|
|
@@ -732,10 +750,15 @@ module Numo
|
|
|
732
750
|
end
|
|
733
751
|
|
|
734
752
|
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
|
-
|
|
753
|
+
raise LapackError, "the #{-info}-th argument of #{fnc} had illegal value" if info.negative?
|
|
754
|
+
raise LapackError, 'the QR algorithm failed to compute all the eigenvalues.' if info.positive? && info <= n
|
|
755
|
+
raise LapackError, 'the eigenvalues could not be reordered.' if info == n + 1
|
|
756
|
+
|
|
757
|
+
if info == n + 2
|
|
758
|
+
raise LapackError, 'after reordering, roundoff changed values of some eigenvalues ' \
|
|
759
|
+
'so that leading eigenvalues in the Schur form no longer satisfy ' \
|
|
760
|
+
'the sorting condition.'
|
|
761
|
+
end
|
|
739
762
|
|
|
740
763
|
[b, v, sdim]
|
|
741
764
|
end
|
|
@@ -779,12 +802,12 @@ module Numo
|
|
|
779
802
|
func = :"#{bchr}gebal"
|
|
780
803
|
b, ilo, ihi, _, info = Numo::Linalg::Lapack.send(func, a.dup)
|
|
781
804
|
|
|
782
|
-
raise "the #{-info}-th argument of #{func} had illegal value" if info.negative?
|
|
805
|
+
raise LapackError, "the #{-info}-th argument of #{func} had illegal value" if info.negative?
|
|
783
806
|
|
|
784
807
|
func = :"#{bchr}gehrd"
|
|
785
808
|
hq, tau, info = Numo::Linalg::Lapack.send(func, b, ilo: ilo, ihi: ihi)
|
|
786
809
|
|
|
787
|
-
raise "the #{-info}-th argument of #{func} had illegal value" if info.negative?
|
|
810
|
+
raise LapackError, "the #{-info}-th argument of #{func} had illegal value" if info.negative?
|
|
788
811
|
|
|
789
812
|
h = hq.triu(-1)
|
|
790
813
|
return h unless calc_q
|
|
@@ -792,7 +815,7 @@ module Numo
|
|
|
792
815
|
func = %w[d s].include?(bchr) ? :"#{bchr}orghr" : :"#{bchr}unghr"
|
|
793
816
|
q, info = Numo::Linalg::Lapack.send(func, hq, tau, ilo: ilo, ihi: ihi)
|
|
794
817
|
|
|
795
|
-
raise "the #{-info}-th argument of #{func} had illegal value" if info.negative?
|
|
818
|
+
raise LapackError, "the #{-info}-th argument of #{func} had illegal value" if info.negative?
|
|
796
819
|
|
|
797
820
|
[h, q]
|
|
798
821
|
end
|
|
@@ -830,7 +853,15 @@ module Numo
|
|
|
830
853
|
raise ArgumentError, "invalid array type: #{a.class}, #{b.class}" if bchr == 'n'
|
|
831
854
|
|
|
832
855
|
gesv = :"#{bchr}gesv"
|
|
833
|
-
Numo::Linalg::Lapack.send(gesv, a.dup, b.dup)
|
|
856
|
+
_lu, x, _ipiv, info = Numo::Linalg::Lapack.send(gesv, a.dup, b.dup)
|
|
857
|
+
raise LapackError, "the #{-info}-th argument of getrf had illegal value" if info.negative?
|
|
858
|
+
|
|
859
|
+
if info.positive?
|
|
860
|
+
warn('the factorization has been completed, but the factor is singular, ' \
|
|
861
|
+
'so the solution could not be computed.')
|
|
862
|
+
end
|
|
863
|
+
|
|
864
|
+
x
|
|
834
865
|
end
|
|
835
866
|
|
|
836
867
|
# Solves linear equation `A * x = b` or `A * X = B` for `x` assuming `A` is a triangular matrix.
|
|
@@ -867,7 +898,7 @@ module Numo
|
|
|
867
898
|
trtrs = :"#{bchr}trtrs"
|
|
868
899
|
uplo = lower ? 'L' : 'U'
|
|
869
900
|
x, info = Numo::Linalg::Lapack.send(trtrs, a, b.dup, uplo: uplo)
|
|
870
|
-
raise "wrong value is given to the #{info}-th argument of #{trtrs} used internally" if info.negative?
|
|
901
|
+
raise LapackError, "wrong value is given to the #{info}-th argument of #{trtrs} used internally" if info.negative?
|
|
871
902
|
|
|
872
903
|
x
|
|
873
904
|
end
|
|
@@ -923,9 +954,9 @@ module Numo
|
|
|
923
954
|
raise ArgumentError, "invalid driver: #{driver}"
|
|
924
955
|
end
|
|
925
956
|
|
|
926
|
-
raise "the #{info.abs}-th argument had illegal value" if info.negative?
|
|
927
|
-
raise 'input array has a NAN entry' if info == -4
|
|
928
|
-
raise '
|
|
957
|
+
raise LapackError, "the #{info.abs}-th argument had illegal value" if info.negative?
|
|
958
|
+
raise LapackError, 'the input array has a NAN entry' if info == -4
|
|
959
|
+
raise LapackError, 'the did not converge' if info.positive?
|
|
929
960
|
|
|
930
961
|
[s, u, vt]
|
|
931
962
|
end
|
|
@@ -1012,9 +1043,9 @@ module Numo
|
|
|
1012
1043
|
raise ArgumentError, "invalid driver: #{driver}"
|
|
1013
1044
|
end
|
|
1014
1045
|
|
|
1015
|
-
raise "the #{info.abs}-th argument had illegal value" if info.negative?
|
|
1016
|
-
raise 'input array has a NAN entry' if info == -4
|
|
1017
|
-
raise '
|
|
1046
|
+
raise LapackError, "the #{info.abs}-th argument had illegal value" if info.negative?
|
|
1047
|
+
raise LapackError, 'the input array has a NAN entry' if info == -4
|
|
1048
|
+
raise LapackError, 'the decomposition did not converge' if info.positive?
|
|
1018
1049
|
|
|
1019
1050
|
s
|
|
1020
1051
|
end
|
|
@@ -1140,8 +1171,12 @@ module Numo
|
|
|
1140
1171
|
getrf = :"#{bchr}getrf"
|
|
1141
1172
|
lu, piv, info = Numo::Linalg::Lapack.send(getrf, a.dup)
|
|
1142
1173
|
|
|
1143
|
-
raise "the #{info.abs}-th argument of getrf had illegal value" if info.negative?
|
|
1144
|
-
|
|
1174
|
+
raise LapackError, "the #{info.abs}-th argument of getrf had illegal value" if info.negative?
|
|
1175
|
+
|
|
1176
|
+
if info.positive?
|
|
1177
|
+
warn("the factorization has been completed, but the factor U[#{info - 1}, #{info - 1}] is " \
|
|
1178
|
+
'exactly zero, indicating that the matrix is singular.')
|
|
1179
|
+
end
|
|
1145
1180
|
|
|
1146
1181
|
[lu, piv]
|
|
1147
1182
|
end
|
|
@@ -1179,7 +1214,7 @@ module Numo
|
|
|
1179
1214
|
getrs = :"#{bchr}getrs"
|
|
1180
1215
|
x, info = Numo::Linalg::Lapack.send(getrs, lu, ipiv, b.dup)
|
|
1181
1216
|
|
|
1182
|
-
raise "the #{info.abs}-th argument of getrs had illegal value" if info.negative?
|
|
1217
|
+
raise LapackError, "the #{info.abs}-th argument of getrs had illegal value" if info.negative?
|
|
1183
1218
|
|
|
1184
1219
|
x
|
|
1185
1220
|
end
|
|
@@ -1200,8 +1235,12 @@ module Numo
|
|
|
1200
1235
|
fnc = :"#{bchr}potrf"
|
|
1201
1236
|
c, info = Numo::Linalg::Lapack.send(fnc, a.dup, uplo: uplo)
|
|
1202
1237
|
|
|
1203
|
-
raise "the #{info}-th
|
|
1204
|
-
|
|
1238
|
+
raise LapackError, "the #{-info}-th argument of #{fnc} had illegal value" if info.negative?
|
|
1239
|
+
|
|
1240
|
+
if info.positive?
|
|
1241
|
+
raise LapackError, "the leading principal minor of order #{info} is not positive, " \
|
|
1242
|
+
'and the factorization could not be completed.'
|
|
1243
|
+
end
|
|
1205
1244
|
|
|
1206
1245
|
c
|
|
1207
1246
|
end
|
|
@@ -1297,7 +1336,7 @@ module Numo
|
|
|
1297
1336
|
fnc = :"#{bchr}gebal"
|
|
1298
1337
|
b, lo, hi, prm_scl, info = Numo::Linalg::Lapack.send(fnc, a.dup, job: job)
|
|
1299
1338
|
|
|
1300
|
-
raise "the #{info.abs}-th argument of #{fnc} had illegal value" if info.negative?
|
|
1339
|
+
raise LapackError, "the #{info.abs}-th argument of #{fnc} had illegal value" if info.negative?
|
|
1301
1340
|
|
|
1302
1341
|
# convert from Fortran style index to Ruby style index.
|
|
1303
1342
|
lo -= 1
|
|
@@ -1374,8 +1413,8 @@ module Numo
|
|
|
1374
1413
|
wr, wi, vl, vr, info = Numo::Linalg::Lapack.send(fnc, a.dup, jobvl: jobvl, jobvr: jobvr)
|
|
1375
1414
|
end
|
|
1376
1415
|
|
|
1377
|
-
raise "the #{info.abs}-th argument of #{fnc} had illegal value" if info.negative?
|
|
1378
|
-
raise 'the QR algorithm failed to compute all the eigenvalues.' if info.positive?
|
|
1416
|
+
raise LapackError, "the #{info.abs}-th argument of #{fnc} had illegal value" if info.negative?
|
|
1417
|
+
raise LapackError, 'the QR algorithm failed to compute all the eigenvalues.' if info.positive?
|
|
1379
1418
|
|
|
1380
1419
|
if %w[d s].include?(bchr)
|
|
1381
1420
|
w = wr + (wi * 1.0i)
|
|
@@ -1419,8 +1458,8 @@ module Numo
|
|
|
1419
1458
|
w = wr + (wi * 1.0i)
|
|
1420
1459
|
end
|
|
1421
1460
|
|
|
1422
|
-
raise "the #{info.abs}-th argument of #{fnc} had illegal value" if info.negative?
|
|
1423
|
-
raise 'the QR algorithm failed to compute all the eigenvalues.' if info.positive?
|
|
1461
|
+
raise LapackError, "the #{info.abs}-th argument of #{fnc} had illegal value" if info.negative?
|
|
1462
|
+
raise LapackError, 'the QR algorithm failed to compute all the eigenvalues.' if info.positive?
|
|
1424
1463
|
|
|
1425
1464
|
w
|
|
1426
1465
|
end
|
|
@@ -1470,8 +1509,12 @@ module Numo
|
|
|
1470
1509
|
lud = a.dup
|
|
1471
1510
|
ipiv, info = Numo::Linalg::Lapack.send(fnc, lud, uplo: uplo)
|
|
1472
1511
|
|
|
1473
|
-
raise "the #{info.abs}-th argument of #{fnc} had illegal value" if info.negative?
|
|
1474
|
-
|
|
1512
|
+
raise LapackError, "the #{info.abs}-th argument of #{fnc} had illegal value" if info.negative?
|
|
1513
|
+
|
|
1514
|
+
if info.positive?
|
|
1515
|
+
warn("the factorization has been completed, but the D[#{info - 1}, #{info - 1}] is " \
|
|
1516
|
+
'exactly zero, indicating that the block diagonal matrix is singular.')
|
|
1517
|
+
end
|
|
1475
1518
|
|
|
1476
1519
|
_lud_permutation(lud, ipiv, uplo: uplo, hermitian: hermitian)
|
|
1477
1520
|
end
|
|
@@ -1559,8 +1602,8 @@ module Numo
|
|
|
1559
1602
|
fnc = :"#{bchr}gelsd"
|
|
1560
1603
|
s, rank, info = Numo::Linalg::Lapack.send(fnc, a.dup, x, rcond: rcond)
|
|
1561
1604
|
|
|
1562
|
-
raise "the #{info.abs}-th argument of #{fnc} had illegal value" if info.negative?
|
|
1563
|
-
raise 'the algorithm for computing the SVD failed to converge' if info.positive?
|
|
1605
|
+
raise LapackError, "the #{info.abs}-th argument of #{fnc} had illegal value" if info.negative?
|
|
1606
|
+
raise LapackError, 'the algorithm for computing the SVD failed to converge' if info.positive?
|
|
1564
1607
|
|
|
1565
1608
|
resids = x.class[]
|
|
1566
1609
|
if m > n
|
|
@@ -1616,6 +1659,22 @@ module Numo
|
|
|
1616
1659
|
a_expm
|
|
1617
1660
|
end
|
|
1618
1661
|
|
|
1662
|
+
# Computes the matrix logarithm using its eigenvalue decomposition.
|
|
1663
|
+
#
|
|
1664
|
+
# @param a [Numo::NArray] The n-by-n square matrix.
|
|
1665
|
+
# @return [Numo::NArray] The matrix logarithm of `a`.
|
|
1666
|
+
def logm(a)
|
|
1667
|
+
raise Numo::NArray::ShapeError, 'input array a must be 2-dimensional' if a.ndim != 2
|
|
1668
|
+
raise Numo::NArray::ShapeError, 'input array a must be square' if a.shape[0] != a.shape[1]
|
|
1669
|
+
|
|
1670
|
+
ev, vl, = eig(a, left: true, right: false)
|
|
1671
|
+
v = vl.transpose.conj
|
|
1672
|
+
inv_v = Numo::Linalg.inv(v)
|
|
1673
|
+
log_ev = Numo::NMath.log(ev)
|
|
1674
|
+
|
|
1675
|
+
inv_v.dot(log_ev.diag).dot(v)
|
|
1676
|
+
end
|
|
1677
|
+
|
|
1619
1678
|
# Computes the matrix sine using the matrix exponential.
|
|
1620
1679
|
#
|
|
1621
1680
|
# @param a [Numo::NArray] The n-by-n square matrix.
|
|
@@ -1705,6 +1764,35 @@ module Numo
|
|
|
1705
1764
|
a_sinh.dot(Numo::Linalg.inv(a_cosh))
|
|
1706
1765
|
end
|
|
1707
1766
|
|
|
1767
|
+
# Computes the square root of a matrix using its eigenvalue decomposition.
|
|
1768
|
+
#
|
|
1769
|
+
# @param a [Numo::NArray] The n-by-n square matrix.
|
|
1770
|
+
# @return [Numo::NArray] The matrix square root of `a`.
|
|
1771
|
+
def sqrtm(a)
|
|
1772
|
+
raise Numo::NArray::ShapeError, 'input array a must be 2-dimensional' if a.ndim != 2
|
|
1773
|
+
raise Numo::NArray::ShapeError, 'input array a must be square' if a.shape[0] != a.shape[1]
|
|
1774
|
+
|
|
1775
|
+
ev, vl, = eig(a, left: true, right: false)
|
|
1776
|
+
v = vl.transpose.conj
|
|
1777
|
+
inv_v = Numo::Linalg.inv(v)
|
|
1778
|
+
sqrt_ev = Numo::NMath.sqrt(ev)
|
|
1779
|
+
|
|
1780
|
+
inv_v.dot(sqrt_ev.diag).dot(v)
|
|
1781
|
+
end
|
|
1782
|
+
|
|
1783
|
+
# Computes the matrix sign function using its inverse and square root matrices.
|
|
1784
|
+
#
|
|
1785
|
+
# @param a [Numo::NArray] The n-by-n square matrix.
|
|
1786
|
+
# @return [Numo::NArray] The matrix sign function of `a`.
|
|
1787
|
+
def signm(a)
|
|
1788
|
+
raise Numo::NArray::ShapeError, 'input array a must be 2-dimensional' if a.ndim != 2
|
|
1789
|
+
raise Numo::NArray::ShapeError, 'input array a must be square' if a.shape[0] != a.shape[1]
|
|
1790
|
+
|
|
1791
|
+
a_sqrt = sqrtm(a.dot(a))
|
|
1792
|
+
a_inv = Numo::Linalg.inv(a)
|
|
1793
|
+
a_inv.dot(a_sqrt)
|
|
1794
|
+
end
|
|
1795
|
+
|
|
1708
1796
|
# Computes the inverse of a matrix using its LU decomposition.
|
|
1709
1797
|
#
|
|
1710
1798
|
# @param lu [Numo::NArray] The LU decomposition of the n-by-n matrix `A`.
|
|
@@ -1717,8 +1805,8 @@ module Numo
|
|
|
1717
1805
|
fnc = :"#{bchr}getri"
|
|
1718
1806
|
inv, info = Numo::Linalg::Lapack.send(fnc, lu.dup, ipiv)
|
|
1719
1807
|
|
|
1720
|
-
raise "the #{info.abs}-th argument of #{fnc} had illegal value" if info.negative?
|
|
1721
|
-
raise 'the matrix is singular and its inverse could not be computed' if info.positive?
|
|
1808
|
+
raise LapackError, "the #{info.abs}-th argument of #{fnc} had illegal value" if info.negative?
|
|
1809
|
+
raise LapackError, 'the matrix is singular and its inverse could not be computed' if info.positive?
|
|
1722
1810
|
|
|
1723
1811
|
inv
|
|
1724
1812
|
end
|
|
@@ -1748,8 +1836,12 @@ module Numo
|
|
|
1748
1836
|
fnc = :"#{bchr}potri"
|
|
1749
1837
|
inv, info = Numo::Linalg::Lapack.send(fnc, a.dup, uplo: uplo)
|
|
1750
1838
|
|
|
1751
|
-
raise "the #{info.abs}-th argument of #{fnc} had illegal value" if info.negative?
|
|
1752
|
-
|
|
1839
|
+
raise LapackError, "the #{info.abs}-th argument of #{fnc} had illegal value" if info.negative?
|
|
1840
|
+
|
|
1841
|
+
if info.positive?
|
|
1842
|
+
raise LapackError, "the (#{info - 1}, #{info - 1})-th element of the factor U or L is zero, " \
|
|
1843
|
+
'and the inverse could not be computed.'
|
|
1844
|
+
end
|
|
1753
1845
|
|
|
1754
1846
|
inv
|
|
1755
1847
|
end
|
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.
|
|
4
|
+
version: 0.7.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- yoshoku
|
|
@@ -37,6 +37,11 @@ files:
|
|
|
37
37
|
- CODE_OF_CONDUCT.md
|
|
38
38
|
- LICENSE.txt
|
|
39
39
|
- README.md
|
|
40
|
+
- ext/numo/linalg/blas/blas_common.h
|
|
41
|
+
- ext/numo/linalg/blas/blas_util.c
|
|
42
|
+
- ext/numo/linalg/blas/blas_util.h
|
|
43
|
+
- ext/numo/linalg/blas/converter.c
|
|
44
|
+
- ext/numo/linalg/blas/converter.h
|
|
40
45
|
- ext/numo/linalg/blas/dot.c
|
|
41
46
|
- ext/numo/linalg/blas/dot.h
|
|
42
47
|
- ext/numo/linalg/blas/dot_sub.c
|
|
@@ -47,8 +52,6 @@ files:
|
|
|
47
52
|
- ext/numo/linalg/blas/gemv.h
|
|
48
53
|
- ext/numo/linalg/blas/nrm2.c
|
|
49
54
|
- ext/numo/linalg/blas/nrm2.h
|
|
50
|
-
- ext/numo/linalg/converter.c
|
|
51
|
-
- ext/numo/linalg/converter.h
|
|
52
55
|
- ext/numo/linalg/extconf.rb
|
|
53
56
|
- ext/numo/linalg/lapack/gebal.c
|
|
54
57
|
- ext/numo/linalg/lapack/gebal.h
|
|
@@ -94,6 +97,8 @@ files:
|
|
|
94
97
|
- ext/numo/linalg/lapack/hetrf.h
|
|
95
98
|
- ext/numo/linalg/lapack/lange.c
|
|
96
99
|
- ext/numo/linalg/lapack/lange.h
|
|
100
|
+
- ext/numo/linalg/lapack/lapack_util.c
|
|
101
|
+
- ext/numo/linalg/lapack/lapack_util.h
|
|
97
102
|
- ext/numo/linalg/lapack/orghr.c
|
|
98
103
|
- ext/numo/linalg/lapack/orghr.h
|
|
99
104
|
- ext/numo/linalg/lapack/orgqr.c
|
|
@@ -130,8 +135,6 @@ files:
|
|
|
130
135
|
- ext/numo/linalg/lapack/ungrq.h
|
|
131
136
|
- ext/numo/linalg/linalg.c
|
|
132
137
|
- ext/numo/linalg/linalg.h
|
|
133
|
-
- ext/numo/linalg/util.c
|
|
134
|
-
- ext/numo/linalg/util.h
|
|
135
138
|
- lib/numo/linalg.rb
|
|
136
139
|
- lib/numo/linalg/version.rb
|
|
137
140
|
- vendor/tmp/.gitkeep
|
|
@@ -142,7 +145,7 @@ metadata:
|
|
|
142
145
|
homepage_uri: https://github.com/yoshoku/numo-linalg-alt
|
|
143
146
|
source_code_uri: https://github.com/yoshoku/numo-linalg-alt
|
|
144
147
|
changelog_uri: https://github.com/yoshoku/numo-linalg-alt/blob/main/CHANGELOG.md
|
|
145
|
-
documentation_uri: https://gemdocs.org/gems/numo-linalg-alt/0.
|
|
148
|
+
documentation_uri: https://gemdocs.org/gems/numo-linalg-alt/0.7.0/
|
|
146
149
|
rubygems_mfa_required: 'true'
|
|
147
150
|
rdoc_options: []
|
|
148
151
|
require_paths:
|
|
@@ -158,7 +161,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
158
161
|
- !ruby/object:Gem::Version
|
|
159
162
|
version: '0'
|
|
160
163
|
requirements: []
|
|
161
|
-
rubygems_version: 3.
|
|
164
|
+
rubygems_version: 3.7.2
|
|
162
165
|
specification_version: 4
|
|
163
166
|
summary: Numo::Linalg Alternative (numo-linalg-alt) is an alternative to Numo::Linalg.
|
|
164
167
|
test_files: []
|
data/ext/numo/linalg/util.c
DELETED
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
#include "util.h"
|
|
2
|
-
|
|
3
|
-
lapack_int get_itype(VALUE val) {
|
|
4
|
-
const lapack_int itype = NUM2INT(val);
|
|
5
|
-
|
|
6
|
-
if (itype != 1 && itype != 2 && itype != 3) {
|
|
7
|
-
rb_raise(rb_eArgError, "itype must be 1, 2 or 3");
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
return itype;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
char get_jobz(VALUE val) {
|
|
14
|
-
const char jobz = NUM2CHR(val);
|
|
15
|
-
|
|
16
|
-
if (jobz != 'N' && jobz != 'V') {
|
|
17
|
-
rb_raise(rb_eArgError, "jobz must be 'N' or 'V'");
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
return jobz;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
char get_jobvs(VALUE val) {
|
|
24
|
-
const char jobvs = NUM2CHR(val);
|
|
25
|
-
if (jobvs != 'N' && jobvs != 'V') {
|
|
26
|
-
rb_raise(rb_eArgError, "jobvs must be 'N' or 'V'");
|
|
27
|
-
}
|
|
28
|
-
return jobvs;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
char get_range(VALUE val) {
|
|
32
|
-
const char range = NUM2CHR(val);
|
|
33
|
-
|
|
34
|
-
if (range != 'A' && range != 'V' && range != 'I') {
|
|
35
|
-
rb_raise(rb_eArgError, "range must be 'A', 'V' or 'I'");
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
return range;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
char get_uplo(VALUE val) {
|
|
42
|
-
const char uplo = NUM2CHR(val);
|
|
43
|
-
|
|
44
|
-
if (uplo != 'U' && uplo != 'L') {
|
|
45
|
-
rb_raise(rb_eArgError, "uplo must be 'U' or 'L'");
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
return uplo;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
int get_matrix_layout(VALUE val) {
|
|
52
|
-
const char option = NUM2CHR(val);
|
|
53
|
-
|
|
54
|
-
switch (option) {
|
|
55
|
-
case 'r':
|
|
56
|
-
case 'R':
|
|
57
|
-
break;
|
|
58
|
-
case 'c':
|
|
59
|
-
case 'C':
|
|
60
|
-
rb_warn("Numo::Linalg does not support column major.");
|
|
61
|
-
break;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
return LAPACK_ROW_MAJOR;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
enum CBLAS_TRANSPOSE get_cblas_trans(VALUE val) {
|
|
68
|
-
const char option = NUM2CHR(val);
|
|
69
|
-
enum CBLAS_TRANSPOSE res = CblasNoTrans;
|
|
70
|
-
|
|
71
|
-
switch (option) {
|
|
72
|
-
case 'n':
|
|
73
|
-
case 'N':
|
|
74
|
-
res = CblasNoTrans;
|
|
75
|
-
break;
|
|
76
|
-
case 't':
|
|
77
|
-
case 'T':
|
|
78
|
-
res = CblasTrans;
|
|
79
|
-
break;
|
|
80
|
-
case 'c':
|
|
81
|
-
case 'C':
|
|
82
|
-
res = CblasConjTrans;
|
|
83
|
-
break;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
return res;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
enum CBLAS_ORDER get_cblas_order(VALUE val) {
|
|
90
|
-
const char option = NUM2CHR(val);
|
|
91
|
-
|
|
92
|
-
switch (option) {
|
|
93
|
-
case 'r':
|
|
94
|
-
case 'R':
|
|
95
|
-
break;
|
|
96
|
-
case 'c':
|
|
97
|
-
case 'C':
|
|
98
|
-
rb_warn("Numo::Linalg does not support column major.");
|
|
99
|
-
break;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
return CblasRowMajor;
|
|
103
|
-
}
|
data/ext/numo/linalg/util.h
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
#ifndef NUMO_LINALG_ALT_UTIL_H
|
|
2
|
-
#define NUMO_LINALG_ALT_UTIL_H 1
|
|
3
|
-
|
|
4
|
-
#include <ruby.h>
|
|
5
|
-
|
|
6
|
-
#include <cblas.h>
|
|
7
|
-
#include <lapacke.h>
|
|
8
|
-
|
|
9
|
-
lapack_int get_itype(VALUE val);
|
|
10
|
-
char get_jobz(VALUE val);
|
|
11
|
-
char get_jobvs(VALUE val);
|
|
12
|
-
char get_range(VALUE val);
|
|
13
|
-
char get_uplo(VALUE val);
|
|
14
|
-
int get_matrix_layout(VALUE val);
|
|
15
|
-
enum CBLAS_TRANSPOSE get_cblas_trans(VALUE val);
|
|
16
|
-
enum CBLAS_ORDER get_cblas_order(VALUE val);
|
|
17
|
-
|
|
18
|
-
#endif // NUMO_LINALG_ALT_UTIL_H
|
|
File without changes
|