@@ -662,6 +662,309 @@ public function matmul(
662
662
return $ C ;
663
663
}
664
664
665
+ /**
666
+ * A = Symmetric matrix
667
+ * C := alpha * AB + beta * C ( right = false )
668
+ * C := alpha * BA + beta * C ( right = true )
669
+ */
670
+ public function symm (
671
+ NDArray $ A ,
672
+ NDArray $ B ,
673
+ float $ alpha =null ,
674
+ float $ beta =null ,
675
+ NDArray $ C =null ,
676
+ bool $ right =null ,
677
+ bool $ lower =null
678
+ ) : NDArray
679
+ {
680
+ if ($ A ->ndim ()!=2 || $ B ->ndim ()!=2 ) {
681
+ throw new InvalidArgumentException ('Dimensions must be 2D-NDArray ' );
682
+ }
683
+ $ shapeA = $ A ->shape ();
684
+ $ rowsA = $ shapeA [0 ];
685
+ if ($ rowsA !=$ shapeA [1 ]) {
686
+ throw new InvalidArgumentException ('The matrix "A" must be symmetric ' );
687
+ }
688
+ $ shapeB = $ B ->shape ();
689
+ $ M = $ shapeB [0 ];
690
+ $ N = $ shapeB [1 ];
691
+ $ tmpB = ($ right ) ? $ N : $ M ;
692
+ if ($ rowsA !=$ tmpB ) {
693
+ throw new InvalidArgumentException ('Unmatch Shape of matrix "A" and "B": ' ."( $ rowsA, $ rowsA) != ( $ M, $ N) " );
694
+ }
695
+ $ AA = $ A ->buffer ();
696
+ $ BB = $ B ->buffer ();
697
+ $ offA = $ A ->offset ();
698
+ $ offB = $ B ->offset ();
699
+
700
+ if ($ alpha ===null ) {
701
+ $ alpha = 1.0 ;
702
+ }
703
+ if ($ beta ===null ) {
704
+ $ beta = 0.0 ;
705
+ }
706
+ if ($ C !=null ) {
707
+ $ shapeC = $ C ->shape ();
708
+ if ($ M !=$ shapeC [0 ] || $ N !=$ shapeC [1 ]) {
709
+ throw new InvalidArgumentException ('Matrix "B" and "C" must be same shape ' );
710
+ }
711
+ } else {
712
+ $ C = $ this ->zeros ($ this ->alloc ([$ M ,$ N ],$ A ->dtype ()));
713
+ }
714
+ $ CC = $ C ->buffer ();
715
+ $ offC = $ C ->offset ();
716
+
717
+ $ lda = $ rowsA ;
718
+ $ ldb = $ N ;
719
+ $ ldc = $ N ;
720
+ $ side = ($ right ) ? BLAS ::Right : BLAS ::Left;
721
+ $ uplo = ($ lower ) ? BLAS ::Lower : BLAS ::Upper;
722
+
723
+ $ this ->blas ->symm (
724
+ BLAS ::RowMajor,$ side ,$ uplo ,
725
+ $ M ,$ N ,
726
+ $ alpha ,
727
+ $ AA ,$ offA ,$ lda ,
728
+ $ BB ,$ offB ,$ ldb ,
729
+ $ beta ,
730
+ $ CC ,$ offC ,$ ldc );
731
+
732
+ return $ C ;
733
+ }
734
+
735
+ /**
736
+ * C := alpha * A A^T + beta * C (trans=false)
737
+ * C := alpha * A^T A + beta * C (trans=true)
738
+ */
739
+ public function syrk (
740
+ NDArray $ A ,
741
+ float $ alpha =null ,
742
+ float $ beta =null ,
743
+ NDArray $ C =null ,
744
+ bool $ lower =null ,
745
+ bool $ trans =null ) : NDArray
746
+ {
747
+ if ($ A ->ndim ()!=2 ) {
748
+ throw new InvalidArgumentException ('Dimensions must be 2D-NDArray ' );
749
+ }
750
+ $ shapeA = $ A ->shape ();
751
+ if ($ trans ) {
752
+ $ shapeA = [$ shapeA [1 ],$ shapeA [0 ]];
753
+ }
754
+ $ AA = $ A ->buffer ();
755
+ $ offA = $ A ->offset ();
756
+ $ N = $ shapeA [0 ];
757
+ $ K = $ shapeA [1 ];
758
+
759
+ if ($ alpha ===null ) {
760
+ $ alpha = 1.0 ;
761
+ }
762
+ if ($ beta ===null ) {
763
+ $ beta = 0.0 ;
764
+ }
765
+ if ($ C !=null ) {
766
+ $ shapeC = $ C ->shape ();
767
+ if ($ N !=$ shapeC [0 ] || $ N !=$ shapeC [1 ]) {
768
+ throw new InvalidArgumentException ('"C" rows and cols must have the same number of "A" cols ' );
769
+ }
770
+ } else {
771
+ $ C = $ this ->zeros ($ this ->alloc ([$ N ,$ N ],$ A ->dtype ()));
772
+ }
773
+ $ CC = $ C ->buffer ();
774
+ $ offC = $ C ->offset ();
775
+
776
+ $ lda = ($ trans ) ? $ N : $ K ;
777
+ $ ldc = $ N ;
778
+ $ uplo = ($ lower ) ? BLAS ::Lower : BLAS ::Upper;
779
+ $ trans = ($ trans ) ? BLAS ::Trans : BLAS ::NoTrans;
780
+
781
+ $ this ->blas ->syrk (
782
+ BLAS ::RowMajor,$ uplo ,$ trans ,
783
+ $ N ,$ K ,
784
+ $ alpha ,
785
+ $ AA ,$ offA ,$ lda ,
786
+ $ beta ,
787
+ $ CC ,$ offC ,$ ldc );
788
+
789
+ return $ C ;
790
+ }
791
+
792
+ /**
793
+ * C := alpha * A B^T + B A^T + beta * C (trans=false)
794
+ * C := alpha * B^T A + A B^T + beta * C (trans=true)
795
+ */
796
+ public function syr2k (
797
+ NDArray $ A ,
798
+ NDArray $ B ,
799
+ float $ alpha =null ,
800
+ float $ beta =null ,
801
+ NDArray $ C =null ,
802
+ bool $ lower =null ,
803
+ bool $ trans =null ) : NDArray
804
+ {
805
+ if ($ A ->ndim ()!=2 || $ B ->ndim ()!=2 ) {
806
+ throw new InvalidArgumentException ('Dimensions must be 2D-NDArray ' );
807
+ }
808
+ $ shapeA = $ A ->shape ();
809
+ $ shapeB = $ B ->shape ();
810
+ if ($ shapeA !=$ shapeB ) {
811
+ throw new InvalidArgumentException ('Matrix A and B must be same shape ' );
812
+ }
813
+ if ($ trans ) {
814
+ $ shapeA = [$ shapeA [1 ],$ shapeA [0 ]];
815
+ }
816
+ $ AA = $ A ->buffer ();
817
+ $ offA = $ A ->offset ();
818
+ $ BB = $ B ->buffer ();
819
+ $ offB = $ B ->offset ();
820
+ $ N = $ shapeA [0 ];
821
+ $ K = $ shapeA [1 ];
822
+
823
+ if ($ alpha ===null ) {
824
+ $ alpha = 1.0 ;
825
+ }
826
+ if ($ beta ===null ) {
827
+ $ beta = 0.0 ;
828
+ }
829
+ if ($ C !=null ) {
830
+ $ shapeC = $ C ->shape ();
831
+ if ($ N !=$ shapeC [0 ] || $ N !=$ shapeC [1 ]) {
832
+ throw new InvalidArgumentException ('"C" rows and cols must have the same number of "A" cols ' );
833
+ }
834
+ } else {
835
+ $ C = $ this ->zeros ($ this ->alloc ([$ N ,$ N ],$ A ->dtype ()));
836
+ }
837
+ $ CC = $ C ->buffer ();
838
+ $ offC = $ C ->offset ();
839
+
840
+ $ lda = ($ trans ) ? $ N : $ K ;
841
+ $ ldb = ($ trans ) ? $ N : $ K ;
842
+ $ ldc = $ N ;
843
+ $ uplo = ($ lower ) ? BLAS ::Lower : BLAS ::Upper;
844
+ $ trans = ($ trans ) ? BLAS ::Trans : BLAS ::NoTrans;
845
+
846
+ $ this ->blas ->syr2k (
847
+ BLAS ::RowMajor,$ uplo ,$ trans ,
848
+ $ N ,$ K ,
849
+ $ alpha ,
850
+ $ AA ,$ offA ,$ lda ,
851
+ $ BB ,$ offB ,$ ldb ,
852
+ $ beta ,
853
+ $ CC ,$ offC ,$ ldc );
854
+
855
+ return $ C ;
856
+ }
857
+
858
+ /**
859
+ * C := alpha * A B (right=false)
860
+ * C := alpha * B A (right=true)
861
+ */
862
+ public function trmm (
863
+ NDArray $ A ,
864
+ NDArray $ B ,
865
+ float $ alpha =null ,
866
+ bool $ right =null ,
867
+ bool $ lower =null ,
868
+ bool $ trans =null ,
869
+ bool $ unit =null ) : NDArray
870
+ {
871
+ if ($ A ->ndim ()!=2 || $ B ->ndim ()!=2 ) {
872
+ throw new InvalidArgumentException ('Dimensions must be 2D-NDArray ' );
873
+ }
874
+ $ shapeA = $ A ->shape ();
875
+ $ shapeB = $ B ->shape ();
876
+ if ($ right ) {
877
+ $ sizeA = $ shapeB [1 ];
878
+ } else {
879
+ $ sizeA = $ shapeB [0 ];
880
+ }
881
+ if ($ sizeA !=$ shapeA [0 ]) {
882
+ throw new InvalidArgumentException ('Unmatch shape of Matrix A and B: ' .
883
+ '[ ' .implode (', ' ,$ shapeA ).'] <=> [ ' .implode (', ' ,$ shapeA ).'] ' );
884
+ }
885
+ $ AA = $ A ->buffer ();
886
+ $ offA = $ A ->offset ();
887
+ $ BB = $ B ->buffer ();
888
+ $ offB = $ B ->offset ();
889
+ $ M = $ shapeB [0 ];
890
+ $ N = $ shapeB [1 ];
891
+
892
+ if ($ alpha ===null ) {
893
+ $ alpha = 1.0 ;
894
+ }
895
+
896
+ $ lda = ($ right ) ? $ N : $ M ;
897
+ $ ldb = $ N ;
898
+ $ side = ($ right ) ? BLAS ::Right : BLAS ::Left;
899
+ $ uplo = ($ lower ) ? BLAS ::Lower : BLAS ::Upper;
900
+ $ trans = ($ trans ) ? BLAS ::Trans : BLAS ::NoTrans;
901
+ $ diag = ($ unit ) ? BLAS ::Unit : BLAS ::NonUnit;
902
+
903
+ $ this ->blas ->trmm (
904
+ BLAS ::RowMajor,$ side ,$ uplo ,$ trans ,$ diag ,
905
+ $ M ,$ N ,
906
+ $ alpha ,
907
+ $ AA ,$ offA ,$ lda ,
908
+ $ BB ,$ offB ,$ ldb );
909
+
910
+ return $ B ;
911
+ }
912
+
913
+ /**
914
+ * C := alpha A^-1 B (right=false)
915
+ * C := alpha B A^-1 (right=true)
916
+ */
917
+ public function trsm (
918
+ NDArray $ A ,
919
+ NDArray $ B ,
920
+ float $ alpha =null ,
921
+ bool $ right =null ,
922
+ bool $ lower =null ,
923
+ bool $ trans =null ,
924
+ bool $ unit =null ) : NDArray
925
+ {
926
+ if ($ A ->ndim ()!=2 || $ B ->ndim ()!=2 ) {
927
+ throw new InvalidArgumentException ('Dimensions must be 2D-NDArray ' );
928
+ }
929
+ $ shapeA = $ A ->shape ();
930
+ $ shapeB = $ B ->shape ();
931
+ if ($ right ) {
932
+ $ sizeA = $ shapeB [1 ];
933
+ } else {
934
+ $ sizeA = $ shapeB [0 ];
935
+ }
936
+ if ($ sizeA !=$ shapeA [0 ]) {
937
+ throw new InvalidArgumentException ('Unmatch shape of Matrix A and B: ' .
938
+ '[ ' .implode (', ' ,$ shapeA ).'] <=> [ ' .implode (', ' ,$ shapeA ).'] ' );
939
+ }
940
+ $ AA = $ A ->buffer ();
941
+ $ offA = $ A ->offset ();
942
+ $ BB = $ B ->buffer ();
943
+ $ offB = $ B ->offset ();
944
+ $ M = $ shapeB [0 ];
945
+ $ N = $ shapeB [1 ];
946
+
947
+ if ($ alpha ===null ) {
948
+ $ alpha = 1.0 ;
949
+ }
950
+
951
+ $ lda = ($ right ) ? $ N : $ M ;
952
+ $ ldb = $ N ;
953
+ $ side = ($ right ) ? BLAS ::Right : BLAS ::Left;
954
+ $ uplo = ($ lower ) ? BLAS ::Lower : BLAS ::Upper;
955
+ $ trans = ($ trans ) ? BLAS ::Trans : BLAS ::NoTrans;
956
+ $ diag = ($ unit ) ? BLAS ::Unit : BLAS ::NonUnit;
957
+
958
+ $ this ->blas ->trsm (
959
+ BLAS ::RowMajor,$ side ,$ uplo ,$ trans ,$ diag ,
960
+ $ M ,$ N ,
961
+ $ alpha ,
962
+ $ AA ,$ offA ,$ lda ,
963
+ $ BB ,$ offB ,$ ldb );
964
+
965
+ return $ B ;
966
+ }
967
+
665
968
/**
666
969
* ret := x_1 + ... + x_n
667
970
*/
0 commit comments