gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485
This commit is contained in:
2
go.mod
2
go.mod
@@ -442,7 +442,7 @@ replace (
|
||||
golang.org/x/text => golang.org/x/text v0.0.0-20170810154203-b19bf474d317
|
||||
golang.org/x/time => golang.org/x/time v0.0.0-20161028155119-f51c12702a4d
|
||||
golang.org/x/tools => golang.org/x/tools v0.0.0-20190205050122-7f7074d5bcfd
|
||||
gonum.org/v1/gonum => gonum.org/v1/gonum v0.0.0-20180726124543-cebdade430cc
|
||||
gonum.org/v1/gonum => gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485
|
||||
gonum.org/v1/netlib => gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e
|
||||
google.golang.org/api => google.golang.org/api v0.0.0-20181220000619-583d854617af
|
||||
google.golang.org/appengine => google.golang.org/appengine v1.5.0
|
||||
|
||||
4
go.sum
4
go.sum
@@ -454,8 +454,8 @@ golang.org/x/time v0.0.0-20161028155119-f51c12702a4d h1:TnM+PKb3ylGmZvyPXmo9m/wk
|
||||
golang.org/x/time v0.0.0-20161028155119-f51c12702a4d/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20190205050122-7f7074d5bcfd h1:Es0jGqKF2dQq+Z+0JvLFrUgmuMpgFwsFnKJQiaKEJNU=
|
||||
golang.org/x/tools v0.0.0-20190205050122-7f7074d5bcfd/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
gonum.org/v1/gonum v0.0.0-20180726124543-cebdade430cc h1:54pjpwMXgPOGLujOy/QdrSB3aRqX3d0a3pNyCJq+a7c=
|
||||
gonum.org/v1/gonum v0.0.0-20180726124543-cebdade430cc/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo=
|
||||
gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485 h1:OB/uP/Puiu5vS5QMRPrXCDWUPb+kt8f1KW8oQzFejQw=
|
||||
gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485/go.mod h1:2ltnJ7xHfj0zHS40VVPYEAAMTa3ZGguvHGBSJeRWqE0=
|
||||
gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e h1:jRyg0XfpwWlhEV8mDfdNGBeSJM2fuyh9Yjrnd8kF2Ts=
|
||||
gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e/go.mod h1:kS+toOQn6AQKjmKJ7gzohV1XkqsFehRA2FbsbkopSuQ=
|
||||
google.golang.org/api v0.0.0-20181220000619-583d854617af h1:iQMS7JKv/0w/iiWf1M49Cg3dmOkBoBZT5KheqPDpaac=
|
||||
|
||||
@@ -149,7 +149,7 @@ replace (
|
||||
golang.org/x/text => golang.org/x/text v0.0.0-20170810154203-b19bf474d317
|
||||
golang.org/x/time => golang.org/x/time v0.0.0-20161028155119-f51c12702a4d
|
||||
golang.org/x/tools => golang.org/x/tools v0.0.0-20190205050122-7f7074d5bcfd
|
||||
gonum.org/v1/gonum => gonum.org/v1/gonum v0.0.0-20180726124543-cebdade430cc
|
||||
gonum.org/v1/gonum => gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485
|
||||
gonum.org/v1/netlib => gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e
|
||||
google.golang.org/appengine => google.golang.org/appengine v1.5.0
|
||||
google.golang.org/genproto => google.golang.org/genproto v0.0.0-20170731182057-09f6ed296fc6
|
||||
|
||||
@@ -192,7 +192,7 @@ golang.org/x/time v0.0.0-20161028155119-f51c12702a4d h1:TnM+PKb3ylGmZvyPXmo9m/wk
|
||||
golang.org/x/time v0.0.0-20161028155119-f51c12702a4d/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20190205050122-7f7074d5bcfd h1:Es0jGqKF2dQq+Z+0JvLFrUgmuMpgFwsFnKJQiaKEJNU=
|
||||
golang.org/x/tools v0.0.0-20190205050122-7f7074d5bcfd/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
gonum.org/v1/gonum v0.0.0-20180726124543-cebdade430cc/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo=
|
||||
gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485/go.mod h1:2ltnJ7xHfj0zHS40VVPYEAAMTa3ZGguvHGBSJeRWqE0=
|
||||
gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e/go.mod h1:kS+toOQn6AQKjmKJ7gzohV1XkqsFehRA2FbsbkopSuQ=
|
||||
google.golang.org/appengine v1.5.0 h1:KxkO13IPW4Lslp2bz+KHP2E3gtFlrIGNThxkZQ3g+4c=
|
||||
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
|
||||
2
staging/src/k8s.io/code-generator/go.mod
generated
2
staging/src/k8s.io/code-generator/go.mod
generated
@@ -20,7 +20,7 @@ replace (
|
||||
github.com/spf13/pflag => github.com/spf13/pflag v1.0.1
|
||||
golang.org/x/exp => golang.org/x/exp v0.0.0-20180321215751-8460e604b9de
|
||||
golang.org/x/tools => golang.org/x/tools v0.0.0-20190205050122-7f7074d5bcfd
|
||||
gonum.org/v1/gonum => gonum.org/v1/gonum v0.0.0-20180726124543-cebdade430cc
|
||||
gonum.org/v1/gonum => gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485
|
||||
gonum.org/v1/netlib => gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e
|
||||
k8s.io/api => ../api
|
||||
k8s.io/apiextensions-apiserver => ../apiextensions-apiserver
|
||||
|
||||
4
staging/src/k8s.io/code-generator/go.sum
generated
4
staging/src/k8s.io/code-generator/go.sum
generated
@@ -7,8 +7,8 @@ golang.org/x/exp v0.0.0-20180321215751-8460e604b9de h1:xSjD6HQTqT0H/k60N5yYBtnN1
|
||||
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/tools v0.0.0-20190205050122-7f7074d5bcfd h1:Es0jGqKF2dQq+Z+0JvLFrUgmuMpgFwsFnKJQiaKEJNU=
|
||||
golang.org/x/tools v0.0.0-20190205050122-7f7074d5bcfd/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
gonum.org/v1/gonum v0.0.0-20180726124543-cebdade430cc h1:54pjpwMXgPOGLujOy/QdrSB3aRqX3d0a3pNyCJq+a7c=
|
||||
gonum.org/v1/gonum v0.0.0-20180726124543-cebdade430cc/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo=
|
||||
gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485 h1:OB/uP/Puiu5vS5QMRPrXCDWUPb+kt8f1KW8oQzFejQw=
|
||||
gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485/go.mod h1:2ltnJ7xHfj0zHS40VVPYEAAMTa3ZGguvHGBSJeRWqE0=
|
||||
gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e h1:jRyg0XfpwWlhEV8mDfdNGBeSJM2fuyh9Yjrnd8kF2Ts=
|
||||
gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e/go.mod h1:kS+toOQn6AQKjmKJ7gzohV1XkqsFehRA2FbsbkopSuQ=
|
||||
k8s.io/gengo v0.0.0-20190116091435-f8a0810f38af h1:SwjZbO0u5ZuaV6TRMWOGB40iaycX8sbdMQHtjNZ19dk=
|
||||
|
||||
2
staging/src/k8s.io/kube-aggregator/go.mod
generated
2
staging/src/k8s.io/kube-aggregator/go.mod
generated
@@ -128,7 +128,7 @@ replace (
|
||||
golang.org/x/text => golang.org/x/text v0.0.0-20170810154203-b19bf474d317
|
||||
golang.org/x/time => golang.org/x/time v0.0.0-20161028155119-f51c12702a4d
|
||||
golang.org/x/tools => golang.org/x/tools v0.0.0-20190205050122-7f7074d5bcfd
|
||||
gonum.org/v1/gonum => gonum.org/v1/gonum v0.0.0-20180726124543-cebdade430cc
|
||||
gonum.org/v1/gonum => gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485
|
||||
gonum.org/v1/netlib => gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e
|
||||
google.golang.org/appengine => google.golang.org/appengine v1.5.0
|
||||
google.golang.org/genproto => google.golang.org/genproto v0.0.0-20170731182057-09f6ed296fc6
|
||||
|
||||
2
staging/src/k8s.io/kube-aggregator/go.sum
generated
2
staging/src/k8s.io/kube-aggregator/go.sum
generated
@@ -176,7 +176,7 @@ golang.org/x/time v0.0.0-20161028155119-f51c12702a4d h1:TnM+PKb3ylGmZvyPXmo9m/wk
|
||||
golang.org/x/time v0.0.0-20161028155119-f51c12702a4d/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20190205050122-7f7074d5bcfd h1:Es0jGqKF2dQq+Z+0JvLFrUgmuMpgFwsFnKJQiaKEJNU=
|
||||
golang.org/x/tools v0.0.0-20190205050122-7f7074d5bcfd/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
gonum.org/v1/gonum v0.0.0-20180726124543-cebdade430cc/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo=
|
||||
gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485/go.mod h1:2ltnJ7xHfj0zHS40VVPYEAAMTa3ZGguvHGBSJeRWqE0=
|
||||
gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e/go.mod h1:kS+toOQn6AQKjmKJ7gzohV1XkqsFehRA2FbsbkopSuQ=
|
||||
google.golang.org/appengine v1.5.0 h1:KxkO13IPW4Lslp2bz+KHP2E3gtFlrIGNThxkZQ3g+4c=
|
||||
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
|
||||
2
staging/src/k8s.io/metrics/go.mod
generated
2
staging/src/k8s.io/metrics/go.mod
generated
@@ -54,7 +54,7 @@ replace (
|
||||
golang.org/x/text => golang.org/x/text v0.0.0-20170810154203-b19bf474d317
|
||||
golang.org/x/time => golang.org/x/time v0.0.0-20161028155119-f51c12702a4d
|
||||
golang.org/x/tools => golang.org/x/tools v0.0.0-20190205050122-7f7074d5bcfd
|
||||
gonum.org/v1/gonum => gonum.org/v1/gonum v0.0.0-20180726124543-cebdade430cc
|
||||
gonum.org/v1/gonum => gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485
|
||||
gonum.org/v1/netlib => gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e
|
||||
google.golang.org/appengine => google.golang.org/appengine v1.5.0
|
||||
gopkg.in/check.v1 => gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405
|
||||
|
||||
2
staging/src/k8s.io/metrics/go.sum
generated
2
staging/src/k8s.io/metrics/go.sum
generated
@@ -60,7 +60,7 @@ golang.org/x/time v0.0.0-20161028155119-f51c12702a4d h1:TnM+PKb3ylGmZvyPXmo9m/wk
|
||||
golang.org/x/time v0.0.0-20161028155119-f51c12702a4d/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20190205050122-7f7074d5bcfd h1:Es0jGqKF2dQq+Z+0JvLFrUgmuMpgFwsFnKJQiaKEJNU=
|
||||
golang.org/x/tools v0.0.0-20190205050122-7f7074d5bcfd/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
gonum.org/v1/gonum v0.0.0-20180726124543-cebdade430cc/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo=
|
||||
gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485/go.mod h1:2ltnJ7xHfj0zHS40VVPYEAAMTa3ZGguvHGBSJeRWqE0=
|
||||
gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e/go.mod h1:kS+toOQn6AQKjmKJ7gzohV1XkqsFehRA2FbsbkopSuQ=
|
||||
google.golang.org/appengine v1.5.0 h1:KxkO13IPW4Lslp2bz+KHP2E3gtFlrIGNThxkZQ3g+4c=
|
||||
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
|
||||
2
staging/src/k8s.io/node-api/go.mod
generated
2
staging/src/k8s.io/node-api/go.mod
generated
@@ -51,7 +51,7 @@ replace (
|
||||
golang.org/x/text => golang.org/x/text v0.0.0-20170810154203-b19bf474d317
|
||||
golang.org/x/time => golang.org/x/time v0.0.0-20161028155119-f51c12702a4d
|
||||
golang.org/x/tools => golang.org/x/tools v0.0.0-20190205050122-7f7074d5bcfd
|
||||
gonum.org/v1/gonum => gonum.org/v1/gonum v0.0.0-20180726124543-cebdade430cc
|
||||
gonum.org/v1/gonum => gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485
|
||||
gonum.org/v1/netlib => gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e
|
||||
google.golang.org/appengine => google.golang.org/appengine v1.5.0
|
||||
gopkg.in/check.v1 => gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405
|
||||
|
||||
2
staging/src/k8s.io/node-api/go.sum
generated
2
staging/src/k8s.io/node-api/go.sum
generated
@@ -62,7 +62,7 @@ golang.org/x/time v0.0.0-20161028155119-f51c12702a4d h1:TnM+PKb3ylGmZvyPXmo9m/wk
|
||||
golang.org/x/time v0.0.0-20161028155119-f51c12702a4d/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20190205050122-7f7074d5bcfd h1:Es0jGqKF2dQq+Z+0JvLFrUgmuMpgFwsFnKJQiaKEJNU=
|
||||
golang.org/x/tools v0.0.0-20190205050122-7f7074d5bcfd/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
gonum.org/v1/gonum v0.0.0-20180726124543-cebdade430cc/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo=
|
||||
gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485/go.mod h1:2ltnJ7xHfj0zHS40VVPYEAAMTa3ZGguvHGBSJeRWqE0=
|
||||
gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e/go.mod h1:kS+toOQn6AQKjmKJ7gzohV1XkqsFehRA2FbsbkopSuQ=
|
||||
google.golang.org/appengine v1.5.0 h1:KxkO13IPW4Lslp2bz+KHP2E3gtFlrIGNThxkZQ3g+4c=
|
||||
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
|
||||
2
staging/src/k8s.io/sample-apiserver/go.mod
generated
2
staging/src/k8s.io/sample-apiserver/go.mod
generated
@@ -118,7 +118,7 @@ replace (
|
||||
golang.org/x/text => golang.org/x/text v0.0.0-20170810154203-b19bf474d317
|
||||
golang.org/x/time => golang.org/x/time v0.0.0-20161028155119-f51c12702a4d
|
||||
golang.org/x/tools => golang.org/x/tools v0.0.0-20190205050122-7f7074d5bcfd
|
||||
gonum.org/v1/gonum => gonum.org/v1/gonum v0.0.0-20180726124543-cebdade430cc
|
||||
gonum.org/v1/gonum => gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485
|
||||
gonum.org/v1/netlib => gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e
|
||||
google.golang.org/appengine => google.golang.org/appengine v1.5.0
|
||||
google.golang.org/genproto => google.golang.org/genproto v0.0.0-20170731182057-09f6ed296fc6
|
||||
|
||||
2
staging/src/k8s.io/sample-apiserver/go.sum
generated
2
staging/src/k8s.io/sample-apiserver/go.sum
generated
@@ -173,7 +173,7 @@ golang.org/x/time v0.0.0-20161028155119-f51c12702a4d h1:TnM+PKb3ylGmZvyPXmo9m/wk
|
||||
golang.org/x/time v0.0.0-20161028155119-f51c12702a4d/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20190205050122-7f7074d5bcfd h1:Es0jGqKF2dQq+Z+0JvLFrUgmuMpgFwsFnKJQiaKEJNU=
|
||||
golang.org/x/tools v0.0.0-20190205050122-7f7074d5bcfd/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
gonum.org/v1/gonum v0.0.0-20180726124543-cebdade430cc/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo=
|
||||
gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485/go.mod h1:2ltnJ7xHfj0zHS40VVPYEAAMTa3ZGguvHGBSJeRWqE0=
|
||||
gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e/go.mod h1:kS+toOQn6AQKjmKJ7gzohV1XkqsFehRA2FbsbkopSuQ=
|
||||
google.golang.org/appengine v1.5.0 h1:KxkO13IPW4Lslp2bz+KHP2E3gtFlrIGNThxkZQ3g+4c=
|
||||
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
|
||||
2
staging/src/k8s.io/sample-controller/go.mod
generated
2
staging/src/k8s.io/sample-controller/go.mod
generated
@@ -53,7 +53,7 @@ replace (
|
||||
golang.org/x/text => golang.org/x/text v0.0.0-20170810154203-b19bf474d317
|
||||
golang.org/x/time => golang.org/x/time v0.0.0-20161028155119-f51c12702a4d
|
||||
golang.org/x/tools => golang.org/x/tools v0.0.0-20190205050122-7f7074d5bcfd
|
||||
gonum.org/v1/gonum => gonum.org/v1/gonum v0.0.0-20180726124543-cebdade430cc
|
||||
gonum.org/v1/gonum => gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485
|
||||
gonum.org/v1/netlib => gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e
|
||||
google.golang.org/appengine => google.golang.org/appengine v1.5.0
|
||||
gopkg.in/check.v1 => gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405
|
||||
|
||||
2
staging/src/k8s.io/sample-controller/go.sum
generated
2
staging/src/k8s.io/sample-controller/go.sum
generated
@@ -63,7 +63,7 @@ golang.org/x/time v0.0.0-20161028155119-f51c12702a4d h1:TnM+PKb3ylGmZvyPXmo9m/wk
|
||||
golang.org/x/time v0.0.0-20161028155119-f51c12702a4d/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20190205050122-7f7074d5bcfd h1:Es0jGqKF2dQq+Z+0JvLFrUgmuMpgFwsFnKJQiaKEJNU=
|
||||
golang.org/x/tools v0.0.0-20190205050122-7f7074d5bcfd/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
gonum.org/v1/gonum v0.0.0-20180726124543-cebdade430cc/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo=
|
||||
gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485/go.mod h1:2ltnJ7xHfj0zHS40VVPYEAAMTa3ZGguvHGBSJeRWqE0=
|
||||
gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e/go.mod h1:kS+toOQn6AQKjmKJ7gzohV1XkqsFehRA2FbsbkopSuQ=
|
||||
google.golang.org/appengine v1.5.0 h1:KxkO13IPW4Lslp2bz+KHP2E3gtFlrIGNThxkZQ3g+4c=
|
||||
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
|
||||
2
vendor/BUILD
vendored
2
vendor/BUILD
vendored
@@ -437,8 +437,10 @@ filegroup(
|
||||
"//vendor/gonum.org/v1/gonum/floats:all-srcs",
|
||||
"//vendor/gonum.org/v1/gonum/graph:all-srcs",
|
||||
"//vendor/gonum.org/v1/gonum/internal/asm/c128:all-srcs",
|
||||
"//vendor/gonum.org/v1/gonum/internal/asm/c64:all-srcs",
|
||||
"//vendor/gonum.org/v1/gonum/internal/asm/f32:all-srcs",
|
||||
"//vendor/gonum.org/v1/gonum/internal/asm/f64:all-srcs",
|
||||
"//vendor/gonum.org/v1/gonum/internal/cmplx64:all-srcs",
|
||||
"//vendor/gonum.org/v1/gonum/internal/math32:all-srcs",
|
||||
"//vendor/gonum.org/v1/gonum/lapack:all-srcs",
|
||||
"//vendor/gonum.org/v1/gonum/mat:all-srcs",
|
||||
|
||||
25
vendor/gonum.org/v1/gonum/AUTHORS
generated
vendored
25
vendor/gonum.org/v1/gonum/AUTHORS
generated
vendored
@@ -8,16 +8,22 @@
|
||||
|
||||
# Please keep the list sorted.
|
||||
|
||||
Brendan Tracey <tracey.brendan@gmail.com>
|
||||
Alexander Egurnov <alexander.egurnov@gmail.com>
|
||||
Bill Gray <wgray@gogray.com>
|
||||
Bill Noon <noon.bill@gmail.com>
|
||||
Brendan Tracey <tracey.brendan@gmail.com>
|
||||
Brent Pedersen <bpederse@gmail.com>
|
||||
Chad Kunde <kunde21@gmail.com>
|
||||
Chih-Wei Chang <bert.cwchang@gmail.com>
|
||||
Chris Tessum <ctessum@gmail.com>
|
||||
Christophe Meessen <christophe.meessen@gmail.com>
|
||||
Clayton Northey <clayton.northey@gmail.com>
|
||||
Dan Kortschak <dan.kortschak@adelaide.edu.au> <dan@kortschak.io>
|
||||
Daniel Fireman <danielfireman@gmail.com>
|
||||
David Samborski <bloggingarrow@gmail.com>
|
||||
Davor Kapsa <davor.kapsa@gmail.com>
|
||||
DeepMind Technologies
|
||||
Dezmond Goff <goff.dezmond@gmail.com>
|
||||
Egon Elbre <egonelbre@gmail.com>
|
||||
Ekaterina Efimova <katerina.efimova@gmail.com>
|
||||
Ethan Burns <burns.ethan@gmail.com>
|
||||
@@ -28,6 +34,8 @@ Francesc Campoy <campoy@golang.org>
|
||||
Google Inc
|
||||
Gustaf Johansson <gustaf@pinon.se>
|
||||
Iakov Davydov <iakov.davydov@unil.ch>
|
||||
Igor Mikushkin <igor.mikushkin@gmail.com>
|
||||
Iskander Sharipov <quasilyte@gmail.com>
|
||||
Jalem Raj Rohit <jrajrohit33@gmail.com>
|
||||
James Bell <james@stellentus.com>
|
||||
James Bowman <james.edward.bowman@gmail.com>
|
||||
@@ -36,35 +44,46 @@ Janne Snabb <snabb@epipe.com>
|
||||
Jeff Juozapaitis <jjjuozap@email.arizona.edu>
|
||||
Jeremy Atkinson <jchatkinson@gmail.com>
|
||||
Jonas Kahler <jonas@derkahler.de>
|
||||
Jonas Schulze <jonas.schulze@ovgu.de>
|
||||
Jonathan J Lawlor <jonathan.lawlor@gmail.com>
|
||||
Jonathan Schroeder <jd.schroeder@gmail.com>
|
||||
Joseph Watson <jtwatson@linux-consulting.us>
|
||||
Josh Wilson <josh.craig.wilson@gmail.com>
|
||||
Julien Roland <juroland@gmail.com>
|
||||
Kai Trukenmüller <ktye78@gmail.com>
|
||||
Kent English <kent.english@gmail.com>
|
||||
Kevin C. Zimmerman <kevinczimmerman@gmail.com>
|
||||
Kirill Motkov <motkov.kirill@gmail.com>
|
||||
Konstantin Shaposhnikov <k.shaposhnikov@gmail.com>
|
||||
Leonid Kneller <recondite.matter@gmail.com>
|
||||
Lyron Winderbaum <lyron.winderbaum@student.adelaide.edu.au>
|
||||
Martin Diz <github@martindiz.com.ar>
|
||||
Matthieu Di Mercurio <matthieu.dimercurio@gmail.com>
|
||||
Max Halford <maxhalford25@gmail.com>
|
||||
MinJae Kwon <k239507@gmail.com>
|
||||
Nick Potts <nick@the-potts.com>
|
||||
Olivier Wulveryck <olivier.wulveryck@gmail.com>
|
||||
Or Rikon <rikonor@gmail.com>
|
||||
Pontus Melke <pontusmelke@gmail.com>
|
||||
Renée French
|
||||
Rishi Desai <desai.rishi1@gmail.com>
|
||||
Robin Eklind <r.eklind.87@gmail.com>
|
||||
Samuel Kelemen <Samuel@Kelemen.us>
|
||||
Sam Zaydel <szaydel@gmail.com>
|
||||
Samuel Kelemen <Samuel@Kelemen.us>
|
||||
Saran Ahluwalia <ahlusar.ahluwalia@gmail.com>
|
||||
Scott Holden <scott@sshconnection.com>
|
||||
Sebastien Binet <seb.binet@gmail.com>
|
||||
source{d} <hello@sourced.tech>
|
||||
Shawn Smith <shawnpsmith@gmail.com>
|
||||
source{d} <hello@sourced.tech>
|
||||
Spencer Lyon <spencerlyon2@gmail.com>
|
||||
Steve McCoy <mccoyst@gmail.com>
|
||||
Taesu Pyo <pyotaesu@gmail.com>
|
||||
Takeshi Yoneda <cz.rk.t0415y.g@gmail.com>
|
||||
The University of Adelaide
|
||||
The University of Minnesota
|
||||
The University of Washington
|
||||
Thomas Berg <tomfuture@gmail.com>
|
||||
Tobin Harding <me@tobin.cc>
|
||||
Vincent Thiery <vjmthiery@gmail.com>
|
||||
Vladimír Chalupecký <vladimir.chalupecky@gmail.com>
|
||||
Yevgeniy Vahlis <evahlis@gmail.com>
|
||||
|
||||
22
vendor/gonum.org/v1/gonum/CONTRIBUTORS
generated
vendored
22
vendor/gonum.org/v1/gonum/CONTRIBUTORS
generated
vendored
@@ -15,17 +15,22 @@
|
||||
#
|
||||
# Please keep the list sorted.
|
||||
|
||||
Alexander Egurnov <alexander.egurnov@gmail.com>
|
||||
Andrew Brampton <brampton@gmail.com>
|
||||
Brendan Tracey <tracey.brendan@gmail.com>
|
||||
Bill Gray <wgray@gogray.com>
|
||||
Bill Noon <noon.bill@gmail.com>
|
||||
Brendan Tracey <tracey.brendan@gmail.com>
|
||||
Brent Pedersen <bpederse@gmail.com>
|
||||
Chad Kunde <kunde21@gmail.com>
|
||||
Chih-Wei Chang <bert.cwchang@gmail.com>
|
||||
Chris Tessum <ctessum@gmail.com>
|
||||
Christophe Meessen <christophe.meessen@gmail.com>
|
||||
Clayton Northey <clayton.northey@gmail.com>
|
||||
Dan Kortschak <dan.kortschak@adelaide.edu.au> <dan@kortschak.io>
|
||||
Daniel Fireman <danielfireman@gmail.com>
|
||||
David Samborski <bloggingarrow@gmail.com>
|
||||
Davor Kapsa <davor.kapsa@gmail.com>
|
||||
Dezmond Goff <goff.dezmond@gmail.com>
|
||||
Egon Elbre <egonelbre@gmail.com>
|
||||
Ekaterina Efimova <katerina.efimova@gmail.com>
|
||||
Ethan Burns <burns.ethan@gmail.com>
|
||||
@@ -35,6 +40,8 @@ Fazlul Shahriar <fshahriar@gmail.com>
|
||||
Francesc Campoy <campoy@golang.org>
|
||||
Gustaf Johansson <gustaf@pinon.se>
|
||||
Iakov Davydov <iakov.davydov@unil.ch>
|
||||
Igor Mikushkin <igor.mikushkin@gmail.com>
|
||||
Iskander Sharipov <quasilyte@gmail.com>
|
||||
Jalem Raj Rohit <jrajrohit33@gmail.com>
|
||||
James Bell <james@stellentus.com>
|
||||
James Bowman <james.edward.bowman@gmail.com>
|
||||
@@ -43,31 +50,42 @@ Janne Snabb <snabb@epipe.com>
|
||||
Jeff Juozapaitis <jjjuozap@email.arizona.edu>
|
||||
Jeremy Atkinson <jchatkinson@gmail.com>
|
||||
Jonas Kahler <jonas@derkahler.de>
|
||||
Jonas Schulze <jonas.schulze@ovgu.de>
|
||||
Jonathan J Lawlor <jonathan.lawlor@gmail.com>
|
||||
Jonathan Schroeder <jd.schroeder@gmail.com>
|
||||
Joseph Watson <jtwatson@linux-consulting.us>
|
||||
Josh Wilson <josh.craig.wilson@gmail.com>
|
||||
Julien Roland <juroland@gmail.com>
|
||||
Kai Trukenmüller <ktye78@gmail.com>
|
||||
Kent English <kent.english@gmail.com>
|
||||
Kevin C. Zimmerman <kevinczimmerman@gmail.com>
|
||||
Kirill Motkov <motkov.kirill@gmail.com>
|
||||
Konstantin Shaposhnikov <k.shaposhnikov@gmail.com>
|
||||
Leonid Kneller <recondite.matter@gmail.com>
|
||||
Lyron Winderbaum <lyron.winderbaum@student.adelaide.edu.au>
|
||||
Martin Diz <github@martindiz.com.ar>
|
||||
Matthieu Di Mercurio <matthieu.dimercurio@gmail.com>
|
||||
Max Halford <maxhalford25@gmail.com>
|
||||
MinJae Kwon <k239507@gmail.com>
|
||||
Nick Potts <nick@the-potts.com>
|
||||
Olivier Wulveryck <olivier.wulveryck@gmail.com>
|
||||
Or Rikon <rikonor@gmail.com>
|
||||
Pontus Melke <pontusmelke@gmail.com>
|
||||
Renée French
|
||||
Rishi Desai <desai.rishi1@gmail.com>
|
||||
Robin Eklind <r.eklind.87@gmail.com>
|
||||
Samuel Kelemen <Samuel@Kelemen.us>
|
||||
Sam Zaydel <szaydel@gmail.com>
|
||||
Samuel Kelemen <Samuel@Kelemen.us>
|
||||
Saran Ahluwalia <ahlusar.ahluwalia@gmail.com>
|
||||
Scott Holden <scott@sshconnection.com>
|
||||
Sebastien Binet <seb.binet@gmail.com>
|
||||
Shawn Smith <shawnpsmith@gmail.com>
|
||||
Spencer Lyon <spencerlyon2@gmail.com>
|
||||
Steve McCoy <mccoyst@gmail.com>
|
||||
Taesu Pyo <pyotaesu@gmail.com>
|
||||
Takeshi Yoneda <cz.rk.t0415y.g@gmail.com>
|
||||
Thomas Berg <tomfuture@gmail.com>
|
||||
Tobin Harding <me@tobin.cc>
|
||||
Vincent Thiery <vjmthiery@gmail.com>
|
||||
Vladimír Chalupecký <vladimir.chalupecky@gmail.com>
|
||||
Yevgeniy Vahlis <evahlis@gmail.com>
|
||||
|
||||
1
vendor/gonum.org/v1/gonum/blas/BUILD
generated
vendored
1
vendor/gonum.org/v1/gonum/blas/BUILD
generated
vendored
@@ -23,6 +23,7 @@ filegroup(
|
||||
srcs = [
|
||||
":package-srcs",
|
||||
"//vendor/gonum.org/v1/gonum/blas/blas64:all-srcs",
|
||||
"//vendor/gonum.org/v1/gonum/blas/cblas128:all-srcs",
|
||||
"//vendor/gonum.org/v1/gonum/blas/gonum:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
|
||||
40
vendor/gonum.org/v1/gonum/blas/blas.go
generated
vendored
40
vendor/gonum.org/v1/gonum/blas/blas.go
generated
vendored
@@ -30,42 +30,38 @@ type DrotmParams struct {
|
||||
H [4]float64 // Column-major 2 by 2 matrix.
|
||||
}
|
||||
|
||||
// Transpose is used to specify the transposition operation for a
|
||||
// routine.
|
||||
type Transpose int
|
||||
// Transpose specifies the transposition operation of a matrix.
|
||||
type Transpose byte
|
||||
|
||||
const (
|
||||
NoTrans Transpose = 111 + iota
|
||||
Trans
|
||||
ConjTrans
|
||||
NoTrans Transpose = 'N'
|
||||
Trans Transpose = 'T'
|
||||
ConjTrans Transpose = 'C'
|
||||
)
|
||||
|
||||
// Uplo is used to specify whether the matrix is an upper or lower
|
||||
// triangular matrix.
|
||||
type Uplo int
|
||||
// Uplo specifies whether a matrix is upper or lower triangular.
|
||||
type Uplo byte
|
||||
|
||||
const (
|
||||
All Uplo = 120 + iota
|
||||
Upper
|
||||
Lower
|
||||
Upper Uplo = 'U'
|
||||
Lower Uplo = 'L'
|
||||
All Uplo = 'A'
|
||||
)
|
||||
|
||||
// Diag is used to specify whether the matrix is a unit or non-unit
|
||||
// triangular matrix.
|
||||
type Diag int
|
||||
// Diag specifies whether a matrix is unit triangular.
|
||||
type Diag byte
|
||||
|
||||
const (
|
||||
NonUnit Diag = 131 + iota
|
||||
Unit
|
||||
NonUnit Diag = 'N'
|
||||
Unit Diag = 'U'
|
||||
)
|
||||
|
||||
// Side is used to specify from which side a multiplication operation
|
||||
// is performed.
|
||||
type Side int
|
||||
// Side specifies from which side a multiplication operation is performed.
|
||||
type Side byte
|
||||
|
||||
const (
|
||||
Left Side = 141 + iota
|
||||
Right
|
||||
Left Side = 'L'
|
||||
Right Side = 'R'
|
||||
)
|
||||
|
||||
// Float32 implements the single precision real BLAS routines.
|
||||
|
||||
104
vendor/gonum.org/v1/gonum/blas/blas64/blas64.go
generated
vendored
104
vendor/gonum.org/v1/gonum/blas/blas64/blas64.go
generated
vendored
@@ -12,7 +12,8 @@ import (
|
||||
var blas64 blas.Float64 = gonum.Implementation{}
|
||||
|
||||
// Use sets the BLAS float64 implementation to be used by subsequent BLAS calls.
|
||||
// The default implementation is native.Implementation.
|
||||
// The default implementation is
|
||||
// gonum.org/v1/gonum/blas/gonum.Implementation.
|
||||
func Use(b blas.Float64) {
|
||||
blas64 = b
|
||||
}
|
||||
@@ -27,104 +28,111 @@ func Implementation() blas.Float64 {
|
||||
|
||||
// Vector represents a vector with an associated element increment.
|
||||
type Vector struct {
|
||||
Inc int
|
||||
N int
|
||||
Data []float64
|
||||
Inc int
|
||||
}
|
||||
|
||||
// General represents a matrix using the conventional storage scheme.
|
||||
type General struct {
|
||||
Rows, Cols int
|
||||
Stride int
|
||||
Data []float64
|
||||
Stride int
|
||||
}
|
||||
|
||||
// Band represents a band matrix using the band storage scheme.
|
||||
type Band struct {
|
||||
Rows, Cols int
|
||||
KL, KU int
|
||||
Stride int
|
||||
Data []float64
|
||||
Stride int
|
||||
}
|
||||
|
||||
// Triangular represents a triangular matrix using the conventional storage scheme.
|
||||
type Triangular struct {
|
||||
N int
|
||||
Stride int
|
||||
Data []float64
|
||||
Uplo blas.Uplo
|
||||
Diag blas.Diag
|
||||
N int
|
||||
Data []float64
|
||||
Stride int
|
||||
}
|
||||
|
||||
// TriangularBand represents a triangular matrix using the band storage scheme.
|
||||
type TriangularBand struct {
|
||||
N, K int
|
||||
Stride int
|
||||
Data []float64
|
||||
Uplo blas.Uplo
|
||||
Diag blas.Diag
|
||||
N, K int
|
||||
Data []float64
|
||||
Stride int
|
||||
}
|
||||
|
||||
// TriangularPacked represents a triangular matrix using the packed storage scheme.
|
||||
type TriangularPacked struct {
|
||||
N int
|
||||
Data []float64
|
||||
Uplo blas.Uplo
|
||||
Diag blas.Diag
|
||||
N int
|
||||
Data []float64
|
||||
}
|
||||
|
||||
// Symmetric represents a symmetric matrix using the conventional storage scheme.
|
||||
type Symmetric struct {
|
||||
N int
|
||||
Stride int
|
||||
Data []float64
|
||||
Uplo blas.Uplo
|
||||
N int
|
||||
Data []float64
|
||||
Stride int
|
||||
}
|
||||
|
||||
// SymmetricBand represents a symmetric matrix using the band storage scheme.
|
||||
type SymmetricBand struct {
|
||||
N, K int
|
||||
Stride int
|
||||
Data []float64
|
||||
Uplo blas.Uplo
|
||||
N, K int
|
||||
Data []float64
|
||||
Stride int
|
||||
}
|
||||
|
||||
// SymmetricPacked represents a symmetric matrix using the packed storage scheme.
|
||||
type SymmetricPacked struct {
|
||||
Uplo blas.Uplo
|
||||
N int
|
||||
Data []float64
|
||||
Uplo blas.Uplo
|
||||
}
|
||||
|
||||
// Level 1
|
||||
|
||||
const negInc = "blas64: negative vector increment"
|
||||
const (
|
||||
negInc = "blas64: negative vector increment"
|
||||
badLength = "blas64: vector length mismatch"
|
||||
)
|
||||
|
||||
// Dot computes the dot product of the two vectors:
|
||||
// \sum_i x[i]*y[i].
|
||||
func Dot(n int, x, y Vector) float64 {
|
||||
return blas64.Ddot(n, x.Data, x.Inc, y.Data, y.Inc)
|
||||
func Dot(x, y Vector) float64 {
|
||||
if x.N != y.N {
|
||||
panic(badLength)
|
||||
}
|
||||
return blas64.Ddot(x.N, x.Data, x.Inc, y.Data, y.Inc)
|
||||
}
|
||||
|
||||
// Nrm2 computes the Euclidean norm of the vector x:
|
||||
// sqrt(\sum_i x[i]*x[i]).
|
||||
//
|
||||
// Nrm2 will panic if the vector increment is negative.
|
||||
func Nrm2(n int, x Vector) float64 {
|
||||
func Nrm2(x Vector) float64 {
|
||||
if x.Inc < 0 {
|
||||
panic(negInc)
|
||||
}
|
||||
return blas64.Dnrm2(n, x.Data, x.Inc)
|
||||
return blas64.Dnrm2(x.N, x.Data, x.Inc)
|
||||
}
|
||||
|
||||
// Asum computes the sum of the absolute values of the elements of x:
|
||||
// \sum_i |x[i]|.
|
||||
//
|
||||
// Asum will panic if the vector increment is negative.
|
||||
func Asum(n int, x Vector) float64 {
|
||||
func Asum(x Vector) float64 {
|
||||
if x.Inc < 0 {
|
||||
panic(negInc)
|
||||
}
|
||||
return blas64.Dasum(n, x.Data, x.Inc)
|
||||
return blas64.Dasum(x.N, x.Data, x.Inc)
|
||||
}
|
||||
|
||||
// Iamax returns the index of an element of x with the largest absolute value.
|
||||
@@ -132,29 +140,39 @@ func Asum(n int, x Vector) float64 {
|
||||
// Iamax returns -1 if n == 0.
|
||||
//
|
||||
// Iamax will panic if the vector increment is negative.
|
||||
func Iamax(n int, x Vector) int {
|
||||
func Iamax(x Vector) int {
|
||||
if x.Inc < 0 {
|
||||
panic(negInc)
|
||||
}
|
||||
return blas64.Idamax(n, x.Data, x.Inc)
|
||||
return blas64.Idamax(x.N, x.Data, x.Inc)
|
||||
}
|
||||
|
||||
// Swap exchanges the elements of the two vectors:
|
||||
// x[i], y[i] = y[i], x[i] for all i.
|
||||
func Swap(n int, x, y Vector) {
|
||||
blas64.Dswap(n, x.Data, x.Inc, y.Data, y.Inc)
|
||||
func Swap(x, y Vector) {
|
||||
if x.N != y.N {
|
||||
panic(badLength)
|
||||
}
|
||||
blas64.Dswap(x.N, x.Data, x.Inc, y.Data, y.Inc)
|
||||
}
|
||||
|
||||
// Copy copies the elements of x into the elements of y:
|
||||
// y[i] = x[i] for all i.
|
||||
func Copy(n int, x, y Vector) {
|
||||
blas64.Dcopy(n, x.Data, x.Inc, y.Data, y.Inc)
|
||||
// Copy requires that the lengths of x and y match and will panic otherwise.
|
||||
func Copy(x, y Vector) {
|
||||
if x.N != y.N {
|
||||
panic(badLength)
|
||||
}
|
||||
blas64.Dcopy(x.N, x.Data, x.Inc, y.Data, y.Inc)
|
||||
}
|
||||
|
||||
// Axpy adds x scaled by alpha to y:
|
||||
// y[i] += alpha*x[i] for all i.
|
||||
func Axpy(n int, alpha float64, x, y Vector) {
|
||||
blas64.Daxpy(n, alpha, x.Data, x.Inc, y.Data, y.Inc)
|
||||
func Axpy(alpha float64, x, y Vector) {
|
||||
if x.N != y.N {
|
||||
panic(badLength)
|
||||
}
|
||||
blas64.Daxpy(x.N, alpha, x.Data, x.Inc, y.Data, y.Inc)
|
||||
}
|
||||
|
||||
// Rotg computes the parameters of a Givens plane rotation so that
|
||||
@@ -184,25 +202,31 @@ func Rotmg(d1, d2, b1, b2 float64) (p blas.DrotmParams, rd1, rd2, rb1 float64) {
|
||||
// and y:
|
||||
// x[i] = c*x[i] + s*y[i],
|
||||
// y[i] = -s*x[i] + c*y[i], for all i.
|
||||
func Rot(n int, x, y Vector, c, s float64) {
|
||||
blas64.Drot(n, x.Data, x.Inc, y.Data, y.Inc, c, s)
|
||||
func Rot(x, y Vector, c, s float64) {
|
||||
if x.N != y.N {
|
||||
panic(badLength)
|
||||
}
|
||||
blas64.Drot(x.N, x.Data, x.Inc, y.Data, y.Inc, c, s)
|
||||
}
|
||||
|
||||
// Rotm applies the modified Givens rotation to n points represented by the
|
||||
// vectors x and y.
|
||||
func Rotm(n int, x, y Vector, p blas.DrotmParams) {
|
||||
blas64.Drotm(n, x.Data, x.Inc, y.Data, y.Inc, p)
|
||||
func Rotm(x, y Vector, p blas.DrotmParams) {
|
||||
if x.N != y.N {
|
||||
panic(badLength)
|
||||
}
|
||||
blas64.Drotm(x.N, x.Data, x.Inc, y.Data, y.Inc, p)
|
||||
}
|
||||
|
||||
// Scal scales the vector x by alpha:
|
||||
// x[i] *= alpha for all i.
|
||||
//
|
||||
// Scal will panic if the vector increment is negative.
|
||||
func Scal(n int, alpha float64, x Vector) {
|
||||
func Scal(alpha float64, x Vector) {
|
||||
if x.Inc < 0 {
|
||||
panic(negInc)
|
||||
}
|
||||
blas64.Dscal(n, alpha, x.Data, x.Inc)
|
||||
blas64.Dscal(x.N, alpha, x.Data, x.Inc)
|
||||
}
|
||||
|
||||
// Level 2
|
||||
|
||||
33
vendor/gonum.org/v1/gonum/blas/cblas128/BUILD
generated
vendored
Normal file
33
vendor/gonum.org/v1/gonum/blas/cblas128/BUILD
generated
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"cblas128.go",
|
||||
"conv.go",
|
||||
"conv_hermitian.go",
|
||||
"conv_symmetric.go",
|
||||
"doc.go",
|
||||
],
|
||||
importmap = "k8s.io/kubernetes/vendor/gonum.org/v1/gonum/blas/cblas128",
|
||||
importpath = "gonum.org/v1/gonum/blas/cblas128",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//vendor/gonum.org/v1/gonum/blas:go_default_library",
|
||||
"//vendor/gonum.org/v1/gonum/blas/gonum:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
508
vendor/gonum.org/v1/gonum/blas/cblas128/cblas128.go
generated
vendored
Normal file
508
vendor/gonum.org/v1/gonum/blas/cblas128/cblas128.go
generated
vendored
Normal file
@@ -0,0 +1,508 @@
|
||||
// Copyright ©2015 The Gonum Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package cblas128
|
||||
|
||||
import (
|
||||
"gonum.org/v1/gonum/blas"
|
||||
"gonum.org/v1/gonum/blas/gonum"
|
||||
)
|
||||
|
||||
var cblas128 blas.Complex128 = gonum.Implementation{}
|
||||
|
||||
// Use sets the BLAS complex128 implementation to be used by subsequent BLAS calls.
|
||||
// The default implementation is
|
||||
// gonum.org/v1/gonum/blas/gonum.Implementation.
|
||||
func Use(b blas.Complex128) {
|
||||
cblas128 = b
|
||||
}
|
||||
|
||||
// Implementation returns the current BLAS complex128 implementation.
|
||||
//
|
||||
// Implementation allows direct calls to the current the BLAS complex128 implementation
|
||||
// giving finer control of parameters.
|
||||
func Implementation() blas.Complex128 {
|
||||
return cblas128
|
||||
}
|
||||
|
||||
// Vector represents a vector with an associated element increment.
|
||||
type Vector struct {
|
||||
Inc int
|
||||
Data []complex128
|
||||
}
|
||||
|
||||
// General represents a matrix using the conventional storage scheme.
|
||||
type General struct {
|
||||
Rows, Cols int
|
||||
Stride int
|
||||
Data []complex128
|
||||
}
|
||||
|
||||
// Band represents a band matrix using the band storage scheme.
|
||||
type Band struct {
|
||||
Rows, Cols int
|
||||
KL, KU int
|
||||
Stride int
|
||||
Data []complex128
|
||||
}
|
||||
|
||||
// Triangular represents a triangular matrix using the conventional storage scheme.
|
||||
type Triangular struct {
|
||||
N int
|
||||
Stride int
|
||||
Data []complex128
|
||||
Uplo blas.Uplo
|
||||
Diag blas.Diag
|
||||
}
|
||||
|
||||
// TriangularBand represents a triangular matrix using the band storage scheme.
|
||||
type TriangularBand struct {
|
||||
N, K int
|
||||
Stride int
|
||||
Data []complex128
|
||||
Uplo blas.Uplo
|
||||
Diag blas.Diag
|
||||
}
|
||||
|
||||
// TriangularPacked represents a triangular matrix using the packed storage scheme.
|
||||
type TriangularPacked struct {
|
||||
N int
|
||||
Data []complex128
|
||||
Uplo blas.Uplo
|
||||
Diag blas.Diag
|
||||
}
|
||||
|
||||
// Symmetric represents a symmetric matrix using the conventional storage scheme.
|
||||
type Symmetric struct {
|
||||
N int
|
||||
Stride int
|
||||
Data []complex128
|
||||
Uplo blas.Uplo
|
||||
}
|
||||
|
||||
// SymmetricBand represents a symmetric matrix using the band storage scheme.
|
||||
type SymmetricBand struct {
|
||||
N, K int
|
||||
Stride int
|
||||
Data []complex128
|
||||
Uplo blas.Uplo
|
||||
}
|
||||
|
||||
// SymmetricPacked represents a symmetric matrix using the packed storage scheme.
|
||||
type SymmetricPacked struct {
|
||||
N int
|
||||
Data []complex128
|
||||
Uplo blas.Uplo
|
||||
}
|
||||
|
||||
// Hermitian represents an Hermitian matrix using the conventional storage scheme.
|
||||
type Hermitian Symmetric
|
||||
|
||||
// HermitianBand represents an Hermitian matrix using the band storage scheme.
|
||||
type HermitianBand SymmetricBand
|
||||
|
||||
// HermitianPacked represents an Hermitian matrix using the packed storage scheme.
|
||||
type HermitianPacked SymmetricPacked
|
||||
|
||||
// Level 1
|
||||
|
||||
const negInc = "cblas128: negative vector increment"
|
||||
|
||||
// Dotu computes the dot product of the two vectors without
|
||||
// complex conjugation:
|
||||
// x^T * y.
|
||||
func Dotu(n int, x, y Vector) complex128 {
|
||||
return cblas128.Zdotu(n, x.Data, x.Inc, y.Data, y.Inc)
|
||||
}
|
||||
|
||||
// Dotc computes the dot product of the two vectors with
|
||||
// complex conjugation:
|
||||
// x^H * y.
|
||||
func Dotc(n int, x, y Vector) complex128 {
|
||||
return cblas128.Zdotc(n, x.Data, x.Inc, y.Data, y.Inc)
|
||||
}
|
||||
|
||||
// Nrm2 computes the Euclidean norm of the vector x:
|
||||
// sqrt(\sum_i x[i] * x[i]).
|
||||
//
|
||||
// Nrm2 will panic if the vector increment is negative.
|
||||
func Nrm2(n int, x Vector) float64 {
|
||||
if x.Inc < 0 {
|
||||
panic(negInc)
|
||||
}
|
||||
return cblas128.Dznrm2(n, x.Data, x.Inc)
|
||||
}
|
||||
|
||||
// Asum computes the sum of magnitudes of the real and imaginary parts of
|
||||
// elements of the vector x:
|
||||
// \sum_i (|Re x[i]| + |Im x[i]|).
|
||||
//
|
||||
// Asum will panic if the vector increment is negative.
|
||||
func Asum(n int, x Vector) float64 {
|
||||
if x.Inc < 0 {
|
||||
panic(negInc)
|
||||
}
|
||||
return cblas128.Dzasum(n, x.Data, x.Inc)
|
||||
}
|
||||
|
||||
// Iamax returns the index of an element of x with the largest sum of
|
||||
// magnitudes of the real and imaginary parts (|Re x[i]|+|Im x[i]|).
|
||||
// If there are multiple such indices, the earliest is returned.
|
||||
//
|
||||
// Iamax returns -1 if n == 0.
|
||||
//
|
||||
// Iamax will panic if the vector increment is negative.
|
||||
func Iamax(n int, x Vector) int {
|
||||
if x.Inc < 0 {
|
||||
panic(negInc)
|
||||
}
|
||||
return cblas128.Izamax(n, x.Data, x.Inc)
|
||||
}
|
||||
|
||||
// Swap exchanges the elements of two vectors:
|
||||
// x[i], y[i] = y[i], x[i] for all i.
|
||||
func Swap(n int, x, y Vector) {
|
||||
cblas128.Zswap(n, x.Data, x.Inc, y.Data, y.Inc)
|
||||
}
|
||||
|
||||
// Copy copies the elements of x into the elements of y:
|
||||
// y[i] = x[i] for all i.
|
||||
func Copy(n int, x, y Vector) {
|
||||
cblas128.Zcopy(n, x.Data, x.Inc, y.Data, y.Inc)
|
||||
}
|
||||
|
||||
// Axpy computes
|
||||
// y = alpha * x + y,
|
||||
// where x and y are vectors, and alpha is a scalar.
|
||||
func Axpy(n int, alpha complex128, x, y Vector) {
|
||||
cblas128.Zaxpy(n, alpha, x.Data, x.Inc, y.Data, y.Inc)
|
||||
}
|
||||
|
||||
// Scal computes
|
||||
// x = alpha * x,
|
||||
// where x is a vector, and alpha is a scalar.
|
||||
//
|
||||
// Scal will panic if the vector increment is negative.
|
||||
func Scal(n int, alpha complex128, x Vector) {
|
||||
if x.Inc < 0 {
|
||||
panic(negInc)
|
||||
}
|
||||
cblas128.Zscal(n, alpha, x.Data, x.Inc)
|
||||
}
|
||||
|
||||
// Dscal computes
|
||||
// x = alpha * x,
|
||||
// where x is a vector, and alpha is a real scalar.
|
||||
//
|
||||
// Dscal will panic if the vector increment is negative.
|
||||
func Dscal(n int, alpha float64, x Vector) {
|
||||
if x.Inc < 0 {
|
||||
panic(negInc)
|
||||
}
|
||||
cblas128.Zdscal(n, alpha, x.Data, x.Inc)
|
||||
}
|
||||
|
||||
// Level 2
|
||||
|
||||
// Gemv computes
|
||||
// y = alpha * A * x + beta * y, if t == blas.NoTrans,
|
||||
// y = alpha * A^T * x + beta * y, if t == blas.Trans,
|
||||
// y = alpha * A^H * x + beta * y, if t == blas.ConjTrans,
|
||||
// where A is an m×n dense matrix, x and y are vectors, and alpha and beta are
|
||||
// scalars.
|
||||
func Gemv(t blas.Transpose, alpha complex128, a General, x Vector, beta complex128, y Vector) {
|
||||
cblas128.Zgemv(t, a.Rows, a.Cols, alpha, a.Data, a.Stride, x.Data, x.Inc, beta, y.Data, y.Inc)
|
||||
}
|
||||
|
||||
// Gbmv computes
|
||||
// y = alpha * A * x + beta * y, if t == blas.NoTrans,
|
||||
// y = alpha * A^T * x + beta * y, if t == blas.Trans,
|
||||
// y = alpha * A^H * x + beta * y, if t == blas.ConjTrans,
|
||||
// where A is an m×n band matrix, x and y are vectors, and alpha and beta are
|
||||
// scalars.
|
||||
func Gbmv(t blas.Transpose, alpha complex128, a Band, x Vector, beta complex128, y Vector) {
|
||||
cblas128.Zgbmv(t, a.Rows, a.Cols, a.KL, a.KU, alpha, a.Data, a.Stride, x.Data, x.Inc, beta, y.Data, y.Inc)
|
||||
}
|
||||
|
||||
// Trmv computes
|
||||
// x = A * x, if t == blas.NoTrans,
|
||||
// x = A^T * x, if t == blas.Trans,
|
||||
// x = A^H * x, if t == blas.ConjTrans,
|
||||
// where A is an n×n triangular matrix, and x is a vector.
|
||||
func Trmv(t blas.Transpose, a Triangular, x Vector) {
|
||||
cblas128.Ztrmv(a.Uplo, t, a.Diag, a.N, a.Data, a.Stride, x.Data, x.Inc)
|
||||
}
|
||||
|
||||
// Tbmv computes
|
||||
// x = A * x, if t == blas.NoTrans,
|
||||
// x = A^T * x, if t == blas.Trans,
|
||||
// x = A^H * x, if t == blas.ConjTrans,
|
||||
// where A is an n×n triangular band matrix, and x is a vector.
|
||||
func Tbmv(t blas.Transpose, a TriangularBand, x Vector) {
|
||||
cblas128.Ztbmv(a.Uplo, t, a.Diag, a.N, a.K, a.Data, a.Stride, x.Data, x.Inc)
|
||||
}
|
||||
|
||||
// Tpmv computes
|
||||
// x = A * x, if t == blas.NoTrans,
|
||||
// x = A^T * x, if t == blas.Trans,
|
||||
// x = A^H * x, if t == blas.ConjTrans,
|
||||
// where A is an n×n triangular matrix in packed format, and x is a vector.
|
||||
func Tpmv(t blas.Transpose, a TriangularPacked, x Vector) {
|
||||
cblas128.Ztpmv(a.Uplo, t, a.Diag, a.N, a.Data, x.Data, x.Inc)
|
||||
}
|
||||
|
||||
// Trsv solves
|
||||
// A * x = b, if t == blas.NoTrans,
|
||||
// A^T * x = b, if t == blas.Trans,
|
||||
// A^H * x = b, if t == blas.ConjTrans,
|
||||
// where A is an n×n triangular matrix and x is a vector.
|
||||
//
|
||||
// At entry to the function, x contains the values of b, and the result is
|
||||
// stored in-place into x.
|
||||
//
|
||||
// No test for singularity or near-singularity is included in this
|
||||
// routine. Such tests must be performed before calling this routine.
|
||||
func Trsv(t blas.Transpose, a Triangular, x Vector) {
|
||||
cblas128.Ztrsv(a.Uplo, t, a.Diag, a.N, a.Data, a.Stride, x.Data, x.Inc)
|
||||
}
|
||||
|
||||
// Tbsv solves
|
||||
// A * x = b, if t == blas.NoTrans,
|
||||
// A^T * x = b, if t == blas.Trans,
|
||||
// A^H * x = b, if t == blas.ConjTrans,
|
||||
// where A is an n×n triangular band matrix, and x is a vector.
|
||||
//
|
||||
// At entry to the function, x contains the values of b, and the result is
|
||||
// stored in-place into x.
|
||||
//
|
||||
// No test for singularity or near-singularity is included in this
|
||||
// routine. Such tests must be performed before calling this routine.
|
||||
func Tbsv(t blas.Transpose, a TriangularBand, x Vector) {
|
||||
cblas128.Ztbsv(a.Uplo, t, a.Diag, a.N, a.K, a.Data, a.Stride, x.Data, x.Inc)
|
||||
}
|
||||
|
||||
// Tpsv solves
|
||||
// A * x = b, if t == blas.NoTrans,
|
||||
// A^T * x = b, if t == blas.Trans,
|
||||
// A^H * x = b, if t == blas.ConjTrans,
|
||||
// where A is an n×n triangular matrix in packed format and x is a vector.
|
||||
//
|
||||
// At entry to the function, x contains the values of b, and the result is
|
||||
// stored in-place into x.
|
||||
//
|
||||
// No test for singularity or near-singularity is included in this
|
||||
// routine. Such tests must be performed before calling this routine.
|
||||
func Tpsv(t blas.Transpose, a TriangularPacked, x Vector) {
|
||||
cblas128.Ztpsv(a.Uplo, t, a.Diag, a.N, a.Data, x.Data, x.Inc)
|
||||
}
|
||||
|
||||
// Hemv computes
|
||||
// y = alpha * A * x + beta * y,
|
||||
// where A is an n×n Hermitian matrix, x and y are vectors, and alpha and
|
||||
// beta are scalars.
|
||||
func Hemv(alpha complex128, a Hermitian, x Vector, beta complex128, y Vector) {
|
||||
cblas128.Zhemv(a.Uplo, a.N, alpha, a.Data, a.Stride, x.Data, x.Inc, beta, y.Data, y.Inc)
|
||||
}
|
||||
|
||||
// Hbmv performs
|
||||
// y = alpha * A * x + beta * y,
|
||||
// where A is an n×n Hermitian band matrix, x and y are vectors, and alpha
|
||||
// and beta are scalars.
|
||||
func Hbmv(alpha complex128, a HermitianBand, x Vector, beta complex128, y Vector) {
|
||||
cblas128.Zhbmv(a.Uplo, a.N, a.K, alpha, a.Data, a.Stride, x.Data, x.Inc, beta, y.Data, y.Inc)
|
||||
}
|
||||
|
||||
// Hpmv performs
|
||||
// y = alpha * A * x + beta * y,
|
||||
// where A is an n×n Hermitian matrix in packed format, x and y are vectors,
|
||||
// and alpha and beta are scalars.
|
||||
func Hpmv(alpha complex128, a HermitianPacked, x Vector, beta complex128, y Vector) {
|
||||
cblas128.Zhpmv(a.Uplo, a.N, alpha, a.Data, x.Data, x.Inc, beta, y.Data, y.Inc)
|
||||
}
|
||||
|
||||
// Geru performs a rank-1 update
|
||||
// A += alpha * x * y^T,
|
||||
// where A is an m×n dense matrix, x and y are vectors, and alpha is a scalar.
|
||||
func Geru(alpha complex128, x, y Vector, a General) {
|
||||
cblas128.Zgeru(a.Rows, a.Cols, alpha, x.Data, x.Inc, y.Data, y.Inc, a.Data, a.Stride)
|
||||
}
|
||||
|
||||
// Gerc performs a rank-1 update
|
||||
// A += alpha * x * y^H,
|
||||
// where A is an m×n dense matrix, x and y are vectors, and alpha is a scalar.
|
||||
func Gerc(alpha complex128, x, y Vector, a General) {
|
||||
cblas128.Zgerc(a.Rows, a.Cols, alpha, x.Data, x.Inc, y.Data, y.Inc, a.Data, a.Stride)
|
||||
}
|
||||
|
||||
// Her performs a rank-1 update
|
||||
// A += alpha * x * y^T,
|
||||
// where A is an m×n Hermitian matrix, x and y are vectors, and alpha is a scalar.
|
||||
func Her(alpha float64, x Vector, a Hermitian) {
|
||||
cblas128.Zher(a.Uplo, a.N, alpha, x.Data, x.Inc, a.Data, a.Stride)
|
||||
}
|
||||
|
||||
// Hpr performs a rank-1 update
|
||||
// A += alpha * x * x^H,
|
||||
// where A is an n×n Hermitian matrix in packed format, x is a vector, and
|
||||
// alpha is a scalar.
|
||||
func Hpr(alpha float64, x Vector, a HermitianPacked) {
|
||||
cblas128.Zhpr(a.Uplo, a.N, alpha, x.Data, x.Inc, a.Data)
|
||||
}
|
||||
|
||||
// Her2 performs a rank-2 update
|
||||
// A += alpha * x * y^H + conj(alpha) * y * x^H,
|
||||
// where A is an n×n Hermitian matrix, x and y are vectors, and alpha is a scalar.
|
||||
func Her2(alpha complex128, x, y Vector, a Hermitian) {
|
||||
cblas128.Zher2(a.Uplo, a.N, alpha, x.Data, x.Inc, y.Data, y.Inc, a.Data, a.Stride)
|
||||
}
|
||||
|
||||
// Hpr2 performs a rank-2 update
|
||||
// A += alpha * x * y^H + conj(alpha) * y * x^H,
|
||||
// where A is an n×n Hermitian matrix in packed format, x and y are vectors,
|
||||
// and alpha is a scalar.
|
||||
func Hpr2(alpha complex128, x, y Vector, a HermitianPacked) {
|
||||
cblas128.Zhpr2(a.Uplo, a.N, alpha, x.Data, x.Inc, y.Data, y.Inc, a.Data)
|
||||
}
|
||||
|
||||
// Level 3
|
||||
|
||||
// Gemm computes
|
||||
// C = alpha * A * B + beta * C,
|
||||
// where A, B, and C are dense matrices, and alpha and beta are scalars.
|
||||
// tA and tB specify whether A or B are transposed or conjugated.
|
||||
func Gemm(tA, tB blas.Transpose, alpha complex128, a, b General, beta complex128, c General) {
|
||||
var m, n, k int
|
||||
if tA == blas.NoTrans {
|
||||
m, k = a.Rows, a.Cols
|
||||
} else {
|
||||
m, k = a.Cols, a.Rows
|
||||
}
|
||||
if tB == blas.NoTrans {
|
||||
n = b.Cols
|
||||
} else {
|
||||
n = b.Rows
|
||||
}
|
||||
cblas128.Zgemm(tA, tB, m, n, k, alpha, a.Data, a.Stride, b.Data, b.Stride, beta, c.Data, c.Stride)
|
||||
}
|
||||
|
||||
// Symm performs
|
||||
// C = alpha * A * B + beta * C, if s == blas.Left,
|
||||
// C = alpha * B * A + beta * C, if s == blas.Right,
|
||||
// where A is an n×n or m×m symmetric matrix, B and C are m×n matrices, and
|
||||
// alpha and beta are scalars.
|
||||
func Symm(s blas.Side, alpha complex128, a Symmetric, b General, beta complex128, c General) {
|
||||
var m, n int
|
||||
if s == blas.Left {
|
||||
m, n = a.N, b.Cols
|
||||
} else {
|
||||
m, n = b.Rows, a.N
|
||||
}
|
||||
cblas128.Zsymm(s, a.Uplo, m, n, alpha, a.Data, a.Stride, b.Data, b.Stride, beta, c.Data, c.Stride)
|
||||
}
|
||||
|
||||
// Syrk performs a symmetric rank-k update
|
||||
// C = alpha * A * A^T + beta * C, if t == blas.NoTrans,
|
||||
// C = alpha * A^T * A + beta * C, if t == blas.Trans,
|
||||
// where C is an n×n symmetric matrix, A is an n×k matrix if t == blas.NoTrans
|
||||
// and a k×n matrix otherwise, and alpha and beta are scalars.
|
||||
func Syrk(t blas.Transpose, alpha complex128, a General, beta complex128, c Symmetric) {
|
||||
var n, k int
|
||||
if t == blas.NoTrans {
|
||||
n, k = a.Rows, a.Cols
|
||||
} else {
|
||||
n, k = a.Cols, a.Rows
|
||||
}
|
||||
cblas128.Zsyrk(c.Uplo, t, n, k, alpha, a.Data, a.Stride, beta, c.Data, c.Stride)
|
||||
}
|
||||
|
||||
// Syr2k performs a symmetric rank-2k update
|
||||
// C = alpha * A * B^T + alpha * B * A^T + beta * C, if t == blas.NoTrans,
|
||||
// C = alpha * A^T * B + alpha * B^T * A + beta * C, if t == blas.Trans,
|
||||
// where C is an n×n symmetric matrix, A and B are n×k matrices if
|
||||
// t == blas.NoTrans and k×n otherwise, and alpha and beta are scalars.
|
||||
func Syr2k(t blas.Transpose, alpha complex128, a, b General, beta complex128, c Symmetric) {
|
||||
var n, k int
|
||||
if t == blas.NoTrans {
|
||||
n, k = a.Rows, a.Cols
|
||||
} else {
|
||||
n, k = a.Cols, a.Rows
|
||||
}
|
||||
cblas128.Zsyr2k(c.Uplo, t, n, k, alpha, a.Data, a.Stride, b.Data, b.Stride, beta, c.Data, c.Stride)
|
||||
}
|
||||
|
||||
// Trmm performs
|
||||
// B = alpha * A * B, if tA == blas.NoTrans and s == blas.Left,
|
||||
// B = alpha * A^T * B, if tA == blas.Trans and s == blas.Left,
|
||||
// B = alpha * A^H * B, if tA == blas.ConjTrans and s == blas.Left,
|
||||
// B = alpha * B * A, if tA == blas.NoTrans and s == blas.Right,
|
||||
// B = alpha * B * A^T, if tA == blas.Trans and s == blas.Right,
|
||||
// B = alpha * B * A^H, if tA == blas.ConjTrans and s == blas.Right,
|
||||
// where A is an n×n or m×m triangular matrix, B is an m×n matrix, and alpha is
|
||||
// a scalar.
|
||||
func Trmm(s blas.Side, tA blas.Transpose, alpha complex128, a Triangular, b General) {
|
||||
cblas128.Ztrmm(s, a.Uplo, tA, a.Diag, b.Rows, b.Cols, alpha, a.Data, a.Stride, b.Data, b.Stride)
|
||||
}
|
||||
|
||||
// Trsm solves
|
||||
// A * X = alpha * B, if tA == blas.NoTrans and s == blas.Left,
|
||||
// A^T * X = alpha * B, if tA == blas.Trans and s == blas.Left,
|
||||
// A^H * X = alpha * B, if tA == blas.ConjTrans and s == blas.Left,
|
||||
// X * A = alpha * B, if tA == blas.NoTrans and s == blas.Right,
|
||||
// X * A^T = alpha * B, if tA == blas.Trans and s == blas.Right,
|
||||
// X * A^H = alpha * B, if tA == blas.ConjTrans and s == blas.Right,
|
||||
// where A is an n×n or m×m triangular matrix, X and B are m×n matrices, and
|
||||
// alpha is a scalar.
|
||||
//
|
||||
// At entry to the function, b contains the values of B, and the result is
|
||||
// stored in-place into b.
|
||||
//
|
||||
// No check is made that A is invertible.
|
||||
func Trsm(s blas.Side, tA blas.Transpose, alpha complex128, a Triangular, b General) {
|
||||
cblas128.Ztrsm(s, a.Uplo, tA, a.Diag, b.Rows, b.Cols, alpha, a.Data, a.Stride, b.Data, b.Stride)
|
||||
}
|
||||
|
||||
// Hemm performs
|
||||
// C = alpha * A * B + beta * C, if s == blas.Left,
|
||||
// C = alpha * B * A + beta * C, if s == blas.Right,
|
||||
// where A is an n×n or m×m Hermitian matrix, B and C are m×n matrices, and
|
||||
// alpha and beta are scalars.
|
||||
func Hemm(s blas.Side, alpha complex128, a Hermitian, b General, beta complex128, c General) {
|
||||
var m, n int
|
||||
if s == blas.Left {
|
||||
m, n = a.N, b.Cols
|
||||
} else {
|
||||
m, n = b.Rows, a.N
|
||||
}
|
||||
cblas128.Zhemm(s, a.Uplo, m, n, alpha, a.Data, a.Stride, b.Data, b.Stride, beta, c.Data, c.Stride)
|
||||
}
|
||||
|
||||
// Herk performs the Hermitian rank-k update
|
||||
// C = alpha * A * A^H + beta*C, if t == blas.NoTrans,
|
||||
// C = alpha * A^H * A + beta*C, if t == blas.ConjTrans,
|
||||
// where C is an n×n Hermitian matrix, A is an n×k matrix if t == blas.NoTrans
|
||||
// and a k×n matrix otherwise, and alpha and beta are scalars.
|
||||
func Herk(t blas.Transpose, alpha float64, a General, beta float64, c Hermitian) {
|
||||
var n, k int
|
||||
if t == blas.NoTrans {
|
||||
n, k = a.Rows, a.Cols
|
||||
} else {
|
||||
n, k = a.Cols, a.Rows
|
||||
}
|
||||
cblas128.Zherk(c.Uplo, t, n, k, alpha, a.Data, a.Stride, beta, c.Data, c.Stride)
|
||||
}
|
||||
|
||||
// Her2k performs the Hermitian rank-2k update
|
||||
// C = alpha * A * B^H + conj(alpha) * B * A^H + beta * C, if t == blas.NoTrans,
|
||||
// C = alpha * A^H * B + conj(alpha) * B^H * A + beta * C, if t == blas.ConjTrans,
|
||||
// where C is an n×n Hermitian matrix, A and B are n×k matrices if t == NoTrans
|
||||
// and k×n matrices otherwise, and alpha and beta are scalars.
|
||||
func Her2k(t blas.Transpose, alpha complex128, a, b General, beta float64, c Hermitian) {
|
||||
var n, k int
|
||||
if t == blas.NoTrans {
|
||||
n, k = a.Rows, a.Cols
|
||||
} else {
|
||||
n, k = a.Cols, a.Rows
|
||||
}
|
||||
cblas128.Zher2k(c.Uplo, t, n, k, alpha, a.Data, a.Stride, b.Data, b.Stride, beta, c.Data, c.Stride)
|
||||
}
|
||||
279
vendor/gonum.org/v1/gonum/blas/cblas128/conv.go
generated
vendored
Normal file
279
vendor/gonum.org/v1/gonum/blas/cblas128/conv.go
generated
vendored
Normal file
@@ -0,0 +1,279 @@
|
||||
// Code generated by "go generate gonum.org/v1/gonum/blas”; DO NOT EDIT.
|
||||
|
||||
// Copyright ©2015 The Gonum Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package cblas128
|
||||
|
||||
import "gonum.org/v1/gonum/blas"
|
||||
|
||||
// GeneralCols represents a matrix using the conventional column-major storage scheme.
|
||||
type GeneralCols General
|
||||
|
||||
// From fills the receiver with elements from a. The receiver
|
||||
// must have the same dimensions as a and have adequate backing
|
||||
// data storage.
|
||||
func (t GeneralCols) From(a General) {
|
||||
if t.Rows != a.Rows || t.Cols != a.Cols {
|
||||
panic("cblas128: mismatched dimension")
|
||||
}
|
||||
if len(t.Data) < (t.Cols-1)*t.Stride+t.Rows {
|
||||
panic("cblas128: short data slice")
|
||||
}
|
||||
for i := 0; i < a.Rows; i++ {
|
||||
for j, v := range a.Data[i*a.Stride : i*a.Stride+a.Cols] {
|
||||
t.Data[i+j*t.Stride] = v
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// From fills the receiver with elements from a. The receiver
|
||||
// must have the same dimensions as a and have adequate backing
|
||||
// data storage.
|
||||
func (t General) From(a GeneralCols) {
|
||||
if t.Rows != a.Rows || t.Cols != a.Cols {
|
||||
panic("cblas128: mismatched dimension")
|
||||
}
|
||||
if len(t.Data) < (t.Rows-1)*t.Stride+t.Cols {
|
||||
panic("cblas128: short data slice")
|
||||
}
|
||||
for j := 0; j < a.Cols; j++ {
|
||||
for i, v := range a.Data[j*a.Stride : j*a.Stride+a.Rows] {
|
||||
t.Data[i*t.Stride+j] = v
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TriangularCols represents a matrix using the conventional column-major storage scheme.
|
||||
type TriangularCols Triangular
|
||||
|
||||
// From fills the receiver with elements from a. The receiver
|
||||
// must have the same dimensions, uplo and diag as a and have
|
||||
// adequate backing data storage.
|
||||
func (t TriangularCols) From(a Triangular) {
|
||||
if t.N != a.N {
|
||||
panic("cblas128: mismatched dimension")
|
||||
}
|
||||
if t.Uplo != a.Uplo {
|
||||
panic("cblas128: mismatched BLAS uplo")
|
||||
}
|
||||
if t.Diag != a.Diag {
|
||||
panic("cblas128: mismatched BLAS diag")
|
||||
}
|
||||
switch a.Uplo {
|
||||
default:
|
||||
panic("cblas128: bad BLAS uplo")
|
||||
case blas.Upper:
|
||||
for i := 0; i < a.N; i++ {
|
||||
for j := i; j < a.N; j++ {
|
||||
t.Data[i+j*t.Stride] = a.Data[i*a.Stride+j]
|
||||
}
|
||||
}
|
||||
case blas.Lower:
|
||||
for i := 0; i < a.N; i++ {
|
||||
for j := 0; j <= i; j++ {
|
||||
t.Data[i+j*t.Stride] = a.Data[i*a.Stride+j]
|
||||
}
|
||||
}
|
||||
case blas.All:
|
||||
for i := 0; i < a.N; i++ {
|
||||
for j := 0; j < a.N; j++ {
|
||||
t.Data[i+j*t.Stride] = a.Data[i*a.Stride+j]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// From fills the receiver with elements from a. The receiver
|
||||
// must have the same dimensions, uplo and diag as a and have
|
||||
// adequate backing data storage.
|
||||
func (t Triangular) From(a TriangularCols) {
|
||||
if t.N != a.N {
|
||||
panic("cblas128: mismatched dimension")
|
||||
}
|
||||
if t.Uplo != a.Uplo {
|
||||
panic("cblas128: mismatched BLAS uplo")
|
||||
}
|
||||
if t.Diag != a.Diag {
|
||||
panic("cblas128: mismatched BLAS diag")
|
||||
}
|
||||
switch a.Uplo {
|
||||
default:
|
||||
panic("cblas128: bad BLAS uplo")
|
||||
case blas.Upper:
|
||||
for i := 0; i < a.N; i++ {
|
||||
for j := i; j < a.N; j++ {
|
||||
t.Data[i*t.Stride+j] = a.Data[i+j*a.Stride]
|
||||
}
|
||||
}
|
||||
case blas.Lower:
|
||||
for i := 0; i < a.N; i++ {
|
||||
for j := 0; j <= i; j++ {
|
||||
t.Data[i*t.Stride+j] = a.Data[i+j*a.Stride]
|
||||
}
|
||||
}
|
||||
case blas.All:
|
||||
for i := 0; i < a.N; i++ {
|
||||
for j := 0; j < a.N; j++ {
|
||||
t.Data[i*t.Stride+j] = a.Data[i+j*a.Stride]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// BandCols represents a matrix using the band column-major storage scheme.
|
||||
type BandCols Band
|
||||
|
||||
// From fills the receiver with elements from a. The receiver
|
||||
// must have the same dimensions and bandwidth as a and have
|
||||
// adequate backing data storage.
|
||||
func (t BandCols) From(a Band) {
|
||||
if t.Rows != a.Rows || t.Cols != a.Cols {
|
||||
panic("cblas128: mismatched dimension")
|
||||
}
|
||||
if t.KL != a.KL || t.KU != a.KU {
|
||||
panic("cblas128: mismatched bandwidth")
|
||||
}
|
||||
if a.Stride < a.KL+a.KU+1 {
|
||||
panic("cblas128: short stride for source")
|
||||
}
|
||||
if t.Stride < t.KL+t.KU+1 {
|
||||
panic("cblas128: short stride for destination")
|
||||
}
|
||||
for i := 0; i < a.Rows; i++ {
|
||||
for j := max(0, i-a.KL); j < min(i+a.KU+1, a.Cols); j++ {
|
||||
t.Data[i+t.KU-j+j*t.Stride] = a.Data[j+a.KL-i+i*a.Stride]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// From fills the receiver with elements from a. The receiver
|
||||
// must have the same dimensions and bandwidth as a and have
|
||||
// adequate backing data storage.
|
||||
func (t Band) From(a BandCols) {
|
||||
if t.Rows != a.Rows || t.Cols != a.Cols {
|
||||
panic("cblas128: mismatched dimension")
|
||||
}
|
||||
if t.KL != a.KL || t.KU != a.KU {
|
||||
panic("cblas128: mismatched bandwidth")
|
||||
}
|
||||
if a.Stride < a.KL+a.KU+1 {
|
||||
panic("cblas128: short stride for source")
|
||||
}
|
||||
if t.Stride < t.KL+t.KU+1 {
|
||||
panic("cblas128: short stride for destination")
|
||||
}
|
||||
for j := 0; j < a.Cols; j++ {
|
||||
for i := max(0, j-a.KU); i < min(j+a.KL+1, a.Rows); i++ {
|
||||
t.Data[j+a.KL-i+i*a.Stride] = a.Data[i+t.KU-j+j*t.Stride]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TriangularBandCols represents a symmetric matrix using the band column-major storage scheme.
|
||||
type TriangularBandCols TriangularBand
|
||||
|
||||
// From fills the receiver with elements from a. The receiver
|
||||
// must have the same dimensions, bandwidth and uplo as a and
|
||||
// have adequate backing data storage.
|
||||
func (t TriangularBandCols) From(a TriangularBand) {
|
||||
if t.N != a.N {
|
||||
panic("cblas128: mismatched dimension")
|
||||
}
|
||||
if t.K != a.K {
|
||||
panic("cblas128: mismatched bandwidth")
|
||||
}
|
||||
if a.Stride < a.K+1 {
|
||||
panic("cblas128: short stride for source")
|
||||
}
|
||||
if t.Stride < t.K+1 {
|
||||
panic("cblas128: short stride for destination")
|
||||
}
|
||||
if t.Uplo != a.Uplo {
|
||||
panic("cblas128: mismatched BLAS uplo")
|
||||
}
|
||||
if t.Diag != a.Diag {
|
||||
panic("cblas128: mismatched BLAS diag")
|
||||
}
|
||||
dst := BandCols{
|
||||
Rows: t.N, Cols: t.N,
|
||||
Stride: t.Stride,
|
||||
Data: t.Data,
|
||||
}
|
||||
src := Band{
|
||||
Rows: a.N, Cols: a.N,
|
||||
Stride: a.Stride,
|
||||
Data: a.Data,
|
||||
}
|
||||
switch a.Uplo {
|
||||
default:
|
||||
panic("cblas128: bad BLAS uplo")
|
||||
case blas.Upper:
|
||||
dst.KU = t.K
|
||||
src.KU = a.K
|
||||
case blas.Lower:
|
||||
dst.KL = t.K
|
||||
src.KL = a.K
|
||||
}
|
||||
dst.From(src)
|
||||
}
|
||||
|
||||
// From fills the receiver with elements from a. The receiver
|
||||
// must have the same dimensions, bandwidth and uplo as a and
|
||||
// have adequate backing data storage.
|
||||
func (t TriangularBand) From(a TriangularBandCols) {
|
||||
if t.N != a.N {
|
||||
panic("cblas128: mismatched dimension")
|
||||
}
|
||||
if t.K != a.K {
|
||||
panic("cblas128: mismatched bandwidth")
|
||||
}
|
||||
if a.Stride < a.K+1 {
|
||||
panic("cblas128: short stride for source")
|
||||
}
|
||||
if t.Stride < t.K+1 {
|
||||
panic("cblas128: short stride for destination")
|
||||
}
|
||||
if t.Uplo != a.Uplo {
|
||||
panic("cblas128: mismatched BLAS uplo")
|
||||
}
|
||||
if t.Diag != a.Diag {
|
||||
panic("cblas128: mismatched BLAS diag")
|
||||
}
|
||||
dst := Band{
|
||||
Rows: t.N, Cols: t.N,
|
||||
Stride: t.Stride,
|
||||
Data: t.Data,
|
||||
}
|
||||
src := BandCols{
|
||||
Rows: a.N, Cols: a.N,
|
||||
Stride: a.Stride,
|
||||
Data: a.Data,
|
||||
}
|
||||
switch a.Uplo {
|
||||
default:
|
||||
panic("cblas128: bad BLAS uplo")
|
||||
case blas.Upper:
|
||||
dst.KU = t.K
|
||||
src.KU = a.K
|
||||
case blas.Lower:
|
||||
dst.KL = t.K
|
||||
src.KL = a.K
|
||||
}
|
||||
dst.From(src)
|
||||
}
|
||||
|
||||
func min(a, b int) int {
|
||||
if a < b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
func max(a, b int) int {
|
||||
if a > b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
155
vendor/gonum.org/v1/gonum/blas/cblas128/conv_hermitian.go
generated
vendored
Normal file
155
vendor/gonum.org/v1/gonum/blas/cblas128/conv_hermitian.go
generated
vendored
Normal file
@@ -0,0 +1,155 @@
|
||||
// Code generated by "go generate gonum.org/v1/gonum/blas”; DO NOT EDIT.
|
||||
|
||||
// Copyright ©2015 The Gonum Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package cblas128
|
||||
|
||||
import "gonum.org/v1/gonum/blas"
|
||||
|
||||
// HermitianCols represents a matrix using the conventional column-major storage scheme.
|
||||
type HermitianCols Hermitian
|
||||
|
||||
// From fills the receiver with elements from a. The receiver
|
||||
// must have the same dimensions and uplo as a and have adequate
|
||||
// backing data storage.
|
||||
func (t HermitianCols) From(a Hermitian) {
|
||||
if t.N != a.N {
|
||||
panic("cblas128: mismatched dimension")
|
||||
}
|
||||
if t.Uplo != a.Uplo {
|
||||
panic("cblas128: mismatched BLAS uplo")
|
||||
}
|
||||
switch a.Uplo {
|
||||
default:
|
||||
panic("cblas128: bad BLAS uplo")
|
||||
case blas.Upper:
|
||||
for i := 0; i < a.N; i++ {
|
||||
for j := i; j < a.N; j++ {
|
||||
t.Data[i+j*t.Stride] = a.Data[i*a.Stride+j]
|
||||
}
|
||||
}
|
||||
case blas.Lower:
|
||||
for i := 0; i < a.N; i++ {
|
||||
for j := 0; j <= i; j++ {
|
||||
t.Data[i+j*t.Stride] = a.Data[i*a.Stride+j]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// From fills the receiver with elements from a. The receiver
|
||||
// must have the same dimensions and uplo as a and have adequate
|
||||
// backing data storage.
|
||||
func (t Hermitian) From(a HermitianCols) {
|
||||
if t.N != a.N {
|
||||
panic("cblas128: mismatched dimension")
|
||||
}
|
||||
if t.Uplo != a.Uplo {
|
||||
panic("cblas128: mismatched BLAS uplo")
|
||||
}
|
||||
switch a.Uplo {
|
||||
default:
|
||||
panic("cblas128: bad BLAS uplo")
|
||||
case blas.Upper:
|
||||
for i := 0; i < a.N; i++ {
|
||||
for j := i; j < a.N; j++ {
|
||||
t.Data[i*t.Stride+j] = a.Data[i+j*a.Stride]
|
||||
}
|
||||
}
|
||||
case blas.Lower:
|
||||
for i := 0; i < a.N; i++ {
|
||||
for j := 0; j <= i; j++ {
|
||||
t.Data[i*t.Stride+j] = a.Data[i+j*a.Stride]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// HermitianBandCols represents an Hermitian matrix using the band column-major storage scheme.
|
||||
type HermitianBandCols HermitianBand
|
||||
|
||||
// From fills the receiver with elements from a. The receiver
|
||||
// must have the same dimensions, bandwidth and uplo as a and
|
||||
// have adequate backing data storage.
|
||||
func (t HermitianBandCols) From(a HermitianBand) {
|
||||
if t.N != a.N {
|
||||
panic("cblas128: mismatched dimension")
|
||||
}
|
||||
if t.K != a.K {
|
||||
panic("cblas128: mismatched bandwidth")
|
||||
}
|
||||
if a.Stride < a.K+1 {
|
||||
panic("cblas128: short stride for source")
|
||||
}
|
||||
if t.Stride < t.K+1 {
|
||||
panic("cblas128: short stride for destination")
|
||||
}
|
||||
if t.Uplo != a.Uplo {
|
||||
panic("cblas128: mismatched BLAS uplo")
|
||||
}
|
||||
dst := BandCols{
|
||||
Rows: t.N, Cols: t.N,
|
||||
Stride: t.Stride,
|
||||
Data: t.Data,
|
||||
}
|
||||
src := Band{
|
||||
Rows: a.N, Cols: a.N,
|
||||
Stride: a.Stride,
|
||||
Data: a.Data,
|
||||
}
|
||||
switch a.Uplo {
|
||||
default:
|
||||
panic("cblas128: bad BLAS uplo")
|
||||
case blas.Upper:
|
||||
dst.KU = t.K
|
||||
src.KU = a.K
|
||||
case blas.Lower:
|
||||
dst.KL = t.K
|
||||
src.KL = a.K
|
||||
}
|
||||
dst.From(src)
|
||||
}
|
||||
|
||||
// From fills the receiver with elements from a. The receiver
|
||||
// must have the same dimensions, bandwidth and uplo as a and
|
||||
// have adequate backing data storage.
|
||||
func (t HermitianBand) From(a HermitianBandCols) {
|
||||
if t.N != a.N {
|
||||
panic("cblas128: mismatched dimension")
|
||||
}
|
||||
if t.K != a.K {
|
||||
panic("cblas128: mismatched bandwidth")
|
||||
}
|
||||
if a.Stride < a.K+1 {
|
||||
panic("cblas128: short stride for source")
|
||||
}
|
||||
if t.Stride < t.K+1 {
|
||||
panic("cblas128: short stride for destination")
|
||||
}
|
||||
if t.Uplo != a.Uplo {
|
||||
panic("cblas128: mismatched BLAS uplo")
|
||||
}
|
||||
dst := Band{
|
||||
Rows: t.N, Cols: t.N,
|
||||
Stride: t.Stride,
|
||||
Data: t.Data,
|
||||
}
|
||||
src := BandCols{
|
||||
Rows: a.N, Cols: a.N,
|
||||
Stride: a.Stride,
|
||||
Data: a.Data,
|
||||
}
|
||||
switch a.Uplo {
|
||||
default:
|
||||
panic("cblas128: bad BLAS uplo")
|
||||
case blas.Upper:
|
||||
dst.KU = t.K
|
||||
src.KU = a.K
|
||||
case blas.Lower:
|
||||
dst.KL = t.K
|
||||
src.KL = a.K
|
||||
}
|
||||
dst.From(src)
|
||||
}
|
||||
155
vendor/gonum.org/v1/gonum/blas/cblas128/conv_symmetric.go
generated
vendored
Normal file
155
vendor/gonum.org/v1/gonum/blas/cblas128/conv_symmetric.go
generated
vendored
Normal file
@@ -0,0 +1,155 @@
|
||||
// Code generated by "go generate gonum.org/v1/gonum/blas”; DO NOT EDIT.
|
||||
|
||||
// Copyright ©2015 The Gonum Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package cblas128
|
||||
|
||||
import "gonum.org/v1/gonum/blas"
|
||||
|
||||
// SymmetricCols represents a matrix using the conventional column-major storage scheme.
|
||||
type SymmetricCols Symmetric
|
||||
|
||||
// From fills the receiver with elements from a. The receiver
|
||||
// must have the same dimensions and uplo as a and have adequate
|
||||
// backing data storage.
|
||||
func (t SymmetricCols) From(a Symmetric) {
|
||||
if t.N != a.N {
|
||||
panic("cblas128: mismatched dimension")
|
||||
}
|
||||
if t.Uplo != a.Uplo {
|
||||
panic("cblas128: mismatched BLAS uplo")
|
||||
}
|
||||
switch a.Uplo {
|
||||
default:
|
||||
panic("cblas128: bad BLAS uplo")
|
||||
case blas.Upper:
|
||||
for i := 0; i < a.N; i++ {
|
||||
for j := i; j < a.N; j++ {
|
||||
t.Data[i+j*t.Stride] = a.Data[i*a.Stride+j]
|
||||
}
|
||||
}
|
||||
case blas.Lower:
|
||||
for i := 0; i < a.N; i++ {
|
||||
for j := 0; j <= i; j++ {
|
||||
t.Data[i+j*t.Stride] = a.Data[i*a.Stride+j]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// From fills the receiver with elements from a. The receiver
|
||||
// must have the same dimensions and uplo as a and have adequate
|
||||
// backing data storage.
|
||||
func (t Symmetric) From(a SymmetricCols) {
|
||||
if t.N != a.N {
|
||||
panic("cblas128: mismatched dimension")
|
||||
}
|
||||
if t.Uplo != a.Uplo {
|
||||
panic("cblas128: mismatched BLAS uplo")
|
||||
}
|
||||
switch a.Uplo {
|
||||
default:
|
||||
panic("cblas128: bad BLAS uplo")
|
||||
case blas.Upper:
|
||||
for i := 0; i < a.N; i++ {
|
||||
for j := i; j < a.N; j++ {
|
||||
t.Data[i*t.Stride+j] = a.Data[i+j*a.Stride]
|
||||
}
|
||||
}
|
||||
case blas.Lower:
|
||||
for i := 0; i < a.N; i++ {
|
||||
for j := 0; j <= i; j++ {
|
||||
t.Data[i*t.Stride+j] = a.Data[i+j*a.Stride]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// SymmetricBandCols represents a symmetric matrix using the band column-major storage scheme.
|
||||
type SymmetricBandCols SymmetricBand
|
||||
|
||||
// From fills the receiver with elements from a. The receiver
|
||||
// must have the same dimensions, bandwidth and uplo as a and
|
||||
// have adequate backing data storage.
|
||||
func (t SymmetricBandCols) From(a SymmetricBand) {
|
||||
if t.N != a.N {
|
||||
panic("cblas128: mismatched dimension")
|
||||
}
|
||||
if t.K != a.K {
|
||||
panic("cblas128: mismatched bandwidth")
|
||||
}
|
||||
if a.Stride < a.K+1 {
|
||||
panic("cblas128: short stride for source")
|
||||
}
|
||||
if t.Stride < t.K+1 {
|
||||
panic("cblas128: short stride for destination")
|
||||
}
|
||||
if t.Uplo != a.Uplo {
|
||||
panic("cblas128: mismatched BLAS uplo")
|
||||
}
|
||||
dst := BandCols{
|
||||
Rows: t.N, Cols: t.N,
|
||||
Stride: t.Stride,
|
||||
Data: t.Data,
|
||||
}
|
||||
src := Band{
|
||||
Rows: a.N, Cols: a.N,
|
||||
Stride: a.Stride,
|
||||
Data: a.Data,
|
||||
}
|
||||
switch a.Uplo {
|
||||
default:
|
||||
panic("cblas128: bad BLAS uplo")
|
||||
case blas.Upper:
|
||||
dst.KU = t.K
|
||||
src.KU = a.K
|
||||
case blas.Lower:
|
||||
dst.KL = t.K
|
||||
src.KL = a.K
|
||||
}
|
||||
dst.From(src)
|
||||
}
|
||||
|
||||
// From fills the receiver with elements from a. The receiver
|
||||
// must have the same dimensions, bandwidth and uplo as a and
|
||||
// have adequate backing data storage.
|
||||
func (t SymmetricBand) From(a SymmetricBandCols) {
|
||||
if t.N != a.N {
|
||||
panic("cblas128: mismatched dimension")
|
||||
}
|
||||
if t.K != a.K {
|
||||
panic("cblas128: mismatched bandwidth")
|
||||
}
|
||||
if a.Stride < a.K+1 {
|
||||
panic("cblas128: short stride for source")
|
||||
}
|
||||
if t.Stride < t.K+1 {
|
||||
panic("cblas128: short stride for destination")
|
||||
}
|
||||
if t.Uplo != a.Uplo {
|
||||
panic("cblas128: mismatched BLAS uplo")
|
||||
}
|
||||
dst := Band{
|
||||
Rows: t.N, Cols: t.N,
|
||||
Stride: t.Stride,
|
||||
Data: t.Data,
|
||||
}
|
||||
src := BandCols{
|
||||
Rows: a.N, Cols: a.N,
|
||||
Stride: a.Stride,
|
||||
Data: a.Data,
|
||||
}
|
||||
switch a.Uplo {
|
||||
default:
|
||||
panic("cblas128: bad BLAS uplo")
|
||||
case blas.Upper:
|
||||
dst.KU = t.K
|
||||
src.KU = a.K
|
||||
case blas.Lower:
|
||||
dst.KL = t.K
|
||||
src.KL = a.K
|
||||
}
|
||||
dst.From(src)
|
||||
}
|
||||
6
vendor/gonum.org/v1/gonum/blas/cblas128/doc.go
generated
vendored
Normal file
6
vendor/gonum.org/v1/gonum/blas/cblas128/doc.go
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
// Copyright ©2017 The Gonum Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package cblas128 provides a simple interface to the complex128 BLAS API.
|
||||
package cblas128 // import "gonum.org/v1/gonum/blas/cblas128"
|
||||
28
vendor/gonum.org/v1/gonum/blas/gonum/BUILD
generated
vendored
28
vendor/gonum.org/v1/gonum/blas/gonum/BUILD
generated
vendored
@@ -3,23 +3,27 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"cmplx.go",
|
||||
"dgemm.go",
|
||||
"doc.go",
|
||||
"errors.go",
|
||||
"gemv.go",
|
||||
"gonum.go",
|
||||
"level1cmplx128.go",
|
||||
"level1double.go",
|
||||
"level1double_ddot.go",
|
||||
"level1single.go",
|
||||
"level1single_dsdot.go",
|
||||
"level1single_sdot.go",
|
||||
"level1single_sdsdot.go",
|
||||
"level1cmplx64.go",
|
||||
"level1float32.go",
|
||||
"level1float32_dsdot.go",
|
||||
"level1float32_sdot.go",
|
||||
"level1float32_sdsdot.go",
|
||||
"level1float64.go",
|
||||
"level1float64_ddot.go",
|
||||
"level2cmplx128.go",
|
||||
"level2double.go",
|
||||
"level2single.go",
|
||||
"level3double.go",
|
||||
"level3single.go",
|
||||
"level2cmplx64.go",
|
||||
"level2float32.go",
|
||||
"level2float64.go",
|
||||
"level3cmplx128.go",
|
||||
"level3cmplx64.go",
|
||||
"level3float32.go",
|
||||
"level3float64.go",
|
||||
"sgemm.go",
|
||||
],
|
||||
importmap = "k8s.io/kubernetes/vendor/gonum.org/v1/gonum/blas/gonum",
|
||||
@@ -28,8 +32,10 @@ go_library(
|
||||
deps = [
|
||||
"//vendor/gonum.org/v1/gonum/blas:go_default_library",
|
||||
"//vendor/gonum.org/v1/gonum/internal/asm/c128:go_default_library",
|
||||
"//vendor/gonum.org/v1/gonum/internal/asm/c64:go_default_library",
|
||||
"//vendor/gonum.org/v1/gonum/internal/asm/f32:go_default_library",
|
||||
"//vendor/gonum.org/v1/gonum/internal/asm/f64:go_default_library",
|
||||
"//vendor/gonum.org/v1/gonum/internal/cmplx64:go_default_library",
|
||||
"//vendor/gonum.org/v1/gonum/internal/math32:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
164
vendor/gonum.org/v1/gonum/blas/gonum/cmplx.go
generated
vendored
164
vendor/gonum.org/v1/gonum/blas/gonum/cmplx.go
generated
vendored
@@ -1,164 +0,0 @@
|
||||
// Copyright ©2017 The Gonum Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package gonum
|
||||
|
||||
import "gonum.org/v1/gonum/blas"
|
||||
|
||||
var (
|
||||
_ blas.Complex64 = Implementation{}
|
||||
_ blas.Complex128 = Implementation{}
|
||||
)
|
||||
|
||||
// TODO(btracey): Replace this as complex routines are added, and instead
|
||||
// automatically generate the complex64 routines from the complex128 ones.
|
||||
|
||||
var noComplex = "native: implementation does not implement this routine, see the cgo wrapper in gonum.org/v1/netlib/blas"
|
||||
|
||||
// Level 1 complex64 routines.
|
||||
|
||||
func (Implementation) Cdotu(n int, x []complex64, incX int, y []complex64, incY int) (dotu complex64) {
|
||||
panic(noComplex)
|
||||
}
|
||||
func (Implementation) Cdotc(n int, x []complex64, incX int, y []complex64, incY int) (dotc complex64) {
|
||||
panic(noComplex)
|
||||
}
|
||||
func (Implementation) Scnrm2(n int, x []complex64, incX int) float32 {
|
||||
panic(noComplex)
|
||||
}
|
||||
func (Implementation) Scasum(n int, x []complex64, incX int) float32 {
|
||||
panic(noComplex)
|
||||
}
|
||||
func (Implementation) Icamax(n int, x []complex64, incX int) int {
|
||||
panic(noComplex)
|
||||
}
|
||||
func (Implementation) Cswap(n int, x []complex64, incX int, y []complex64, incY int) {
|
||||
panic(noComplex)
|
||||
}
|
||||
func (Implementation) Ccopy(n int, x []complex64, incX int, y []complex64, incY int) {
|
||||
panic(noComplex)
|
||||
}
|
||||
func (Implementation) Caxpy(n int, alpha complex64, x []complex64, incX int, y []complex64, incY int) {
|
||||
panic(noComplex)
|
||||
}
|
||||
func (Implementation) Cscal(n int, alpha complex64, x []complex64, incX int) {
|
||||
panic(noComplex)
|
||||
}
|
||||
func (Implementation) Csscal(n int, alpha float32, x []complex64, incX int) {
|
||||
panic(noComplex)
|
||||
}
|
||||
|
||||
// Level 2 complex64 routines.
|
||||
|
||||
func (Implementation) Cgemv(tA blas.Transpose, m, n int, alpha complex64, a []complex64, lda int, x []complex64, incX int, beta complex64, y []complex64, incY int) {
|
||||
panic(noComplex)
|
||||
}
|
||||
func (Implementation) Cgbmv(tA blas.Transpose, m, n, kL, kU int, alpha complex64, a []complex64, lda int, x []complex64, incX int, beta complex64, y []complex64, incY int) {
|
||||
panic(noComplex)
|
||||
}
|
||||
func (Implementation) Ctrmv(ul blas.Uplo, tA blas.Transpose, d blas.Diag, n int, a []complex64, lda int, x []complex64, incX int) {
|
||||
panic(noComplex)
|
||||
}
|
||||
func (Implementation) Ctbmv(ul blas.Uplo, tA blas.Transpose, d blas.Diag, n, k int, a []complex64, lda int, x []complex64, incX int) {
|
||||
panic(noComplex)
|
||||
}
|
||||
func (Implementation) Ctpmv(ul blas.Uplo, tA blas.Transpose, d blas.Diag, n int, ap []complex64, x []complex64, incX int) {
|
||||
panic(noComplex)
|
||||
}
|
||||
func (Implementation) Ctrsv(ul blas.Uplo, tA blas.Transpose, d blas.Diag, n int, a []complex64, lda int, x []complex64, incX int) {
|
||||
panic(noComplex)
|
||||
}
|
||||
func (Implementation) Ctbsv(ul blas.Uplo, tA blas.Transpose, d blas.Diag, n, k int, a []complex64, lda int, x []complex64, incX int) {
|
||||
panic(noComplex)
|
||||
}
|
||||
func (Implementation) Ctpsv(ul blas.Uplo, tA blas.Transpose, d blas.Diag, n int, ap []complex64, x []complex64, incX int) {
|
||||
panic(noComplex)
|
||||
}
|
||||
func (Implementation) Chemv(ul blas.Uplo, n int, alpha complex64, a []complex64, lda int, x []complex64, incX int, beta complex64, y []complex64, incY int) {
|
||||
panic(noComplex)
|
||||
}
|
||||
func (Implementation) Chbmv(ul blas.Uplo, n, k int, alpha complex64, a []complex64, lda int, x []complex64, incX int, beta complex64, y []complex64, incY int) {
|
||||
panic(noComplex)
|
||||
}
|
||||
func (Implementation) Chpmv(ul blas.Uplo, n int, alpha complex64, ap []complex64, x []complex64, incX int, beta complex64, y []complex64, incY int) {
|
||||
panic(noComplex)
|
||||
}
|
||||
func (Implementation) Cgeru(m, n int, alpha complex64, x []complex64, incX int, y []complex64, incY int, a []complex64, lda int) {
|
||||
panic(noComplex)
|
||||
}
|
||||
func (Implementation) Cgerc(m, n int, alpha complex64, x []complex64, incX int, y []complex64, incY int, a []complex64, lda int) {
|
||||
panic(noComplex)
|
||||
}
|
||||
func (Implementation) Cher(ul blas.Uplo, n int, alpha float32, x []complex64, incX int, a []complex64, lda int) {
|
||||
panic(noComplex)
|
||||
}
|
||||
func (Implementation) Chpr(ul blas.Uplo, n int, alpha float32, x []complex64, incX int, a []complex64) {
|
||||
panic(noComplex)
|
||||
}
|
||||
func (Implementation) Cher2(ul blas.Uplo, n int, alpha complex64, x []complex64, incX int, y []complex64, incY int, a []complex64, lda int) {
|
||||
panic(noComplex)
|
||||
}
|
||||
func (Implementation) Chpr2(ul blas.Uplo, n int, alpha complex64, x []complex64, incX int, y []complex64, incY int, ap []complex64) {
|
||||
panic(noComplex)
|
||||
}
|
||||
|
||||
// Level 3 complex64 routines.
|
||||
|
||||
func (Implementation) Cgemm(tA, tB blas.Transpose, m, n, k int, alpha complex64, a []complex64, lda int, b []complex64, ldb int, beta complex64, c []complex64, ldc int) {
|
||||
panic(noComplex)
|
||||
}
|
||||
func (Implementation) Csymm(s blas.Side, ul blas.Uplo, m, n int, alpha complex64, a []complex64, lda int, b []complex64, ldb int, beta complex64, c []complex64, ldc int) {
|
||||
panic(noComplex)
|
||||
}
|
||||
func (Implementation) Csyrk(ul blas.Uplo, t blas.Transpose, n, k int, alpha complex64, a []complex64, lda int, beta complex64, c []complex64, ldc int) {
|
||||
panic(noComplex)
|
||||
}
|
||||
func (Implementation) Csyr2k(ul blas.Uplo, t blas.Transpose, n, k int, alpha complex64, a []complex64, lda int, b []complex64, ldb int, beta complex64, c []complex64, ldc int) {
|
||||
panic(noComplex)
|
||||
}
|
||||
func (Implementation) Ctrmm(s blas.Side, ul blas.Uplo, tA blas.Transpose, d blas.Diag, m, n int, alpha complex64, a []complex64, lda int, b []complex64, ldb int) {
|
||||
panic(noComplex)
|
||||
}
|
||||
func (Implementation) Ctrsm(s blas.Side, ul blas.Uplo, tA blas.Transpose, d blas.Diag, m, n int, alpha complex64, a []complex64, lda int, b []complex64, ldb int) {
|
||||
panic(noComplex)
|
||||
}
|
||||
func (Implementation) Chemm(s blas.Side, ul blas.Uplo, m, n int, alpha complex64, a []complex64, lda int, b []complex64, ldb int, beta complex64, c []complex64, ldc int) {
|
||||
panic(noComplex)
|
||||
}
|
||||
func (Implementation) Cherk(ul blas.Uplo, t blas.Transpose, n, k int, alpha float32, a []complex64, lda int, beta float32, c []complex64, ldc int) {
|
||||
panic(noComplex)
|
||||
}
|
||||
func (Implementation) Cher2k(ul blas.Uplo, t blas.Transpose, n, k int, alpha complex64, a []complex64, lda int, b []complex64, ldb int, beta float32, c []complex64, ldc int) {
|
||||
panic(noComplex)
|
||||
}
|
||||
|
||||
// Level 3 complex128 routines.
|
||||
|
||||
func (Implementation) Zgemm(tA, tB blas.Transpose, m, n, k int, alpha complex128, a []complex128, lda int, b []complex128, ldb int, beta complex128, c []complex128, ldc int) {
|
||||
panic(noComplex)
|
||||
}
|
||||
func (Implementation) Zsymm(s blas.Side, ul blas.Uplo, m, n int, alpha complex128, a []complex128, lda int, b []complex128, ldb int, beta complex128, c []complex128, ldc int) {
|
||||
panic(noComplex)
|
||||
}
|
||||
func (Implementation) Zsyrk(ul blas.Uplo, t blas.Transpose, n, k int, alpha complex128, a []complex128, lda int, beta complex128, c []complex128, ldc int) {
|
||||
panic(noComplex)
|
||||
}
|
||||
func (Implementation) Zsyr2k(ul blas.Uplo, t blas.Transpose, n, k int, alpha complex128, a []complex128, lda int, b []complex128, ldb int, beta complex128, c []complex128, ldc int) {
|
||||
panic(noComplex)
|
||||
}
|
||||
func (Implementation) Ztrmm(s blas.Side, ul blas.Uplo, tA blas.Transpose, d blas.Diag, m, n int, alpha complex128, a []complex128, lda int, b []complex128, ldb int) {
|
||||
panic(noComplex)
|
||||
}
|
||||
func (Implementation) Ztrsm(s blas.Side, ul blas.Uplo, tA blas.Transpose, d blas.Diag, m, n int, alpha complex128, a []complex128, lda int, b []complex128, ldb int) {
|
||||
panic(noComplex)
|
||||
}
|
||||
func (Implementation) Zhemm(s blas.Side, ul blas.Uplo, m, n int, alpha complex128, a []complex128, lda int, b []complex128, ldb int, beta complex128, c []complex128, ldc int) {
|
||||
panic(noComplex)
|
||||
}
|
||||
func (Implementation) Zherk(ul blas.Uplo, t blas.Transpose, n, k int, alpha float64, a []complex128, lda int, beta float64, c []complex128, ldc int) {
|
||||
panic(noComplex)
|
||||
}
|
||||
func (Implementation) Zher2k(ul blas.Uplo, t blas.Transpose, n, k int, alpha complex128, a []complex128, lda int, b []complex128, ldb int, beta float64, c []complex128, ldc int) {
|
||||
panic(noComplex)
|
||||
}
|
||||
81
vendor/gonum.org/v1/gonum/blas/gonum/dgemm.go
generated
vendored
81
vendor/gonum.org/v1/gonum/blas/gonum/dgemm.go
generated
vendored
@@ -21,25 +21,81 @@ import (
|
||||
// an m×n matrix, and alpha and beta are scalars. tA and tB specify whether A or
|
||||
// B are transposed.
|
||||
func (Implementation) Dgemm(tA, tB blas.Transpose, m, n, k int, alpha float64, a []float64, lda int, b []float64, ldb int, beta float64, c []float64, ldc int) {
|
||||
if tA != blas.NoTrans && tA != blas.Trans && tA != blas.ConjTrans {
|
||||
switch tA {
|
||||
default:
|
||||
panic(badTranspose)
|
||||
case blas.NoTrans, blas.Trans, blas.ConjTrans:
|
||||
}
|
||||
if tB != blas.NoTrans && tB != blas.Trans && tB != blas.ConjTrans {
|
||||
switch tB {
|
||||
default:
|
||||
panic(badTranspose)
|
||||
case blas.NoTrans, blas.Trans, blas.ConjTrans:
|
||||
}
|
||||
if m < 0 {
|
||||
panic(mLT0)
|
||||
}
|
||||
if n < 0 {
|
||||
panic(nLT0)
|
||||
}
|
||||
if k < 0 {
|
||||
panic(kLT0)
|
||||
}
|
||||
aTrans := tA == blas.Trans || tA == blas.ConjTrans
|
||||
if aTrans {
|
||||
checkDMatrix('a', k, m, a, lda)
|
||||
if lda < max(1, m) {
|
||||
panic(badLdA)
|
||||
}
|
||||
} else {
|
||||
checkDMatrix('a', m, k, a, lda)
|
||||
if lda < max(1, k) {
|
||||
panic(badLdA)
|
||||
}
|
||||
}
|
||||
bTrans := tB == blas.Trans || tB == blas.ConjTrans
|
||||
if bTrans {
|
||||
checkDMatrix('b', n, k, b, ldb)
|
||||
if ldb < max(1, k) {
|
||||
panic(badLdB)
|
||||
}
|
||||
} else {
|
||||
checkDMatrix('b', k, n, b, ldb)
|
||||
if ldb < max(1, n) {
|
||||
panic(badLdB)
|
||||
}
|
||||
}
|
||||
if ldc < max(1, n) {
|
||||
panic(badLdC)
|
||||
}
|
||||
|
||||
// Quick return if possible.
|
||||
if m == 0 || n == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// For zero matrix size the following slice length checks are trivially satisfied.
|
||||
if aTrans {
|
||||
if len(a) < (k-1)*lda+m {
|
||||
panic(shortA)
|
||||
}
|
||||
} else {
|
||||
if len(a) < (m-1)*lda+k {
|
||||
panic(shortA)
|
||||
}
|
||||
}
|
||||
if bTrans {
|
||||
if len(b) < (n-1)*ldb+k {
|
||||
panic(shortB)
|
||||
}
|
||||
} else {
|
||||
if len(b) < (k-1)*ldb+n {
|
||||
panic(shortB)
|
||||
}
|
||||
}
|
||||
if len(c) < (m-1)*ldc+n {
|
||||
panic(shortC)
|
||||
}
|
||||
|
||||
// Quick return if possible.
|
||||
if (alpha == 0 || k == 0) && beta == 1 {
|
||||
return
|
||||
}
|
||||
checkDMatrix('c', m, n, c, ldc)
|
||||
|
||||
// scale c
|
||||
if beta != 1 {
|
||||
@@ -124,13 +180,6 @@ func dgemmParallel(aTrans, bTrans bool, m, n, k int, a []float64, lda int, b []f
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
// Make local copies of otherwise global variables to reduce shared memory.
|
||||
// This has a noticeable effect on benchmarks in some cases.
|
||||
alpha := alpha
|
||||
aTrans := aTrans
|
||||
bTrans := bTrans
|
||||
m := m
|
||||
n := n
|
||||
for sub := range sendChan {
|
||||
i := sub.i
|
||||
j := sub.j
|
||||
@@ -210,7 +259,7 @@ func dgemmSerialNotNot(m, n, k int, a []float64, lda int, b []float64, ldb int,
|
||||
for l, v := range a[i*lda : i*lda+k] {
|
||||
tmp := alpha * v
|
||||
if tmp != 0 {
|
||||
f64.AxpyUnitaryTo(ctmp, tmp, b[l*ldb:l*ldb+n], ctmp)
|
||||
f64.AxpyUnitary(tmp, b[l*ldb:l*ldb+n], ctmp)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -226,7 +275,7 @@ func dgemmSerialTransNot(m, n, k int, a []float64, lda int, b []float64, ldb int
|
||||
tmp := alpha * v
|
||||
if tmp != 0 {
|
||||
ctmp := c[i*ldc : i*ldc+n]
|
||||
f64.AxpyUnitaryTo(ctmp, tmp, btmp, ctmp)
|
||||
f64.AxpyUnitary(tmp, btmp, ctmp)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
35
vendor/gonum.org/v1/gonum/blas/gonum/errors.go
generated
vendored
Normal file
35
vendor/gonum.org/v1/gonum/blas/gonum/errors.go
generated
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
// Copyright ©2015 The Gonum Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package gonum
|
||||
|
||||
// Panic strings used during parameter checks.
|
||||
// This list is duplicated in netlib/blas/netlib. Keep in sync.
|
||||
const (
|
||||
zeroIncX = "blas: zero x index increment"
|
||||
zeroIncY = "blas: zero y index increment"
|
||||
|
||||
mLT0 = "blas: m < 0"
|
||||
nLT0 = "blas: n < 0"
|
||||
kLT0 = "blas: k < 0"
|
||||
kLLT0 = "blas: kL < 0"
|
||||
kULT0 = "blas: kU < 0"
|
||||
|
||||
badUplo = "blas: illegal triangle"
|
||||
badTranspose = "blas: illegal transpose"
|
||||
badDiag = "blas: illegal diagonal"
|
||||
badSide = "blas: illegal side"
|
||||
badFlag = "blas: illegal rotm flag"
|
||||
|
||||
badLdA = "blas: bad leading dimension of A"
|
||||
badLdB = "blas: bad leading dimension of B"
|
||||
badLdC = "blas: bad leading dimension of C"
|
||||
|
||||
shortX = "blas: insufficient length of x"
|
||||
shortY = "blas: insufficient length of y"
|
||||
shortAP = "blas: insufficient length of ap"
|
||||
shortA = "blas: insufficient length of a"
|
||||
shortB = "blas: insufficient length of b"
|
||||
shortC = "blas: insufficient length of c"
|
||||
)
|
||||
56
vendor/gonum.org/v1/gonum/blas/gonum/gemv.go
generated
vendored
56
vendor/gonum.org/v1/gonum/blas/gonum/gemv.go
generated
vendored
@@ -29,7 +29,6 @@ func (Implementation) Dgemv(tA blas.Transpose, m, n int, alpha float64, a []floa
|
||||
if lda < max(1, n) {
|
||||
panic(badLdA)
|
||||
}
|
||||
|
||||
if incX == 0 {
|
||||
panic(zeroIncX)
|
||||
}
|
||||
@@ -43,18 +42,24 @@ func (Implementation) Dgemv(tA blas.Transpose, m, n int, alpha float64, a []floa
|
||||
lenX = n
|
||||
lenY = m
|
||||
}
|
||||
|
||||
// Quick return if possible
|
||||
if m == 0 || n == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
if (incX > 0 && (lenX-1)*incX >= len(x)) || (incX < 0 && (1-lenX)*incX >= len(x)) {
|
||||
panic(badX)
|
||||
panic(shortX)
|
||||
}
|
||||
if (incY > 0 && (lenY-1)*incY >= len(y)) || (incY < 0 && (1-lenY)*incY >= len(y)) {
|
||||
panic(badY)
|
||||
panic(shortY)
|
||||
}
|
||||
if lda*(m-1)+n > len(a) || lda < max(1, n) {
|
||||
panic(badLdA)
|
||||
if len(a) < lda*(m-1)+n {
|
||||
panic(shortA)
|
||||
}
|
||||
|
||||
// Quick return if possible
|
||||
if m == 0 || n == 0 || (alpha == 0 && beta == 1) {
|
||||
if alpha == 0 && beta == 1 {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -96,13 +101,18 @@ func (Implementation) Sgemv(tA blas.Transpose, m, n int, alpha float32, a []floa
|
||||
if lda < max(1, n) {
|
||||
panic(badLdA)
|
||||
}
|
||||
|
||||
if incX == 0 {
|
||||
panic(zeroIncX)
|
||||
}
|
||||
if incY == 0 {
|
||||
panic(zeroIncY)
|
||||
}
|
||||
|
||||
// Quick return if possible.
|
||||
if m == 0 || n == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// Set up indexes
|
||||
lenX := m
|
||||
lenY := n
|
||||
@@ -111,28 +121,20 @@ func (Implementation) Sgemv(tA blas.Transpose, m, n int, alpha float32, a []floa
|
||||
lenY = m
|
||||
}
|
||||
if (incX > 0 && (lenX-1)*incX >= len(x)) || (incX < 0 && (1-lenX)*incX >= len(x)) {
|
||||
panic(badX)
|
||||
panic(shortX)
|
||||
}
|
||||
if (incY > 0 && (lenY-1)*incY >= len(y)) || (incY < 0 && (1-lenY)*incY >= len(y)) {
|
||||
panic(badY)
|
||||
panic(shortY)
|
||||
}
|
||||
if lda*(m-1)+n > len(a) || lda < max(1, n) {
|
||||
panic(badLdA)
|
||||
if len(a) < lda*(m-1)+n {
|
||||
panic(shortA)
|
||||
}
|
||||
|
||||
// Quick return if possible
|
||||
if m == 0 || n == 0 || (alpha == 0 && beta == 1) {
|
||||
// Quick return if possible.
|
||||
if alpha == 0 && beta == 1 {
|
||||
return
|
||||
}
|
||||
|
||||
var kx, ky int
|
||||
if incX < 0 {
|
||||
kx = -(lenX - 1) * incX
|
||||
}
|
||||
if incY < 0 {
|
||||
ky = -(lenY - 1) * incY
|
||||
}
|
||||
|
||||
// First form y = beta * y
|
||||
if incY > 0 {
|
||||
Implementation{}.Sscal(lenY, beta, y, incY)
|
||||
@@ -144,11 +146,19 @@ func (Implementation) Sgemv(tA blas.Transpose, m, n int, alpha float32, a []floa
|
||||
return
|
||||
}
|
||||
|
||||
var kx, ky int
|
||||
if incX < 0 {
|
||||
kx = -(lenX - 1) * incX
|
||||
}
|
||||
if incY < 0 {
|
||||
ky = -(lenY - 1) * incY
|
||||
}
|
||||
|
||||
// Form y = alpha * A * x + y
|
||||
if tA == blas.NoTrans {
|
||||
if incX == 1 && incY == 1 {
|
||||
for i := 0; i < m; i++ {
|
||||
y[i] += alpha * f32.DotUnitary(a[lda*i:lda*i+n], x)
|
||||
y[i] += alpha * f32.DotUnitary(a[lda*i:lda*i+n], x[:n])
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -164,7 +174,7 @@ func (Implementation) Sgemv(tA blas.Transpose, m, n int, alpha float32, a []floa
|
||||
for i := 0; i < m; i++ {
|
||||
tmp := alpha * x[i]
|
||||
if tmp != 0 {
|
||||
f32.AxpyUnitaryTo(y, tmp, a[lda*i:lda*i+n], y)
|
||||
f32.AxpyUnitaryTo(y, tmp, a[lda*i:lda*i+n], y[:n])
|
||||
}
|
||||
}
|
||||
return
|
||||
|
||||
144
vendor/gonum.org/v1/gonum/blas/gonum/gonum.go
generated
vendored
144
vendor/gonum.org/v1/gonum/blas/gonum/gonum.go
generated
vendored
@@ -6,34 +6,14 @@
|
||||
|
||||
package gonum
|
||||
|
||||
import "math"
|
||||
import (
|
||||
"math"
|
||||
|
||||
"gonum.org/v1/gonum/internal/math32"
|
||||
)
|
||||
|
||||
type Implementation struct{}
|
||||
|
||||
// The following are panic strings used during parameter checks.
|
||||
const (
|
||||
zeroIncX = "blas: zero x index increment"
|
||||
zeroIncY = "blas: zero y index increment"
|
||||
|
||||
mLT0 = "blas: m < 0"
|
||||
nLT0 = "blas: n < 0"
|
||||
kLT0 = "blas: k < 0"
|
||||
kLLT0 = "blas: kL < 0"
|
||||
kULT0 = "blas: kU < 0"
|
||||
|
||||
badUplo = "blas: illegal triangle"
|
||||
badTranspose = "blas: illegal transpose"
|
||||
badDiag = "blas: illegal diagonal"
|
||||
badSide = "blas: illegal side"
|
||||
|
||||
badLdA = "blas: bad leading dimension of A"
|
||||
badLdB = "blas: bad leading dimension of B"
|
||||
badLdC = "blas: bad leading dimension of C"
|
||||
|
||||
badX = "blas: bad length of x"
|
||||
badY = "blas: bad length of y"
|
||||
)
|
||||
|
||||
// [SD]gemm behavior constants. These are kept here to keep them out of the
|
||||
// way during single precision code genration.
|
||||
const (
|
||||
@@ -61,115 +41,6 @@ func min(a, b int) int {
|
||||
return a
|
||||
}
|
||||
|
||||
func checkSMatrix(name byte, m, n int, a []float32, lda int) {
|
||||
if m < 0 {
|
||||
panic(mLT0)
|
||||
}
|
||||
if n < 0 {
|
||||
panic(nLT0)
|
||||
}
|
||||
if lda < n {
|
||||
panic("blas: illegal stride of " + string(name))
|
||||
}
|
||||
if len(a) < (m-1)*lda+n {
|
||||
panic("blas: index of " + string(name) + " out of range")
|
||||
}
|
||||
}
|
||||
|
||||
func checkDMatrix(name byte, m, n int, a []float64, lda int) {
|
||||
if m < 0 {
|
||||
panic(mLT0)
|
||||
}
|
||||
if n < 0 {
|
||||
panic(nLT0)
|
||||
}
|
||||
if lda < n {
|
||||
panic("blas: illegal stride of " + string(name))
|
||||
}
|
||||
if len(a) < (m-1)*lda+n {
|
||||
panic("blas: index of " + string(name) + " out of range")
|
||||
}
|
||||
}
|
||||
|
||||
func checkZMatrix(name byte, m, n int, a []complex128, lda int) {
|
||||
if m < 0 {
|
||||
panic(mLT0)
|
||||
}
|
||||
if n < 0 {
|
||||
panic(nLT0)
|
||||
}
|
||||
if lda < max(1, n) {
|
||||
panic("blas: illegal stride of " + string(name))
|
||||
}
|
||||
if len(a) < (m-1)*lda+n {
|
||||
panic("blas: insufficient " + string(name) + " matrix slice length")
|
||||
}
|
||||
}
|
||||
|
||||
func checkZBandMatrix(name byte, m, n, kL, kU int, ab []complex128, ldab int) {
|
||||
if m < 0 {
|
||||
panic(mLT0)
|
||||
}
|
||||
if n < 0 {
|
||||
panic(nLT0)
|
||||
}
|
||||
if kL < 0 {
|
||||
panic(kLLT0)
|
||||
}
|
||||
if kU < 0 {
|
||||
panic(kULT0)
|
||||
}
|
||||
if ldab < kL+kU+1 {
|
||||
panic("blas: illegal stride of band matrix " + string(name))
|
||||
}
|
||||
nRow := min(m, n+kL)
|
||||
if len(ab) < (nRow-1)*ldab+kL+1+kU {
|
||||
panic("blas: insufficient " + string(name) + " band matrix slice length")
|
||||
}
|
||||
}
|
||||
|
||||
func checkZhbMatrix(name byte, n, k int, ab []complex128, ldab int) {
|
||||
if n < 0 {
|
||||
panic(nLT0)
|
||||
}
|
||||
if k < 0 {
|
||||
panic(kLT0)
|
||||
}
|
||||
if ldab < k+1 {
|
||||
panic("blas: illegal stride of Hermitian band matrix " + string(name))
|
||||
}
|
||||
if len(ab) < (n-1)*ldab+k+1 {
|
||||
panic("blas: insufficient " + string(name) + " Hermitian band matrix slice length")
|
||||
}
|
||||
}
|
||||
|
||||
func checkZtbMatrix(name byte, n, k int, ab []complex128, ldab int) {
|
||||
if n < 0 {
|
||||
panic(nLT0)
|
||||
}
|
||||
if k < 0 {
|
||||
panic(kLT0)
|
||||
}
|
||||
if ldab < k+1 {
|
||||
panic("blas: illegal stride of triangular band matrix " + string(name))
|
||||
}
|
||||
if len(ab) < (n-1)*ldab+k+1 {
|
||||
panic("blas: insufficient " + string(name) + " triangular band matrix slice length")
|
||||
}
|
||||
}
|
||||
|
||||
func checkZVector(name byte, n int, x []complex128, incX int) {
|
||||
if n < 0 {
|
||||
panic(nLT0)
|
||||
}
|
||||
if incX == 0 {
|
||||
panic(zeroIncX)
|
||||
}
|
||||
if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) {
|
||||
panic("blas: insufficient " + string(name) + " vector slice length")
|
||||
}
|
||||
}
|
||||
|
||||
// blocks returns the number of divisions of the dimension length with the given
|
||||
// block size.
|
||||
func blocks(dim, bsize int) int {
|
||||
@@ -180,3 +51,8 @@ func blocks(dim, bsize int) int {
|
||||
func dcabs1(z complex128) float64 {
|
||||
return math.Abs(real(z)) + math.Abs(imag(z))
|
||||
}
|
||||
|
||||
// scabs1 returns |real(z)|+|imag(z)|.
|
||||
func scabs1(z complex64) float32 {
|
||||
return math32.Abs(real(z)) + math32.Abs(imag(z))
|
||||
}
|
||||
|
||||
43
vendor/gonum.org/v1/gonum/blas/gonum/level1cmplx128.go
generated
vendored
43
vendor/gonum.org/v1/gonum/blas/gonum/level1cmplx128.go
generated
vendored
@@ -7,9 +7,12 @@ package gonum
|
||||
import (
|
||||
"math"
|
||||
|
||||
"gonum.org/v1/gonum/blas"
|
||||
"gonum.org/v1/gonum/internal/asm/c128"
|
||||
)
|
||||
|
||||
var _ blas.Complex128Level1 = Implementation{}
|
||||
|
||||
// Dzasum returns the sum of the absolute values of the elements of x
|
||||
// \sum_i |Re(x[i])| + |Im(x[i])|
|
||||
// Dzasum returns 0 if incX is negative.
|
||||
@@ -26,7 +29,7 @@ func (Implementation) Dzasum(n int, x []complex128, incX int) float64 {
|
||||
var sum float64
|
||||
if incX == 1 {
|
||||
if len(x) < n {
|
||||
panic(badX)
|
||||
panic(shortX)
|
||||
}
|
||||
for _, v := range x[:n] {
|
||||
sum += dcabs1(v)
|
||||
@@ -34,7 +37,7 @@ func (Implementation) Dzasum(n int, x []complex128, incX int) float64 {
|
||||
return sum
|
||||
}
|
||||
if (n-1)*incX >= len(x) {
|
||||
panic(badX)
|
||||
panic(shortX)
|
||||
}
|
||||
for i := 0; i < n; i++ {
|
||||
v := x[i*incX]
|
||||
@@ -60,7 +63,7 @@ func (Implementation) Dznrm2(n int, x []complex128, incX int) float64 {
|
||||
panic(nLT0)
|
||||
}
|
||||
if (n-1)*incX >= len(x) {
|
||||
panic(badX)
|
||||
panic(shortX)
|
||||
}
|
||||
var (
|
||||
scale float64
|
||||
@@ -134,7 +137,7 @@ func (Implementation) Izamax(n int, x []complex128, incX int) int {
|
||||
panic(nLT0)
|
||||
}
|
||||
if len(x) <= (n-1)*incX {
|
||||
panic(badX)
|
||||
panic(shortX)
|
||||
}
|
||||
idx := 0
|
||||
max := dcabs1(x[0])
|
||||
@@ -176,10 +179,10 @@ func (Implementation) Zaxpy(n int, alpha complex128, x []complex128, incX int, y
|
||||
panic(nLT0)
|
||||
}
|
||||
if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) {
|
||||
panic(badX)
|
||||
panic(shortX)
|
||||
}
|
||||
if (incY > 0 && (n-1)*incY >= len(y)) || (incY < 0 && (1-n)*incY >= len(y)) {
|
||||
panic(badY)
|
||||
panic(shortY)
|
||||
}
|
||||
if alpha == 0 {
|
||||
return
|
||||
@@ -213,10 +216,10 @@ func (Implementation) Zcopy(n int, x []complex128, incX int, y []complex128, inc
|
||||
panic(nLT0)
|
||||
}
|
||||
if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) {
|
||||
panic(badX)
|
||||
panic(shortX)
|
||||
}
|
||||
if (incY > 0 && (n-1)*incY >= len(y)) || (incY < 0 && (1-n)*incY >= len(y)) {
|
||||
panic(badY)
|
||||
panic(shortY)
|
||||
}
|
||||
if incX == 1 && incY == 1 {
|
||||
copy(y[:n], x[:n])
|
||||
@@ -254,10 +257,10 @@ func (Implementation) Zdotc(n int, x []complex128, incX int, y []complex128, inc
|
||||
}
|
||||
if incX == 1 && incY == 1 {
|
||||
if len(x) < n {
|
||||
panic(badX)
|
||||
panic(shortX)
|
||||
}
|
||||
if len(y) < n {
|
||||
panic(badY)
|
||||
panic(shortY)
|
||||
}
|
||||
return c128.DotcUnitary(x[:n], y[:n])
|
||||
}
|
||||
@@ -269,10 +272,10 @@ func (Implementation) Zdotc(n int, x []complex128, incX int, y []complex128, inc
|
||||
iy = (-n + 1) * incY
|
||||
}
|
||||
if ix >= len(x) || (n-1)*incX >= len(x) {
|
||||
panic(badX)
|
||||
panic(shortX)
|
||||
}
|
||||
if iy >= len(y) || (n-1)*incY >= len(y) {
|
||||
panic(badY)
|
||||
panic(shortY)
|
||||
}
|
||||
return c128.DotcInc(x, y, uintptr(n), uintptr(incX), uintptr(incY), uintptr(ix), uintptr(iy))
|
||||
}
|
||||
@@ -295,10 +298,10 @@ func (Implementation) Zdotu(n int, x []complex128, incX int, y []complex128, inc
|
||||
}
|
||||
if incX == 1 && incY == 1 {
|
||||
if len(x) < n {
|
||||
panic(badX)
|
||||
panic(shortX)
|
||||
}
|
||||
if len(y) < n {
|
||||
panic(badY)
|
||||
panic(shortY)
|
||||
}
|
||||
return c128.DotuUnitary(x[:n], y[:n])
|
||||
}
|
||||
@@ -310,10 +313,10 @@ func (Implementation) Zdotu(n int, x []complex128, incX int, y []complex128, inc
|
||||
iy = (-n + 1) * incY
|
||||
}
|
||||
if ix >= len(x) || (n-1)*incX >= len(x) {
|
||||
panic(badX)
|
||||
panic(shortX)
|
||||
}
|
||||
if iy >= len(y) || (n-1)*incY >= len(y) {
|
||||
panic(badY)
|
||||
panic(shortY)
|
||||
}
|
||||
return c128.DotuInc(x, y, uintptr(n), uintptr(incX), uintptr(incY), uintptr(ix), uintptr(iy))
|
||||
}
|
||||
@@ -328,7 +331,7 @@ func (Implementation) Zdscal(n int, alpha float64, x []complex128, incX int) {
|
||||
return
|
||||
}
|
||||
if (n-1)*incX >= len(x) {
|
||||
panic(badX)
|
||||
panic(shortX)
|
||||
}
|
||||
if n < 1 {
|
||||
if n == 0 {
|
||||
@@ -372,7 +375,7 @@ func (Implementation) Zscal(n int, alpha complex128, x []complex128, incX int) {
|
||||
return
|
||||
}
|
||||
if (n-1)*incX >= len(x) {
|
||||
panic(badX)
|
||||
panic(shortX)
|
||||
}
|
||||
if n < 1 {
|
||||
if n == 0 {
|
||||
@@ -415,10 +418,10 @@ func (Implementation) Zswap(n int, x []complex128, incX int, y []complex128, inc
|
||||
panic(nLT0)
|
||||
}
|
||||
if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) {
|
||||
panic(badX)
|
||||
panic(shortX)
|
||||
}
|
||||
if (incY > 0 && (n-1)*incY >= len(y)) || (incY < 0 && (1-n)*incY >= len(y)) {
|
||||
panic(badY)
|
||||
panic(shortY)
|
||||
}
|
||||
if incX == 1 && incY == 1 {
|
||||
x = x[:n]
|
||||
|
||||
467
vendor/gonum.org/v1/gonum/blas/gonum/level1cmplx64.go
generated
vendored
Normal file
467
vendor/gonum.org/v1/gonum/blas/gonum/level1cmplx64.go
generated
vendored
Normal file
@@ -0,0 +1,467 @@
|
||||
// Code generated by "go generate gonum.org/v1/gonum/blas/gonum”; DO NOT EDIT.
|
||||
|
||||
// Copyright ©2017 The Gonum Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package gonum
|
||||
|
||||
import (
|
||||
math "gonum.org/v1/gonum/internal/math32"
|
||||
|
||||
"gonum.org/v1/gonum/blas"
|
||||
"gonum.org/v1/gonum/internal/asm/c64"
|
||||
)
|
||||
|
||||
var _ blas.Complex64Level1 = Implementation{}
|
||||
|
||||
// Scasum returns the sum of the absolute values of the elements of x
|
||||
// \sum_i |Re(x[i])| + |Im(x[i])|
|
||||
// Scasum returns 0 if incX is negative.
|
||||
//
|
||||
// Complex64 implementations are autogenerated and not directly tested.
|
||||
func (Implementation) Scasum(n int, x []complex64, incX int) float32 {
|
||||
if n < 0 {
|
||||
panic(nLT0)
|
||||
}
|
||||
if incX < 1 {
|
||||
if incX == 0 {
|
||||
panic(zeroIncX)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
var sum float32
|
||||
if incX == 1 {
|
||||
if len(x) < n {
|
||||
panic(shortX)
|
||||
}
|
||||
for _, v := range x[:n] {
|
||||
sum += scabs1(v)
|
||||
}
|
||||
return sum
|
||||
}
|
||||
if (n-1)*incX >= len(x) {
|
||||
panic(shortX)
|
||||
}
|
||||
for i := 0; i < n; i++ {
|
||||
v := x[i*incX]
|
||||
sum += scabs1(v)
|
||||
}
|
||||
return sum
|
||||
}
|
||||
|
||||
// Scnrm2 computes the Euclidean norm of the complex vector x,
|
||||
// ‖x‖_2 = sqrt(\sum_i x[i] * conj(x[i])).
|
||||
// This function returns 0 if incX is negative.
|
||||
//
|
||||
// Complex64 implementations are autogenerated and not directly tested.
|
||||
func (Implementation) Scnrm2(n int, x []complex64, incX int) float32 {
|
||||
if incX < 1 {
|
||||
if incX == 0 {
|
||||
panic(zeroIncX)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
if n < 1 {
|
||||
if n == 0 {
|
||||
return 0
|
||||
}
|
||||
panic(nLT0)
|
||||
}
|
||||
if (n-1)*incX >= len(x) {
|
||||
panic(shortX)
|
||||
}
|
||||
var (
|
||||
scale float32
|
||||
ssq float32 = 1
|
||||
)
|
||||
if incX == 1 {
|
||||
for _, v := range x[:n] {
|
||||
re, im := math.Abs(real(v)), math.Abs(imag(v))
|
||||
if re != 0 {
|
||||
if re > scale {
|
||||
ssq = 1 + ssq*(scale/re)*(scale/re)
|
||||
scale = re
|
||||
} else {
|
||||
ssq += (re / scale) * (re / scale)
|
||||
}
|
||||
}
|
||||
if im != 0 {
|
||||
if im > scale {
|
||||
ssq = 1 + ssq*(scale/im)*(scale/im)
|
||||
scale = im
|
||||
} else {
|
||||
ssq += (im / scale) * (im / scale)
|
||||
}
|
||||
}
|
||||
}
|
||||
if math.IsInf(scale, 1) {
|
||||
return math.Inf(1)
|
||||
}
|
||||
return scale * math.Sqrt(ssq)
|
||||
}
|
||||
for ix := 0; ix < n*incX; ix += incX {
|
||||
re, im := math.Abs(real(x[ix])), math.Abs(imag(x[ix]))
|
||||
if re != 0 {
|
||||
if re > scale {
|
||||
ssq = 1 + ssq*(scale/re)*(scale/re)
|
||||
scale = re
|
||||
} else {
|
||||
ssq += (re / scale) * (re / scale)
|
||||
}
|
||||
}
|
||||
if im != 0 {
|
||||
if im > scale {
|
||||
ssq = 1 + ssq*(scale/im)*(scale/im)
|
||||
scale = im
|
||||
} else {
|
||||
ssq += (im / scale) * (im / scale)
|
||||
}
|
||||
}
|
||||
}
|
||||
if math.IsInf(scale, 1) {
|
||||
return math.Inf(1)
|
||||
}
|
||||
return scale * math.Sqrt(ssq)
|
||||
}
|
||||
|
||||
// Icamax returns the index of the first element of x having largest |Re(·)|+|Im(·)|.
|
||||
// Icamax returns -1 if n is 0 or incX is negative.
|
||||
//
|
||||
// Complex64 implementations are autogenerated and not directly tested.
|
||||
func (Implementation) Icamax(n int, x []complex64, incX int) int {
|
||||
if incX < 1 {
|
||||
if incX == 0 {
|
||||
panic(zeroIncX)
|
||||
}
|
||||
// Return invalid index.
|
||||
return -1
|
||||
}
|
||||
if n < 1 {
|
||||
if n == 0 {
|
||||
// Return invalid index.
|
||||
return -1
|
||||
}
|
||||
panic(nLT0)
|
||||
}
|
||||
if len(x) <= (n-1)*incX {
|
||||
panic(shortX)
|
||||
}
|
||||
idx := 0
|
||||
max := scabs1(x[0])
|
||||
if incX == 1 {
|
||||
for i, v := range x[1:n] {
|
||||
absV := scabs1(v)
|
||||
if absV > max {
|
||||
max = absV
|
||||
idx = i + 1
|
||||
}
|
||||
}
|
||||
return idx
|
||||
}
|
||||
ix := incX
|
||||
for i := 1; i < n; i++ {
|
||||
absV := scabs1(x[ix])
|
||||
if absV > max {
|
||||
max = absV
|
||||
idx = i
|
||||
}
|
||||
ix += incX
|
||||
}
|
||||
return idx
|
||||
}
|
||||
|
||||
// Caxpy adds alpha times x to y:
|
||||
// y[i] += alpha * x[i] for all i
|
||||
//
|
||||
// Complex64 implementations are autogenerated and not directly tested.
|
||||
func (Implementation) Caxpy(n int, alpha complex64, x []complex64, incX int, y []complex64, incY int) {
|
||||
if incX == 0 {
|
||||
panic(zeroIncX)
|
||||
}
|
||||
if incY == 0 {
|
||||
panic(zeroIncY)
|
||||
}
|
||||
if n < 1 {
|
||||
if n == 0 {
|
||||
return
|
||||
}
|
||||
panic(nLT0)
|
||||
}
|
||||
if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) {
|
||||
panic(shortX)
|
||||
}
|
||||
if (incY > 0 && (n-1)*incY >= len(y)) || (incY < 0 && (1-n)*incY >= len(y)) {
|
||||
panic(shortY)
|
||||
}
|
||||
if alpha == 0 {
|
||||
return
|
||||
}
|
||||
if incX == 1 && incY == 1 {
|
||||
c64.AxpyUnitary(alpha, x[:n], y[:n])
|
||||
return
|
||||
}
|
||||
var ix, iy int
|
||||
if incX < 0 {
|
||||
ix = (1 - n) * incX
|
||||
}
|
||||
if incY < 0 {
|
||||
iy = (1 - n) * incY
|
||||
}
|
||||
c64.AxpyInc(alpha, x, y, uintptr(n), uintptr(incX), uintptr(incY), uintptr(ix), uintptr(iy))
|
||||
}
|
||||
|
||||
// Ccopy copies the vector x to vector y.
|
||||
//
|
||||
// Complex64 implementations are autogenerated and not directly tested.
|
||||
func (Implementation) Ccopy(n int, x []complex64, incX int, y []complex64, incY int) {
|
||||
if incX == 0 {
|
||||
panic(zeroIncX)
|
||||
}
|
||||
if incY == 0 {
|
||||
panic(zeroIncY)
|
||||
}
|
||||
if n < 1 {
|
||||
if n == 0 {
|
||||
return
|
||||
}
|
||||
panic(nLT0)
|
||||
}
|
||||
if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) {
|
||||
panic(shortX)
|
||||
}
|
||||
if (incY > 0 && (n-1)*incY >= len(y)) || (incY < 0 && (1-n)*incY >= len(y)) {
|
||||
panic(shortY)
|
||||
}
|
||||
if incX == 1 && incY == 1 {
|
||||
copy(y[:n], x[:n])
|
||||
return
|
||||
}
|
||||
var ix, iy int
|
||||
if incX < 0 {
|
||||
ix = (-n + 1) * incX
|
||||
}
|
||||
if incY < 0 {
|
||||
iy = (-n + 1) * incY
|
||||
}
|
||||
for i := 0; i < n; i++ {
|
||||
y[iy] = x[ix]
|
||||
ix += incX
|
||||
iy += incY
|
||||
}
|
||||
}
|
||||
|
||||
// Cdotc computes the dot product
|
||||
// x^H · y
|
||||
// of two complex vectors x and y.
|
||||
//
|
||||
// Complex64 implementations are autogenerated and not directly tested.
|
||||
func (Implementation) Cdotc(n int, x []complex64, incX int, y []complex64, incY int) complex64 {
|
||||
if incX == 0 {
|
||||
panic(zeroIncX)
|
||||
}
|
||||
if incY == 0 {
|
||||
panic(zeroIncY)
|
||||
}
|
||||
if n <= 0 {
|
||||
if n == 0 {
|
||||
return 0
|
||||
}
|
||||
panic(nLT0)
|
||||
}
|
||||
if incX == 1 && incY == 1 {
|
||||
if len(x) < n {
|
||||
panic(shortX)
|
||||
}
|
||||
if len(y) < n {
|
||||
panic(shortY)
|
||||
}
|
||||
return c64.DotcUnitary(x[:n], y[:n])
|
||||
}
|
||||
var ix, iy int
|
||||
if incX < 0 {
|
||||
ix = (-n + 1) * incX
|
||||
}
|
||||
if incY < 0 {
|
||||
iy = (-n + 1) * incY
|
||||
}
|
||||
if ix >= len(x) || (n-1)*incX >= len(x) {
|
||||
panic(shortX)
|
||||
}
|
||||
if iy >= len(y) || (n-1)*incY >= len(y) {
|
||||
panic(shortY)
|
||||
}
|
||||
return c64.DotcInc(x, y, uintptr(n), uintptr(incX), uintptr(incY), uintptr(ix), uintptr(iy))
|
||||
}
|
||||
|
||||
// Cdotu computes the dot product
|
||||
// x^T · y
|
||||
// of two complex vectors x and y.
|
||||
//
|
||||
// Complex64 implementations are autogenerated and not directly tested.
|
||||
func (Implementation) Cdotu(n int, x []complex64, incX int, y []complex64, incY int) complex64 {
|
||||
if incX == 0 {
|
||||
panic(zeroIncX)
|
||||
}
|
||||
if incY == 0 {
|
||||
panic(zeroIncY)
|
||||
}
|
||||
if n <= 0 {
|
||||
if n == 0 {
|
||||
return 0
|
||||
}
|
||||
panic(nLT0)
|
||||
}
|
||||
if incX == 1 && incY == 1 {
|
||||
if len(x) < n {
|
||||
panic(shortX)
|
||||
}
|
||||
if len(y) < n {
|
||||
panic(shortY)
|
||||
}
|
||||
return c64.DotuUnitary(x[:n], y[:n])
|
||||
}
|
||||
var ix, iy int
|
||||
if incX < 0 {
|
||||
ix = (-n + 1) * incX
|
||||
}
|
||||
if incY < 0 {
|
||||
iy = (-n + 1) * incY
|
||||
}
|
||||
if ix >= len(x) || (n-1)*incX >= len(x) {
|
||||
panic(shortX)
|
||||
}
|
||||
if iy >= len(y) || (n-1)*incY >= len(y) {
|
||||
panic(shortY)
|
||||
}
|
||||
return c64.DotuInc(x, y, uintptr(n), uintptr(incX), uintptr(incY), uintptr(ix), uintptr(iy))
|
||||
}
|
||||
|
||||
// Csscal scales the vector x by a real scalar alpha.
|
||||
// Csscal has no effect if incX < 0.
|
||||
//
|
||||
// Complex64 implementations are autogenerated and not directly tested.
|
||||
func (Implementation) Csscal(n int, alpha float32, x []complex64, incX int) {
|
||||
if incX < 1 {
|
||||
if incX == 0 {
|
||||
panic(zeroIncX)
|
||||
}
|
||||
return
|
||||
}
|
||||
if (n-1)*incX >= len(x) {
|
||||
panic(shortX)
|
||||
}
|
||||
if n < 1 {
|
||||
if n == 0 {
|
||||
return
|
||||
}
|
||||
panic(nLT0)
|
||||
}
|
||||
if alpha == 0 {
|
||||
if incX == 1 {
|
||||
x = x[:n]
|
||||
for i := range x {
|
||||
x[i] = 0
|
||||
}
|
||||
return
|
||||
}
|
||||
for ix := 0; ix < n*incX; ix += incX {
|
||||
x[ix] = 0
|
||||
}
|
||||
return
|
||||
}
|
||||
if incX == 1 {
|
||||
x = x[:n]
|
||||
for i, v := range x {
|
||||
x[i] = complex(alpha*real(v), alpha*imag(v))
|
||||
}
|
||||
return
|
||||
}
|
||||
for ix := 0; ix < n*incX; ix += incX {
|
||||
v := x[ix]
|
||||
x[ix] = complex(alpha*real(v), alpha*imag(v))
|
||||
}
|
||||
}
|
||||
|
||||
// Cscal scales the vector x by a complex scalar alpha.
|
||||
// Cscal has no effect if incX < 0.
|
||||
//
|
||||
// Complex64 implementations are autogenerated and not directly tested.
|
||||
func (Implementation) Cscal(n int, alpha complex64, x []complex64, incX int) {
|
||||
if incX < 1 {
|
||||
if incX == 0 {
|
||||
panic(zeroIncX)
|
||||
}
|
||||
return
|
||||
}
|
||||
if (n-1)*incX >= len(x) {
|
||||
panic(shortX)
|
||||
}
|
||||
if n < 1 {
|
||||
if n == 0 {
|
||||
return
|
||||
}
|
||||
panic(nLT0)
|
||||
}
|
||||
if alpha == 0 {
|
||||
if incX == 1 {
|
||||
x = x[:n]
|
||||
for i := range x {
|
||||
x[i] = 0
|
||||
}
|
||||
return
|
||||
}
|
||||
for ix := 0; ix < n*incX; ix += incX {
|
||||
x[ix] = 0
|
||||
}
|
||||
return
|
||||
}
|
||||
if incX == 1 {
|
||||
c64.ScalUnitary(alpha, x[:n])
|
||||
return
|
||||
}
|
||||
c64.ScalInc(alpha, x, uintptr(n), uintptr(incX))
|
||||
}
|
||||
|
||||
// Cswap exchanges the elements of two complex vectors x and y.
|
||||
//
|
||||
// Complex64 implementations are autogenerated and not directly tested.
|
||||
func (Implementation) Cswap(n int, x []complex64, incX int, y []complex64, incY int) {
|
||||
if incX == 0 {
|
||||
panic(zeroIncX)
|
||||
}
|
||||
if incY == 0 {
|
||||
panic(zeroIncY)
|
||||
}
|
||||
if n < 1 {
|
||||
if n == 0 {
|
||||
return
|
||||
}
|
||||
panic(nLT0)
|
||||
}
|
||||
if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) {
|
||||
panic(shortX)
|
||||
}
|
||||
if (incY > 0 && (n-1)*incY >= len(y)) || (incY < 0 && (1-n)*incY >= len(y)) {
|
||||
panic(shortY)
|
||||
}
|
||||
if incX == 1 && incY == 1 {
|
||||
x = x[:n]
|
||||
for i, v := range x {
|
||||
x[i], y[i] = y[i], v
|
||||
}
|
||||
return
|
||||
}
|
||||
var ix, iy int
|
||||
if incX < 0 {
|
||||
ix = (-n + 1) * incX
|
||||
}
|
||||
if incY < 0 {
|
||||
iy = (-n + 1) * incY
|
||||
}
|
||||
for i := 0; i < n; i++ {
|
||||
x[ix], y[iy] = y[iy], x[ix]
|
||||
ix += incX
|
||||
iy += incY
|
||||
}
|
||||
}
|
||||
@@ -27,8 +27,8 @@ func (Implementation) Snrm2(n int, x []float32, incX int) float32 {
|
||||
}
|
||||
return 0
|
||||
}
|
||||
if incX > 0 && (n-1)*incX >= len(x) {
|
||||
panic(badX)
|
||||
if len(x) <= (n-1)*incX {
|
||||
panic(shortX)
|
||||
}
|
||||
if n < 2 {
|
||||
if n == 1 {
|
||||
@@ -103,8 +103,8 @@ func (Implementation) Sasum(n int, x []float32, incX int) float32 {
|
||||
}
|
||||
return 0
|
||||
}
|
||||
if incX > 0 && (n-1)*incX >= len(x) {
|
||||
panic(badX)
|
||||
if len(x) <= (n-1)*incX {
|
||||
panic(shortX)
|
||||
}
|
||||
if incX == 1 {
|
||||
x = x[:n]
|
||||
@@ -131,15 +131,15 @@ func (Implementation) Isamax(n int, x []float32, incX int) int {
|
||||
}
|
||||
return -1
|
||||
}
|
||||
if incX > 0 && (n-1)*incX >= len(x) {
|
||||
panic(badX)
|
||||
if len(x) <= (n-1)*incX {
|
||||
panic(shortX)
|
||||
}
|
||||
if n < 2 {
|
||||
if n == 1 {
|
||||
return 0
|
||||
}
|
||||
if n == 0 {
|
||||
return -1 // Netlib returns invalid index when n == 0
|
||||
return -1 // Netlib returns invalid index when n == 0.
|
||||
}
|
||||
panic(nLT0)
|
||||
}
|
||||
@@ -185,11 +185,11 @@ func (Implementation) Sswap(n int, x []float32, incX int, y []float32, incY int)
|
||||
}
|
||||
panic(nLT0)
|
||||
}
|
||||
if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) {
|
||||
panic(badX)
|
||||
if (incX > 0 && len(x) <= (n-1)*incX) || (incX < 0 && len(x) <= (1-n)*incX) {
|
||||
panic(shortX)
|
||||
}
|
||||
if (incY > 0 && (n-1)*incY >= len(y)) || (incY < 0 && (1-n)*incY >= len(y)) {
|
||||
panic(badY)
|
||||
if (incY > 0 && len(y) <= (n-1)*incY) || (incY < 0 && len(y) <= (1-n)*incY) {
|
||||
panic(shortY)
|
||||
}
|
||||
if incX == 1 && incY == 1 {
|
||||
x = x[:n]
|
||||
@@ -229,11 +229,11 @@ func (Implementation) Scopy(n int, x []float32, incX int, y []float32, incY int)
|
||||
}
|
||||
panic(nLT0)
|
||||
}
|
||||
if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) {
|
||||
panic(badX)
|
||||
if (incX > 0 && len(x) <= (n-1)*incX) || (incX < 0 && len(x) <= (1-n)*incX) {
|
||||
panic(shortX)
|
||||
}
|
||||
if (incY > 0 && (n-1)*incY >= len(y)) || (incY < 0 && (1-n)*incY >= len(y)) {
|
||||
panic(badY)
|
||||
if (incY > 0 && len(y) <= (n-1)*incY) || (incY < 0 && len(y) <= (1-n)*incY) {
|
||||
panic(shortY)
|
||||
}
|
||||
if incX == 1 && incY == 1 {
|
||||
copy(y[:n], x[:n])
|
||||
@@ -270,11 +270,11 @@ func (Implementation) Saxpy(n int, alpha float32, x []float32, incX int, y []flo
|
||||
}
|
||||
panic(nLT0)
|
||||
}
|
||||
if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) {
|
||||
panic(badX)
|
||||
if (incX > 0 && len(x) <= (n-1)*incX) || (incX < 0 && len(x) <= (1-n)*incX) {
|
||||
panic(shortX)
|
||||
}
|
||||
if (incY > 0 && (n-1)*incY >= len(y)) || (incY < 0 && (1-n)*incY >= len(y)) {
|
||||
panic(badY)
|
||||
if (incY > 0 && len(y) <= (n-1)*incY) || (incY < 0 && len(y) <= (1-n)*incY) {
|
||||
panic(shortY)
|
||||
}
|
||||
if alpha == 0 {
|
||||
return
|
||||
@@ -303,7 +303,7 @@ func (Implementation) Saxpy(n int, alpha float32, x []float32, incX int, y []flo
|
||||
// c = a/r, the cosine of the plane rotation
|
||||
// s = b/r, the sine of the plane rotation
|
||||
//
|
||||
// NOTE: There is a discrepancy between the refence implementation and the BLAS
|
||||
// NOTE: There is a discrepancy between the reference implementation and the BLAS
|
||||
// technical manual regarding the sign for r when a or b are zero.
|
||||
// Srotg agrees with the definition in the manual and other
|
||||
// common BLAS implementations.
|
||||
@@ -440,7 +440,7 @@ func (Implementation) Srotmg(d1, d2, x1, y1 float32) (p blas.SrotmParams, rd1, r
|
||||
case blas.Rescaling:
|
||||
p.H = [4]float32{h11, h21, h12, h22}
|
||||
default:
|
||||
panic("blas: unexpected blas.Flag")
|
||||
panic(badFlag)
|
||||
}
|
||||
|
||||
return p, d1, d2, x1
|
||||
@@ -464,11 +464,11 @@ func (Implementation) Srot(n int, x []float32, incX int, y []float32, incY int,
|
||||
}
|
||||
panic(nLT0)
|
||||
}
|
||||
if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) {
|
||||
panic(badX)
|
||||
if (incX > 0 && len(x) <= (n-1)*incX) || (incX < 0 && len(x) <= (1-n)*incX) {
|
||||
panic(shortX)
|
||||
}
|
||||
if (incY > 0 && (n-1)*incY >= len(y)) || (incY < 0 && (1-n)*incY >= len(y)) {
|
||||
panic(badY)
|
||||
if (incY > 0 && len(y) <= (n-1)*incY) || (incY < 0 && len(y) <= (1-n)*incY) {
|
||||
panic(shortY)
|
||||
}
|
||||
if incX == 1 && incY == 1 {
|
||||
x = x[:n]
|
||||
@@ -510,11 +510,11 @@ func (Implementation) Srotm(n int, x []float32, incX int, y []float32, incY int,
|
||||
}
|
||||
panic(nLT0)
|
||||
}
|
||||
if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) {
|
||||
panic(badX)
|
||||
if (incX > 0 && len(x) <= (n-1)*incX) || (incX < 0 && len(x) <= (1-n)*incX) {
|
||||
panic(shortX)
|
||||
}
|
||||
if (incY > 0 && (n-1)*incY >= len(y)) || (incY < 0 && (1-n)*incY >= len(y)) {
|
||||
panic(badY)
|
||||
if (incY > 0 && len(y) <= (n-1)*incY) || (incY < 0 && len(y) <= (1-n)*incY) {
|
||||
panic(shortY)
|
||||
}
|
||||
|
||||
if p.Flag == blas.Identity {
|
||||
@@ -614,15 +614,15 @@ func (Implementation) Sscal(n int, alpha float32, x []float32, incX int) {
|
||||
}
|
||||
return
|
||||
}
|
||||
if (n-1)*incX >= len(x) {
|
||||
panic(badX)
|
||||
}
|
||||
if n < 1 {
|
||||
if n == 0 {
|
||||
return
|
||||
}
|
||||
panic(nLT0)
|
||||
}
|
||||
if (n-1)*incX >= len(x) {
|
||||
panic(shortX)
|
||||
}
|
||||
if alpha == 0 {
|
||||
if incX == 1 {
|
||||
x = x[:n]
|
||||
@@ -29,12 +29,12 @@ func (Implementation) Dsdot(n int, x []float32, incX int, y []float32, incY int)
|
||||
}
|
||||
if incX == 1 && incY == 1 {
|
||||
if len(x) < n {
|
||||
panic(badX)
|
||||
panic(shortX)
|
||||
}
|
||||
if len(y) < n {
|
||||
panic(badY)
|
||||
panic(shortY)
|
||||
}
|
||||
return f32.DdotUnitary(x[:n], y)
|
||||
return f32.DdotUnitary(x[:n], y[:n])
|
||||
}
|
||||
var ix, iy int
|
||||
if incX < 0 {
|
||||
@@ -44,10 +44,10 @@ func (Implementation) Dsdot(n int, x []float32, incX int, y []float32, incY int)
|
||||
iy = (-n + 1) * incY
|
||||
}
|
||||
if ix >= len(x) || ix+(n-1)*incX >= len(x) {
|
||||
panic(badX)
|
||||
panic(shortX)
|
||||
}
|
||||
if iy >= len(y) || iy+(n-1)*incY >= len(y) {
|
||||
panic(badY)
|
||||
panic(shortY)
|
||||
}
|
||||
return f32.DdotInc(x, y, uintptr(n), uintptr(incX), uintptr(incY), uintptr(ix), uintptr(iy))
|
||||
}
|
||||
@@ -29,12 +29,12 @@ func (Implementation) Sdot(n int, x []float32, incX int, y []float32, incY int)
|
||||
}
|
||||
if incX == 1 && incY == 1 {
|
||||
if len(x) < n {
|
||||
panic(badX)
|
||||
panic(shortX)
|
||||
}
|
||||
if len(y) < n {
|
||||
panic(badY)
|
||||
panic(shortY)
|
||||
}
|
||||
return f32.DotUnitary(x[:n], y)
|
||||
return f32.DotUnitary(x[:n], y[:n])
|
||||
}
|
||||
var ix, iy int
|
||||
if incX < 0 {
|
||||
@@ -44,10 +44,10 @@ func (Implementation) Sdot(n int, x []float32, incX int, y []float32, incY int)
|
||||
iy = (-n + 1) * incY
|
||||
}
|
||||
if ix >= len(x) || ix+(n-1)*incX >= len(x) {
|
||||
panic(badX)
|
||||
panic(shortX)
|
||||
}
|
||||
if iy >= len(y) || iy+(n-1)*incY >= len(y) {
|
||||
panic(badY)
|
||||
panic(shortY)
|
||||
}
|
||||
return f32.DotInc(x, y, uintptr(n), uintptr(incX), uintptr(incY), uintptr(ix), uintptr(iy))
|
||||
}
|
||||
@@ -29,12 +29,12 @@ func (Implementation) Sdsdot(n int, alpha float32, x []float32, incX int, y []fl
|
||||
}
|
||||
if incX == 1 && incY == 1 {
|
||||
if len(x) < n {
|
||||
panic(badX)
|
||||
panic(shortX)
|
||||
}
|
||||
if len(y) < n {
|
||||
panic(badY)
|
||||
panic(shortY)
|
||||
}
|
||||
return alpha + float32(f32.DdotUnitary(x[:n], y))
|
||||
return alpha + float32(f32.DdotUnitary(x[:n], y[:n]))
|
||||
}
|
||||
var ix, iy int
|
||||
if incX < 0 {
|
||||
@@ -44,10 +44,10 @@ func (Implementation) Sdsdot(n int, alpha float32, x []float32, incX int, y []fl
|
||||
iy = (-n + 1) * incY
|
||||
}
|
||||
if ix >= len(x) || ix+(n-1)*incX >= len(x) {
|
||||
panic(badX)
|
||||
panic(shortX)
|
||||
}
|
||||
if iy >= len(y) || iy+(n-1)*incY >= len(y) {
|
||||
panic(badY)
|
||||
panic(shortY)
|
||||
}
|
||||
return alpha + float32(f32.DdotInc(x, y, uintptr(n), uintptr(incX), uintptr(incY), uintptr(ix), uintptr(iy)))
|
||||
}
|
||||
@@ -23,8 +23,8 @@ func (Implementation) Dnrm2(n int, x []float64, incX int) float64 {
|
||||
}
|
||||
return 0
|
||||
}
|
||||
if incX > 0 && (n-1)*incX >= len(x) {
|
||||
panic(badX)
|
||||
if len(x) <= (n-1)*incX {
|
||||
panic(shortX)
|
||||
}
|
||||
if n < 2 {
|
||||
if n == 1 {
|
||||
@@ -97,8 +97,8 @@ func (Implementation) Dasum(n int, x []float64, incX int) float64 {
|
||||
}
|
||||
return 0
|
||||
}
|
||||
if incX > 0 && (n-1)*incX >= len(x) {
|
||||
panic(badX)
|
||||
if len(x) <= (n-1)*incX {
|
||||
panic(shortX)
|
||||
}
|
||||
if incX == 1 {
|
||||
x = x[:n]
|
||||
@@ -123,15 +123,15 @@ func (Implementation) Idamax(n int, x []float64, incX int) int {
|
||||
}
|
||||
return -1
|
||||
}
|
||||
if incX > 0 && (n-1)*incX >= len(x) {
|
||||
panic(badX)
|
||||
if len(x) <= (n-1)*incX {
|
||||
panic(shortX)
|
||||
}
|
||||
if n < 2 {
|
||||
if n == 1 {
|
||||
return 0
|
||||
}
|
||||
if n == 0 {
|
||||
return -1 // Netlib returns invalid index when n == 0
|
||||
return -1 // Netlib returns invalid index when n == 0.
|
||||
}
|
||||
panic(nLT0)
|
||||
}
|
||||
@@ -175,11 +175,11 @@ func (Implementation) Dswap(n int, x []float64, incX int, y []float64, incY int)
|
||||
}
|
||||
panic(nLT0)
|
||||
}
|
||||
if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) {
|
||||
panic(badX)
|
||||
if (incX > 0 && len(x) <= (n-1)*incX) || (incX < 0 && len(x) <= (1-n)*incX) {
|
||||
panic(shortX)
|
||||
}
|
||||
if (incY > 0 && (n-1)*incY >= len(y)) || (incY < 0 && (1-n)*incY >= len(y)) {
|
||||
panic(badY)
|
||||
if (incY > 0 && len(y) <= (n-1)*incY) || (incY < 0 && len(y) <= (1-n)*incY) {
|
||||
panic(shortY)
|
||||
}
|
||||
if incX == 1 && incY == 1 {
|
||||
x = x[:n]
|
||||
@@ -217,11 +217,11 @@ func (Implementation) Dcopy(n int, x []float64, incX int, y []float64, incY int)
|
||||
}
|
||||
panic(nLT0)
|
||||
}
|
||||
if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) {
|
||||
panic(badX)
|
||||
if (incX > 0 && len(x) <= (n-1)*incX) || (incX < 0 && len(x) <= (1-n)*incX) {
|
||||
panic(shortX)
|
||||
}
|
||||
if (incY > 0 && (n-1)*incY >= len(y)) || (incY < 0 && (1-n)*incY >= len(y)) {
|
||||
panic(badY)
|
||||
if (incY > 0 && len(y) <= (n-1)*incY) || (incY < 0 && len(y) <= (1-n)*incY) {
|
||||
panic(shortY)
|
||||
}
|
||||
if incX == 1 && incY == 1 {
|
||||
copy(y[:n], x[:n])
|
||||
@@ -256,11 +256,11 @@ func (Implementation) Daxpy(n int, alpha float64, x []float64, incX int, y []flo
|
||||
}
|
||||
panic(nLT0)
|
||||
}
|
||||
if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) {
|
||||
panic(badX)
|
||||
if (incX > 0 && len(x) <= (n-1)*incX) || (incX < 0 && len(x) <= (1-n)*incX) {
|
||||
panic(shortX)
|
||||
}
|
||||
if (incY > 0 && (n-1)*incY >= len(y)) || (incY < 0 && (1-n)*incY >= len(y)) {
|
||||
panic(badY)
|
||||
if (incY > 0 && len(y) <= (n-1)*incY) || (incY < 0 && len(y) <= (1-n)*incY) {
|
||||
panic(shortY)
|
||||
}
|
||||
if alpha == 0 {
|
||||
return
|
||||
@@ -289,7 +289,7 @@ func (Implementation) Daxpy(n int, alpha float64, x []float64, incX int, y []flo
|
||||
// c = a/r, the cosine of the plane rotation
|
||||
// s = b/r, the sine of the plane rotation
|
||||
//
|
||||
// NOTE: There is a discrepancy between the refence implementation and the BLAS
|
||||
// NOTE: There is a discrepancy between the reference implementation and the BLAS
|
||||
// technical manual regarding the sign for r when a or b are zero.
|
||||
// Drotg agrees with the definition in the manual and other
|
||||
// common BLAS implementations.
|
||||
@@ -422,7 +422,7 @@ func (Implementation) Drotmg(d1, d2, x1, y1 float64) (p blas.DrotmParams, rd1, r
|
||||
case blas.Rescaling:
|
||||
p.H = [4]float64{h11, h21, h12, h22}
|
||||
default:
|
||||
panic("blas: unexpected blas.Flag")
|
||||
panic(badFlag)
|
||||
}
|
||||
|
||||
return p, d1, d2, x1
|
||||
@@ -444,11 +444,11 @@ func (Implementation) Drot(n int, x []float64, incX int, y []float64, incY int,
|
||||
}
|
||||
panic(nLT0)
|
||||
}
|
||||
if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) {
|
||||
panic(badX)
|
||||
if (incX > 0 && len(x) <= (n-1)*incX) || (incX < 0 && len(x) <= (1-n)*incX) {
|
||||
panic(shortX)
|
||||
}
|
||||
if (incY > 0 && (n-1)*incY >= len(y)) || (incY < 0 && (1-n)*incY >= len(y)) {
|
||||
panic(badY)
|
||||
if (incY > 0 && len(y) <= (n-1)*incY) || (incY < 0 && len(y) <= (1-n)*incY) {
|
||||
panic(shortY)
|
||||
}
|
||||
if incX == 1 && incY == 1 {
|
||||
x = x[:n]
|
||||
@@ -488,11 +488,11 @@ func (Implementation) Drotm(n int, x []float64, incX int, y []float64, incY int,
|
||||
}
|
||||
panic(nLT0)
|
||||
}
|
||||
if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) {
|
||||
panic(badX)
|
||||
if (incX > 0 && len(x) <= (n-1)*incX) || (incX < 0 && len(x) <= (1-n)*incX) {
|
||||
panic(shortX)
|
||||
}
|
||||
if (incY > 0 && (n-1)*incY >= len(y)) || (incY < 0 && (1-n)*incY >= len(y)) {
|
||||
panic(badY)
|
||||
if (incY > 0 && len(y) <= (n-1)*incY) || (incY < 0 && len(y) <= (1-n)*incY) {
|
||||
panic(shortY)
|
||||
}
|
||||
|
||||
if p.Flag == blas.Identity {
|
||||
@@ -590,15 +590,15 @@ func (Implementation) Dscal(n int, alpha float64, x []float64, incX int) {
|
||||
}
|
||||
return
|
||||
}
|
||||
if (n-1)*incX >= len(x) {
|
||||
panic(badX)
|
||||
}
|
||||
if n < 1 {
|
||||
if n == 0 {
|
||||
return
|
||||
}
|
||||
panic(nLT0)
|
||||
}
|
||||
if (n-1)*incX >= len(x) {
|
||||
panic(shortX)
|
||||
}
|
||||
if alpha == 0 {
|
||||
if incX == 1 {
|
||||
x = x[:n]
|
||||
@@ -25,12 +25,12 @@ func (Implementation) Ddot(n int, x []float64, incX int, y []float64, incY int)
|
||||
}
|
||||
if incX == 1 && incY == 1 {
|
||||
if len(x) < n {
|
||||
panic(badX)
|
||||
panic(shortX)
|
||||
}
|
||||
if len(y) < n {
|
||||
panic(badY)
|
||||
panic(shortY)
|
||||
}
|
||||
return f64.DotUnitary(x[:n], y)
|
||||
return f64.DotUnitary(x[:n], y[:n])
|
||||
}
|
||||
var ix, iy int
|
||||
if incX < 0 {
|
||||
@@ -40,10 +40,10 @@ func (Implementation) Ddot(n int, x []float64, incX int, y []float64, incY int)
|
||||
iy = (-n + 1) * incY
|
||||
}
|
||||
if ix >= len(x) || ix+(n-1)*incX >= len(x) {
|
||||
panic(badX)
|
||||
panic(shortX)
|
||||
}
|
||||
if iy >= len(y) || iy+(n-1)*incY >= len(y) {
|
||||
panic(badY)
|
||||
panic(shortY)
|
||||
}
|
||||
return f64.DotInc(x, y, uintptr(n), uintptr(incX), uintptr(incY), uintptr(ix), uintptr(iy))
|
||||
}
|
||||
753
vendor/gonum.org/v1/gonum/blas/gonum/level2cmplx128.go
generated
vendored
753
vendor/gonum.org/v1/gonum/blas/gonum/level2cmplx128.go
generated
vendored
File diff suppressed because it is too large
Load Diff
2942
vendor/gonum.org/v1/gonum/blas/gonum/level2cmplx64.go
generated
vendored
Normal file
2942
vendor/gonum.org/v1/gonum/blas/gonum/level2cmplx64.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
@@ -19,34 +19,40 @@ var _ blas.Float32Level2 = Implementation{}
|
||||
//
|
||||
// Float32 implementations are autogenerated and not directly tested.
|
||||
func (Implementation) Sger(m, n int, alpha float32, x []float32, incX int, y []float32, incY int, a []float32, lda int) {
|
||||
// Check inputs
|
||||
if m < 0 {
|
||||
panic("m < 0")
|
||||
panic(mLT0)
|
||||
}
|
||||
if n < 0 {
|
||||
panic(nLT0)
|
||||
}
|
||||
if lda < max(1, n) {
|
||||
panic(badLdA)
|
||||
}
|
||||
if incX == 0 {
|
||||
panic(zeroIncX)
|
||||
}
|
||||
if incY == 0 {
|
||||
panic(zeroIncY)
|
||||
}
|
||||
if (incX > 0 && (m-1)*incX >= len(x)) || (incX < 0 && (1-m)*incX >= len(x)) {
|
||||
panic(badX)
|
||||
}
|
||||
if (incY > 0 && (n-1)*incY >= len(y)) || (incY < 0 && (1-n)*incY >= len(y)) {
|
||||
panic(badY)
|
||||
}
|
||||
if lda*(m-1)+n > len(a) || lda < max(1, n) {
|
||||
panic(badLdA)
|
||||
}
|
||||
if lda < max(1, n) {
|
||||
panic(badLdA)
|
||||
|
||||
// Quick return if possible.
|
||||
if m == 0 || n == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// Quick return if possible
|
||||
if m == 0 || n == 0 || alpha == 0 {
|
||||
// For zero matrix size the following slice length checks are trivially satisfied.
|
||||
if (incX > 0 && len(x) <= (m-1)*incX) || (incX < 0 && len(x) <= (1-m)*incX) {
|
||||
panic(shortX)
|
||||
}
|
||||
if (incY > 0 && len(y) <= (n-1)*incY) || (incY < 0 && len(y) <= (1-n)*incY) {
|
||||
panic(shortY)
|
||||
}
|
||||
if len(a) < lda*(m-1)+n {
|
||||
panic(shortA)
|
||||
}
|
||||
|
||||
// Quick return if possible.
|
||||
if alpha == 0 {
|
||||
return
|
||||
}
|
||||
f32.Ger(uintptr(m), uintptr(n),
|
||||
@@ -76,7 +82,7 @@ func (Implementation) Sgbmv(tA blas.Transpose, m, n, kL, kU int, alpha float32,
|
||||
if kL < 0 {
|
||||
panic(kLLT0)
|
||||
}
|
||||
if kL < 0 {
|
||||
if kU < 0 {
|
||||
panic(kULT0)
|
||||
}
|
||||
if lda < kL+kU+1 {
|
||||
@@ -88,25 +94,31 @@ func (Implementation) Sgbmv(tA blas.Transpose, m, n, kL, kU int, alpha float32,
|
||||
if incY == 0 {
|
||||
panic(zeroIncY)
|
||||
}
|
||||
// Set up indexes
|
||||
|
||||
// Quick return if possible.
|
||||
if m == 0 || n == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// For zero matrix size the following slice length checks are trivially satisfied.
|
||||
if len(a) < lda*(min(m, n+kL)-1)+kL+kU+1 {
|
||||
panic(shortA)
|
||||
}
|
||||
lenX := m
|
||||
lenY := n
|
||||
if tA == blas.NoTrans {
|
||||
lenX = n
|
||||
lenY = m
|
||||
}
|
||||
if (incX > 0 && (lenX-1)*incX >= len(x)) || (incX < 0 && (1-lenX)*incX >= len(x)) {
|
||||
panic(badX)
|
||||
if (incX > 0 && len(x) <= (lenX-1)*incX) || (incX < 0 && len(x) <= (1-lenX)*incX) {
|
||||
panic(shortX)
|
||||
}
|
||||
if (incY > 0 && (lenY-1)*incY >= len(y)) || (incY < 0 && (1-lenY)*incY >= len(y)) {
|
||||
panic(badY)
|
||||
}
|
||||
if lda*(min(m, n+kL)-1)+kL+kU+1 > len(a) || lda < kL+kU+1 {
|
||||
panic(badLdA)
|
||||
if (incY > 0 && len(y) <= (lenY-1)*incY) || (incY < 0 && len(y) <= (1-lenY)*incY) {
|
||||
panic(shortY)
|
||||
}
|
||||
|
||||
// Quick return if possible
|
||||
if m == 0 || n == 0 || (alpha == 0 && beta == 1) {
|
||||
// Quick return if possible.
|
||||
if alpha == 0 && beta == 1 {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -118,11 +130,31 @@ func (Implementation) Sgbmv(tA blas.Transpose, m, n, kL, kU int, alpha float32,
|
||||
ky = -(lenY - 1) * incY
|
||||
}
|
||||
|
||||
// First form y = beta * y
|
||||
if incY > 0 {
|
||||
Implementation{}.Sscal(lenY, beta, y, incY)
|
||||
} else {
|
||||
Implementation{}.Sscal(lenY, beta, y, -incY)
|
||||
// Form y = beta * y.
|
||||
if beta != 1 {
|
||||
if incY == 1 {
|
||||
if beta == 0 {
|
||||
for i := range y[:lenY] {
|
||||
y[i] = 0
|
||||
}
|
||||
} else {
|
||||
f32.ScalUnitary(beta, y[:lenY])
|
||||
}
|
||||
} else {
|
||||
iy := ky
|
||||
if beta == 0 {
|
||||
for i := 0; i < lenY; i++ {
|
||||
y[iy] = 0
|
||||
iy += incY
|
||||
}
|
||||
} else {
|
||||
if incY > 0 {
|
||||
f32.ScalInc(beta, y, uintptr(lenY), uintptr(incY))
|
||||
} else {
|
||||
f32.ScalInc(beta, y, uintptr(lenY), uintptr(-incY))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if alpha == 0 {
|
||||
@@ -216,21 +248,26 @@ func (Implementation) Strmv(ul blas.Uplo, tA blas.Transpose, d blas.Diag, n int,
|
||||
if n < 0 {
|
||||
panic(nLT0)
|
||||
}
|
||||
if lda < n {
|
||||
if lda < max(1, n) {
|
||||
panic(badLdA)
|
||||
}
|
||||
if incX == 0 {
|
||||
panic(zeroIncX)
|
||||
}
|
||||
if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) {
|
||||
panic(badX)
|
||||
}
|
||||
if lda*(n-1)+n > len(a) || lda < max(1, n) {
|
||||
panic(badLdA)
|
||||
}
|
||||
|
||||
// Quick return if possible.
|
||||
if n == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// For zero matrix size the following slice length checks are trivially satisfied.
|
||||
if len(a) < lda*(n-1)+n {
|
||||
panic(shortA)
|
||||
}
|
||||
if (incX > 0 && len(x) <= (n-1)*incX) || (incX < 0 && len(x) <= (1-n)*incX) {
|
||||
panic(shortX)
|
||||
}
|
||||
|
||||
nonUnit := d != blas.Unit
|
||||
if n == 1 {
|
||||
if nonUnit {
|
||||
@@ -253,8 +290,7 @@ func (Implementation) Strmv(ul blas.Uplo, tA blas.Transpose, d blas.Diag, n int,
|
||||
} else {
|
||||
tmp = x[i]
|
||||
}
|
||||
xtmp := x[i+1:]
|
||||
x[i] = tmp + f32.DotUnitary(a[ilda+i+1:ilda+n], xtmp)
|
||||
x[i] = tmp + f32.DotUnitary(a[ilda+i+1:ilda+n], x[i+1:n])
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -281,7 +317,7 @@ func (Implementation) Strmv(ul blas.Uplo, tA blas.Transpose, d blas.Diag, n int,
|
||||
} else {
|
||||
tmp = x[i]
|
||||
}
|
||||
x[i] = tmp + f32.DotUnitary(a[ilda:ilda+i], x)
|
||||
x[i] = tmp + f32.DotUnitary(a[ilda:ilda+i], x[:i])
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -328,7 +364,7 @@ func (Implementation) Strmv(ul blas.Uplo, tA blas.Transpose, d blas.Diag, n int,
|
||||
for i := 0; i < n; i++ {
|
||||
ilda := i * lda
|
||||
xi := x[i]
|
||||
f32.AxpyUnitary(xi, a[ilda:ilda+i], x)
|
||||
f32.AxpyUnitary(xi, a[ilda:ilda+i], x[:i])
|
||||
if nonUnit {
|
||||
x[i] *= a[i*lda+i]
|
||||
}
|
||||
@@ -360,8 +396,6 @@ func (Implementation) Strmv(ul blas.Uplo, tA blas.Transpose, d blas.Diag, n int,
|
||||
//
|
||||
// Float32 implementations are autogenerated and not directly tested.
|
||||
func (Implementation) Strsv(ul blas.Uplo, tA blas.Transpose, d blas.Diag, n int, a []float32, lda int, x []float32, incX int) {
|
||||
// Test the input parameters
|
||||
// Verify inputs
|
||||
if ul != blas.Lower && ul != blas.Upper {
|
||||
panic(badUplo)
|
||||
}
|
||||
@@ -374,19 +408,26 @@ func (Implementation) Strsv(ul blas.Uplo, tA blas.Transpose, d blas.Diag, n int,
|
||||
if n < 0 {
|
||||
panic(nLT0)
|
||||
}
|
||||
if lda*(n-1)+n > len(a) || lda < max(1, n) {
|
||||
if lda < max(1, n) {
|
||||
panic(badLdA)
|
||||
}
|
||||
if incX == 0 {
|
||||
panic(zeroIncX)
|
||||
}
|
||||
if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) {
|
||||
panic(badX)
|
||||
}
|
||||
// Quick return if possible
|
||||
|
||||
// Quick return if possible.
|
||||
if n == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// For zero matrix size the following slice length checks are trivially satisfied.
|
||||
if len(a) < lda*(n-1)+n {
|
||||
panic(shortA)
|
||||
}
|
||||
if (incX > 0 && len(x) <= (n-1)*incX) || (incX < 0 && len(x) <= (1-n)*incX) {
|
||||
panic(shortX)
|
||||
}
|
||||
|
||||
if n == 1 {
|
||||
if d == blas.NonUnit {
|
||||
x[0] /= a[0]
|
||||
@@ -532,14 +573,13 @@ func (Implementation) Strsv(ul blas.Uplo, tA blas.Transpose, d blas.Diag, n int,
|
||||
//
|
||||
// Float32 implementations are autogenerated and not directly tested.
|
||||
func (Implementation) Ssymv(ul blas.Uplo, n int, alpha float32, a []float32, lda int, x []float32, incX int, beta float32, y []float32, incY int) {
|
||||
// Check inputs
|
||||
if ul != blas.Lower && ul != blas.Upper {
|
||||
panic(badUplo)
|
||||
}
|
||||
if n < 0 {
|
||||
panic(nLT0)
|
||||
}
|
||||
if lda > 1 && lda < n {
|
||||
if lda < max(1, n) {
|
||||
panic(badLdA)
|
||||
}
|
||||
if incX == 0 {
|
||||
@@ -548,17 +588,25 @@ func (Implementation) Ssymv(ul blas.Uplo, n int, alpha float32, a []float32, lda
|
||||
if incY == 0 {
|
||||
panic(zeroIncY)
|
||||
}
|
||||
if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) {
|
||||
panic(badX)
|
||||
|
||||
// Quick return if possible.
|
||||
if n == 0 {
|
||||
return
|
||||
}
|
||||
if (incY > 0 && (n-1)*incY >= len(y)) || (incY < 0 && (1-n)*incY >= len(y)) {
|
||||
panic(badY)
|
||||
|
||||
// For zero matrix size the following slice length checks are trivially satisfied.
|
||||
if len(a) < lda*(n-1)+n {
|
||||
panic(shortA)
|
||||
}
|
||||
if lda*(n-1)+n > len(a) || lda < max(1, n) {
|
||||
panic(badLdA)
|
||||
if (incX > 0 && len(x) <= (n-1)*incX) || (incX < 0 && len(x) <= (1-n)*incX) {
|
||||
panic(shortX)
|
||||
}
|
||||
// Quick return if possible
|
||||
if n == 0 || (alpha == 0 && beta == 1) {
|
||||
if (incY > 0 && len(y) <= (n-1)*incY) || (incY < 0 && len(y) <= (1-n)*incY) {
|
||||
panic(shortY)
|
||||
}
|
||||
|
||||
// Quick return if possible.
|
||||
if alpha == 0 && beta == 1 {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -573,10 +621,28 @@ func (Implementation) Ssymv(ul blas.Uplo, n int, alpha float32, a []float32, lda
|
||||
|
||||
// Form y = beta * y
|
||||
if beta != 1 {
|
||||
if incY > 0 {
|
||||
Implementation{}.Sscal(n, beta, y, incY)
|
||||
if incY == 1 {
|
||||
if beta == 0 {
|
||||
for i := range y[:n] {
|
||||
y[i] = 0
|
||||
}
|
||||
} else {
|
||||
f32.ScalUnitary(beta, y[:n])
|
||||
}
|
||||
} else {
|
||||
Implementation{}.Sscal(n, beta, y, -incY)
|
||||
iy := ky
|
||||
if beta == 0 {
|
||||
for i := 0; i < n; i++ {
|
||||
y[iy] = 0
|
||||
iy += incY
|
||||
}
|
||||
} else {
|
||||
if incY > 0 {
|
||||
f32.ScalInc(beta, y, uintptr(n), uintptr(incY))
|
||||
} else {
|
||||
f32.ScalInc(beta, y, uintptr(n), uintptr(-incY))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -692,18 +758,26 @@ func (Implementation) Stbmv(ul blas.Uplo, tA blas.Transpose, d blas.Diag, n, k i
|
||||
if k < 0 {
|
||||
panic(kLT0)
|
||||
}
|
||||
if lda*(n-1)+k+1 > len(a) || lda < k+1 {
|
||||
if lda < k+1 {
|
||||
panic(badLdA)
|
||||
}
|
||||
if incX == 0 {
|
||||
panic(zeroIncX)
|
||||
}
|
||||
if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) {
|
||||
panic(badX)
|
||||
}
|
||||
|
||||
// Quick return if possible.
|
||||
if n == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// For zero matrix size the following slice length checks are trivially satisfied.
|
||||
if len(a) < lda*(n-1)+k+1 {
|
||||
panic(shortA)
|
||||
}
|
||||
if (incX > 0 && len(x) <= (n-1)*incX) || (incX < 0 && len(x) <= (1-n)*incX) {
|
||||
panic(shortX)
|
||||
}
|
||||
|
||||
var kx int
|
||||
if incX < 0 {
|
||||
kx = -(n - 1) * incX
|
||||
@@ -880,7 +954,6 @@ func (Implementation) Stbmv(ul blas.Uplo, tA blas.Transpose, d blas.Diag, n, k i
|
||||
//
|
||||
// Float32 implementations are autogenerated and not directly tested.
|
||||
func (Implementation) Stpmv(ul blas.Uplo, tA blas.Transpose, d blas.Diag, n int, ap []float32, x []float32, incX int) {
|
||||
// Verify inputs
|
||||
if ul != blas.Lower && ul != blas.Upper {
|
||||
panic(badUplo)
|
||||
}
|
||||
@@ -893,18 +966,23 @@ func (Implementation) Stpmv(ul blas.Uplo, tA blas.Transpose, d blas.Diag, n int,
|
||||
if n < 0 {
|
||||
panic(nLT0)
|
||||
}
|
||||
if len(ap) < (n*(n+1))/2 {
|
||||
panic(badLdA)
|
||||
}
|
||||
if incX == 0 {
|
||||
panic(zeroIncX)
|
||||
}
|
||||
if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) {
|
||||
panic(badX)
|
||||
}
|
||||
|
||||
// Quick return if possible.
|
||||
if n == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// For zero matrix size the following slice length checks are trivially satisfied.
|
||||
if len(ap) < n*(n+1)/2 {
|
||||
panic(shortAP)
|
||||
}
|
||||
if (incX > 0 && len(x) <= (n-1)*incX) || (incX < 0 && len(x) <= (1-n)*incX) {
|
||||
panic(shortX)
|
||||
}
|
||||
|
||||
var kx int
|
||||
if incX < 0 {
|
||||
kx = -(n - 1) * incX
|
||||
@@ -1076,18 +1154,29 @@ func (Implementation) Stbsv(ul blas.Uplo, tA blas.Transpose, d blas.Diag, n, k i
|
||||
if n < 0 {
|
||||
panic(nLT0)
|
||||
}
|
||||
if lda*(n-1)+k+1 > len(a) || lda < k+1 {
|
||||
if k < 0 {
|
||||
panic(kLT0)
|
||||
}
|
||||
if lda < k+1 {
|
||||
panic(badLdA)
|
||||
}
|
||||
if incX == 0 {
|
||||
panic(zeroIncX)
|
||||
}
|
||||
if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) {
|
||||
panic(badX)
|
||||
}
|
||||
|
||||
// Quick return if possible.
|
||||
if n == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// For zero matrix size the following slice length checks are trivially satisfied.
|
||||
if len(a) < lda*(n-1)+k+1 {
|
||||
panic(shortA)
|
||||
}
|
||||
if (incX > 0 && len(x) <= (n-1)*incX) || (incX < 0 && len(x) <= (1-n)*incX) {
|
||||
panic(shortX)
|
||||
}
|
||||
|
||||
var kx int
|
||||
if incX < 0 {
|
||||
kx = -(n - 1) * incX
|
||||
@@ -1276,25 +1365,37 @@ func (Implementation) Ssbmv(ul blas.Uplo, n, k int, alpha float32, a []float32,
|
||||
if n < 0 {
|
||||
panic(nLT0)
|
||||
}
|
||||
|
||||
if k < 0 {
|
||||
panic(kLT0)
|
||||
}
|
||||
if lda < k+1 {
|
||||
panic(badLdA)
|
||||
}
|
||||
if incX == 0 {
|
||||
panic(zeroIncX)
|
||||
}
|
||||
if incY == 0 {
|
||||
panic(zeroIncY)
|
||||
}
|
||||
if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) {
|
||||
panic(badX)
|
||||
}
|
||||
if (incY > 0 && (n-1)*incY >= len(y)) || (incY < 0 && (1-n)*incY >= len(y)) {
|
||||
panic(badY)
|
||||
}
|
||||
if lda*(n-1)+k+1 > len(a) || lda < k+1 {
|
||||
panic(badLdA)
|
||||
|
||||
// Quick return if possible.
|
||||
if n == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// Quick return if possible
|
||||
if n == 0 || (alpha == 0 && beta == 1) {
|
||||
// For zero matrix size the following slice length checks are trivially satisfied.
|
||||
if len(a) < lda*(n-1)+k+1 {
|
||||
panic(shortA)
|
||||
}
|
||||
if (incX > 0 && len(x) <= (n-1)*incX) || (incX < 0 && len(x) <= (1-n)*incX) {
|
||||
panic(shortX)
|
||||
}
|
||||
if (incY > 0 && len(y) <= (n-1)*incY) || (incY < 0 && len(y) <= (1-n)*incY) {
|
||||
panic(shortY)
|
||||
}
|
||||
|
||||
// Quick return if possible.
|
||||
if alpha == 0 && beta == 1 {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1309,11 +1410,31 @@ func (Implementation) Ssbmv(ul blas.Uplo, n, k int, alpha float32, a []float32,
|
||||
ky = -(lenY - 1) * incY
|
||||
}
|
||||
|
||||
// First form y = beta * y
|
||||
if incY > 0 {
|
||||
Implementation{}.Sscal(lenY, beta, y, incY)
|
||||
} else {
|
||||
Implementation{}.Sscal(lenY, beta, y, -incY)
|
||||
// Form y = beta * y.
|
||||
if beta != 1 {
|
||||
if incY == 1 {
|
||||
if beta == 0 {
|
||||
for i := range y[:n] {
|
||||
y[i] = 0
|
||||
}
|
||||
} else {
|
||||
f32.ScalUnitary(beta, y[:n])
|
||||
}
|
||||
} else {
|
||||
iy := ky
|
||||
if beta == 0 {
|
||||
for i := 0; i < n; i++ {
|
||||
y[iy] = 0
|
||||
iy += incY
|
||||
}
|
||||
} else {
|
||||
if incY > 0 {
|
||||
f32.ScalInc(beta, y, uintptr(n), uintptr(incY))
|
||||
} else {
|
||||
f32.ScalInc(beta, y, uintptr(n), uintptr(-incY))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if alpha == 0 {
|
||||
@@ -1415,16 +1536,28 @@ func (Implementation) Ssyr(ul blas.Uplo, n int, alpha float32, x []float32, incX
|
||||
if n < 0 {
|
||||
panic(nLT0)
|
||||
}
|
||||
if lda < max(1, n) {
|
||||
panic(badLdA)
|
||||
}
|
||||
if incX == 0 {
|
||||
panic(zeroIncX)
|
||||
}
|
||||
if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) {
|
||||
panic(badX)
|
||||
|
||||
// Quick return if possible.
|
||||
if n == 0 {
|
||||
return
|
||||
}
|
||||
if lda*(n-1)+n > len(a) || lda < max(1, n) {
|
||||
panic(badLdA)
|
||||
|
||||
// For zero matrix size the following slice length checks are trivially satisfied.
|
||||
if (incX > 0 && len(x) <= (n-1)*incX) || (incX < 0 && len(x) <= (1-n)*incX) {
|
||||
panic(shortX)
|
||||
}
|
||||
if alpha == 0 || n == 0 {
|
||||
if len(a) < lda*(n-1)+n {
|
||||
panic(shortA)
|
||||
}
|
||||
|
||||
// Quick return if possible.
|
||||
if alpha == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1503,21 +1636,33 @@ func (Implementation) Ssyr2(ul blas.Uplo, n int, alpha float32, x []float32, inc
|
||||
if n < 0 {
|
||||
panic(nLT0)
|
||||
}
|
||||
if lda < max(1, n) {
|
||||
panic(badLdA)
|
||||
}
|
||||
if incX == 0 {
|
||||
panic(zeroIncX)
|
||||
}
|
||||
if incY == 0 {
|
||||
panic(zeroIncY)
|
||||
}
|
||||
if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) {
|
||||
panic(badX)
|
||||
|
||||
// Quick return if possible.
|
||||
if n == 0 {
|
||||
return
|
||||
}
|
||||
if (incY > 0 && (n-1)*incY >= len(y)) || (incY < 0 && (1-n)*incY >= len(y)) {
|
||||
panic(badY)
|
||||
|
||||
// For zero matrix size the following slice length checks are trivially satisfied.
|
||||
if (incX > 0 && len(x) <= (n-1)*incX) || (incX < 0 && len(x) <= (1-n)*incX) {
|
||||
panic(shortX)
|
||||
}
|
||||
if lda*(n-1)+n > len(a) || lda < max(1, n) {
|
||||
panic(badLdA)
|
||||
if (incY > 0 && len(y) <= (n-1)*incY) || (incY < 0 && len(y) <= (1-n)*incY) {
|
||||
panic(shortY)
|
||||
}
|
||||
if len(a) < lda*(n-1)+n {
|
||||
panic(shortA)
|
||||
}
|
||||
|
||||
// Quick return if possible.
|
||||
if alpha == 0 {
|
||||
return
|
||||
}
|
||||
@@ -1601,7 +1746,6 @@ func (Implementation) Ssyr2(ul blas.Uplo, n int, alpha float32, x []float32, inc
|
||||
//
|
||||
// Float32 implementations are autogenerated and not directly tested.
|
||||
func (Implementation) Stpsv(ul blas.Uplo, tA blas.Transpose, d blas.Diag, n int, ap []float32, x []float32, incX int) {
|
||||
// Verify inputs
|
||||
if ul != blas.Lower && ul != blas.Upper {
|
||||
panic(badUplo)
|
||||
}
|
||||
@@ -1614,18 +1758,23 @@ func (Implementation) Stpsv(ul blas.Uplo, tA blas.Transpose, d blas.Diag, n int,
|
||||
if n < 0 {
|
||||
panic(nLT0)
|
||||
}
|
||||
if len(ap) < (n*(n+1))/2 {
|
||||
panic(badLdA)
|
||||
}
|
||||
if incX == 0 {
|
||||
panic(zeroIncX)
|
||||
}
|
||||
if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) {
|
||||
panic(badX)
|
||||
}
|
||||
|
||||
// Quick return if possible.
|
||||
if n == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// For zero matrix size the following slice length checks are trivially satisfied.
|
||||
if len(ap) < n*(n+1)/2 {
|
||||
panic(shortAP)
|
||||
}
|
||||
if (incX > 0 && len(x) <= (n-1)*incX) || (incX < 0 && len(x) <= (1-n)*incX) {
|
||||
panic(shortX)
|
||||
}
|
||||
|
||||
var kx int
|
||||
if incX < 0 {
|
||||
kx = -(n - 1) * incX
|
||||
@@ -1776,31 +1925,38 @@ func (Implementation) Stpsv(ul blas.Uplo, tA blas.Transpose, d blas.Diag, n int,
|
||||
// and alpha and beta are scalars.
|
||||
//
|
||||
// Float32 implementations are autogenerated and not directly tested.
|
||||
func (Implementation) Sspmv(ul blas.Uplo, n int, alpha float32, a []float32, x []float32, incX int, beta float32, y []float32, incY int) {
|
||||
// Verify inputs
|
||||
func (Implementation) Sspmv(ul blas.Uplo, n int, alpha float32, ap []float32, x []float32, incX int, beta float32, y []float32, incY int) {
|
||||
if ul != blas.Lower && ul != blas.Upper {
|
||||
panic(badUplo)
|
||||
}
|
||||
if n < 0 {
|
||||
panic(nLT0)
|
||||
}
|
||||
if len(a) < (n*(n+1))/2 {
|
||||
panic(badLdA)
|
||||
}
|
||||
if incX == 0 {
|
||||
panic(zeroIncX)
|
||||
}
|
||||
if incY == 0 {
|
||||
panic(zeroIncY)
|
||||
}
|
||||
if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) {
|
||||
panic(badX)
|
||||
|
||||
// Quick return if possible.
|
||||
if n == 0 {
|
||||
return
|
||||
}
|
||||
if (incY > 0 && (n-1)*incY >= len(y)) || (incY < 0 && (1-n)*incY >= len(y)) {
|
||||
panic(badY)
|
||||
|
||||
// For zero matrix size the following slice length checks are trivially satisfied.
|
||||
if len(ap) < n*(n+1)/2 {
|
||||
panic(shortAP)
|
||||
}
|
||||
// Quick return if possible
|
||||
if n == 0 || (alpha == 0 && beta == 1) {
|
||||
if (incX > 0 && len(x) <= (n-1)*incX) || (incX < 0 && len(x) <= (1-n)*incX) {
|
||||
panic(shortX)
|
||||
}
|
||||
if (incY > 0 && len(y) <= (n-1)*incY) || (incY < 0 && len(y) <= (1-n)*incY) {
|
||||
panic(shortY)
|
||||
}
|
||||
|
||||
// Quick return if possible.
|
||||
if alpha == 0 && beta == 1 {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1813,12 +1969,30 @@ func (Implementation) Sspmv(ul blas.Uplo, n int, alpha float32, a []float32, x [
|
||||
ky = -(n - 1) * incY
|
||||
}
|
||||
|
||||
// Form y = beta * y
|
||||
// Form y = beta * y.
|
||||
if beta != 1 {
|
||||
if incY > 0 {
|
||||
Implementation{}.Sscal(n, beta, y, incY)
|
||||
if incY == 1 {
|
||||
if beta == 0 {
|
||||
for i := range y[:n] {
|
||||
y[i] = 0
|
||||
}
|
||||
} else {
|
||||
f32.ScalUnitary(beta, y[:n])
|
||||
}
|
||||
} else {
|
||||
Implementation{}.Sscal(n, beta, y, -incY)
|
||||
iy := ky
|
||||
if beta == 0 {
|
||||
for i := 0; i < n; i++ {
|
||||
y[iy] = 0
|
||||
iy += incY
|
||||
}
|
||||
} else {
|
||||
if incY > 0 {
|
||||
f32.ScalInc(beta, y, uintptr(n), uintptr(incY))
|
||||
} else {
|
||||
f32.ScalInc(beta, y, uintptr(n), uintptr(-incY))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1827,7 +2001,7 @@ func (Implementation) Sspmv(ul blas.Uplo, n int, alpha float32, a []float32, x [
|
||||
}
|
||||
|
||||
if n == 1 {
|
||||
y[0] += alpha * a[0] * x[0]
|
||||
y[0] += alpha * ap[0] * x[0]
|
||||
return
|
||||
}
|
||||
var offset int // Offset is the index of (i,i).
|
||||
@@ -1836,8 +2010,8 @@ func (Implementation) Sspmv(ul blas.Uplo, n int, alpha float32, a []float32, x [
|
||||
iy := ky
|
||||
for i := 0; i < n; i++ {
|
||||
xv := x[i] * alpha
|
||||
sum := a[offset] * x[i]
|
||||
atmp := a[offset+1 : offset+n-i]
|
||||
sum := ap[offset] * x[i]
|
||||
atmp := ap[offset+1 : offset+n-i]
|
||||
xtmp := x[i+1:]
|
||||
jy := ky + (i+1)*incY
|
||||
for j, v := range atmp {
|
||||
@@ -1855,8 +2029,8 @@ func (Implementation) Sspmv(ul blas.Uplo, n int, alpha float32, a []float32, x [
|
||||
iy := ky
|
||||
for i := 0; i < n; i++ {
|
||||
xv := x[ix] * alpha
|
||||
sum := a[offset] * x[ix]
|
||||
atmp := a[offset+1 : offset+n-i]
|
||||
sum := ap[offset] * x[ix]
|
||||
atmp := ap[offset+1 : offset+n-i]
|
||||
jx := kx + (i+1)*incX
|
||||
jy := ky + (i+1)*incY
|
||||
for _, v := range atmp {
|
||||
@@ -1876,7 +2050,7 @@ func (Implementation) Sspmv(ul blas.Uplo, n int, alpha float32, a []float32, x [
|
||||
iy := ky
|
||||
for i := 0; i < n; i++ {
|
||||
xv := x[i] * alpha
|
||||
atmp := a[offset-i : offset]
|
||||
atmp := ap[offset-i : offset]
|
||||
jy := ky
|
||||
var sum float32
|
||||
for j, v := range atmp {
|
||||
@@ -1884,7 +2058,7 @@ func (Implementation) Sspmv(ul blas.Uplo, n int, alpha float32, a []float32, x [
|
||||
y[jy] += v * xv
|
||||
jy += incY
|
||||
}
|
||||
sum += a[offset] * x[i]
|
||||
sum += ap[offset] * x[i]
|
||||
y[iy] += alpha * sum
|
||||
iy += incY
|
||||
offset += i + 2
|
||||
@@ -1895,7 +2069,7 @@ func (Implementation) Sspmv(ul blas.Uplo, n int, alpha float32, a []float32, x [
|
||||
iy := ky
|
||||
for i := 0; i < n; i++ {
|
||||
xv := x[ix] * alpha
|
||||
atmp := a[offset-i : offset]
|
||||
atmp := ap[offset-i : offset]
|
||||
jx := kx
|
||||
jy := ky
|
||||
var sum float32
|
||||
@@ -1906,7 +2080,7 @@ func (Implementation) Sspmv(ul blas.Uplo, n int, alpha float32, a []float32, x [
|
||||
jy += incY
|
||||
}
|
||||
|
||||
sum += a[offset] * x[ix]
|
||||
sum += ap[offset] * x[ix]
|
||||
y[iy] += alpha * sum
|
||||
ix += incX
|
||||
iy += incY
|
||||
@@ -1920,7 +2094,7 @@ func (Implementation) Sspmv(ul blas.Uplo, n int, alpha float32, a []float32, x [
|
||||
// alpha is a scalar.
|
||||
//
|
||||
// Float32 implementations are autogenerated and not directly tested.
|
||||
func (Implementation) Sspr(ul blas.Uplo, n int, alpha float32, x []float32, incX int, a []float32) {
|
||||
func (Implementation) Sspr(ul blas.Uplo, n int, alpha float32, x []float32, incX int, ap []float32) {
|
||||
if ul != blas.Lower && ul != blas.Upper {
|
||||
panic(badUplo)
|
||||
}
|
||||
@@ -1930,15 +2104,25 @@ func (Implementation) Sspr(ul blas.Uplo, n int, alpha float32, x []float32, incX
|
||||
if incX == 0 {
|
||||
panic(zeroIncX)
|
||||
}
|
||||
if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) {
|
||||
panic(badX)
|
||||
}
|
||||
if len(a) < (n*(n+1))/2 {
|
||||
panic(badLdA)
|
||||
}
|
||||
if alpha == 0 || n == 0 {
|
||||
|
||||
// Quick return if possible.
|
||||
if n == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// For zero matrix size the following slice length checks are trivially satisfied.
|
||||
if (incX > 0 && len(x) <= (n-1)*incX) || (incX < 0 && len(x) <= (1-n)*incX) {
|
||||
panic(shortX)
|
||||
}
|
||||
if len(ap) < n*(n+1)/2 {
|
||||
panic(shortAP)
|
||||
}
|
||||
|
||||
// Quick return if possible.
|
||||
if alpha == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
lenX := n
|
||||
var kx int
|
||||
if incX < 0 {
|
||||
@@ -1948,7 +2132,7 @@ func (Implementation) Sspr(ul blas.Uplo, n int, alpha float32, x []float32, incX
|
||||
if ul == blas.Upper {
|
||||
if incX == 1 {
|
||||
for i := 0; i < n; i++ {
|
||||
atmp := a[offset:]
|
||||
atmp := ap[offset:]
|
||||
xv := alpha * x[i]
|
||||
xtmp := x[i:n]
|
||||
for j, v := range xtmp {
|
||||
@@ -1961,7 +2145,7 @@ func (Implementation) Sspr(ul blas.Uplo, n int, alpha float32, x []float32, incX
|
||||
ix := kx
|
||||
for i := 0; i < n; i++ {
|
||||
jx := kx + i*incX
|
||||
atmp := a[offset:]
|
||||
atmp := ap[offset:]
|
||||
xv := alpha * x[ix]
|
||||
for j := 0; j < n-i; j++ {
|
||||
atmp[j] += xv * x[jx]
|
||||
@@ -1974,7 +2158,7 @@ func (Implementation) Sspr(ul blas.Uplo, n int, alpha float32, x []float32, incX
|
||||
}
|
||||
if incX == 1 {
|
||||
for i := 0; i < n; i++ {
|
||||
atmp := a[offset-i:]
|
||||
atmp := ap[offset-i:]
|
||||
xv := alpha * x[i]
|
||||
xtmp := x[:i+1]
|
||||
for j, v := range xtmp {
|
||||
@@ -1987,7 +2171,7 @@ func (Implementation) Sspr(ul blas.Uplo, n int, alpha float32, x []float32, incX
|
||||
ix := kx
|
||||
for i := 0; i < n; i++ {
|
||||
jx := kx
|
||||
atmp := a[offset-i:]
|
||||
atmp := ap[offset-i:]
|
||||
xv := alpha * x[ix]
|
||||
for j := 0; j <= i; j++ {
|
||||
atmp[j] += xv * x[jx]
|
||||
@@ -2017,18 +2201,28 @@ func (Implementation) Sspr2(ul blas.Uplo, n int, alpha float32, x []float32, inc
|
||||
if incY == 0 {
|
||||
panic(zeroIncY)
|
||||
}
|
||||
if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) {
|
||||
panic(badX)
|
||||
|
||||
// Quick return if possible.
|
||||
if n == 0 {
|
||||
return
|
||||
}
|
||||
if (incY > 0 && (n-1)*incY >= len(y)) || (incY < 0 && (1-n)*incY >= len(y)) {
|
||||
panic(badY)
|
||||
|
||||
// For zero matrix size the following slice length checks are trivially satisfied.
|
||||
if (incX > 0 && len(x) <= (n-1)*incX) || (incX < 0 && len(x) <= (1-n)*incX) {
|
||||
panic(shortX)
|
||||
}
|
||||
if len(ap) < (n*(n+1))/2 {
|
||||
panic(badLdA)
|
||||
if (incY > 0 && len(y) <= (n-1)*incY) || (incY < 0 && len(y) <= (1-n)*incY) {
|
||||
panic(shortY)
|
||||
}
|
||||
if len(ap) < n*(n+1)/2 {
|
||||
panic(shortAP)
|
||||
}
|
||||
|
||||
// Quick return if possible.
|
||||
if alpha == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
var ky, kx int
|
||||
if incY < 0 {
|
||||
ky = -(n - 1) * incY
|
||||
@@ -15,34 +15,40 @@ var _ blas.Float64Level2 = Implementation{}
|
||||
// A += alpha * x * y^T
|
||||
// where A is an m×n dense matrix, x and y are vectors, and alpha is a scalar.
|
||||
func (Implementation) Dger(m, n int, alpha float64, x []float64, incX int, y []float64, incY int, a []float64, lda int) {
|
||||
// Check inputs
|
||||
if m < 0 {
|
||||
panic("m < 0")
|
||||
panic(mLT0)
|
||||
}
|
||||
if n < 0 {
|
||||
panic(nLT0)
|
||||
}
|
||||
if lda < max(1, n) {
|
||||
panic(badLdA)
|
||||
}
|
||||
if incX == 0 {
|
||||
panic(zeroIncX)
|
||||
}
|
||||
if incY == 0 {
|
||||
panic(zeroIncY)
|
||||
}
|
||||
if (incX > 0 && (m-1)*incX >= len(x)) || (incX < 0 && (1-m)*incX >= len(x)) {
|
||||
panic(badX)
|
||||
}
|
||||
if (incY > 0 && (n-1)*incY >= len(y)) || (incY < 0 && (1-n)*incY >= len(y)) {
|
||||
panic(badY)
|
||||
}
|
||||
if lda*(m-1)+n > len(a) || lda < max(1, n) {
|
||||
panic(badLdA)
|
||||
}
|
||||
if lda < max(1, n) {
|
||||
panic(badLdA)
|
||||
|
||||
// Quick return if possible.
|
||||
if m == 0 || n == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// Quick return if possible
|
||||
if m == 0 || n == 0 || alpha == 0 {
|
||||
// For zero matrix size the following slice length checks are trivially satisfied.
|
||||
if (incX > 0 && len(x) <= (m-1)*incX) || (incX < 0 && len(x) <= (1-m)*incX) {
|
||||
panic(shortX)
|
||||
}
|
||||
if (incY > 0 && len(y) <= (n-1)*incY) || (incY < 0 && len(y) <= (1-n)*incY) {
|
||||
panic(shortY)
|
||||
}
|
||||
if len(a) < lda*(m-1)+n {
|
||||
panic(shortA)
|
||||
}
|
||||
|
||||
// Quick return if possible.
|
||||
if alpha == 0 {
|
||||
return
|
||||
}
|
||||
f64.Ger(uintptr(m), uintptr(n),
|
||||
@@ -70,7 +76,7 @@ func (Implementation) Dgbmv(tA blas.Transpose, m, n, kL, kU int, alpha float64,
|
||||
if kL < 0 {
|
||||
panic(kLLT0)
|
||||
}
|
||||
if kL < 0 {
|
||||
if kU < 0 {
|
||||
panic(kULT0)
|
||||
}
|
||||
if lda < kL+kU+1 {
|
||||
@@ -82,25 +88,31 @@ func (Implementation) Dgbmv(tA blas.Transpose, m, n, kL, kU int, alpha float64,
|
||||
if incY == 0 {
|
||||
panic(zeroIncY)
|
||||
}
|
||||
// Set up indexes
|
||||
|
||||
// Quick return if possible.
|
||||
if m == 0 || n == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// For zero matrix size the following slice length checks are trivially satisfied.
|
||||
if len(a) < lda*(min(m, n+kL)-1)+kL+kU+1 {
|
||||
panic(shortA)
|
||||
}
|
||||
lenX := m
|
||||
lenY := n
|
||||
if tA == blas.NoTrans {
|
||||
lenX = n
|
||||
lenY = m
|
||||
}
|
||||
if (incX > 0 && (lenX-1)*incX >= len(x)) || (incX < 0 && (1-lenX)*incX >= len(x)) {
|
||||
panic(badX)
|
||||
if (incX > 0 && len(x) <= (lenX-1)*incX) || (incX < 0 && len(x) <= (1-lenX)*incX) {
|
||||
panic(shortX)
|
||||
}
|
||||
if (incY > 0 && (lenY-1)*incY >= len(y)) || (incY < 0 && (1-lenY)*incY >= len(y)) {
|
||||
panic(badY)
|
||||
}
|
||||
if lda*(min(m, n+kL)-1)+kL+kU+1 > len(a) || lda < kL+kU+1 {
|
||||
panic(badLdA)
|
||||
if (incY > 0 && len(y) <= (lenY-1)*incY) || (incY < 0 && len(y) <= (1-lenY)*incY) {
|
||||
panic(shortY)
|
||||
}
|
||||
|
||||
// Quick return if possible
|
||||
if m == 0 || n == 0 || (alpha == 0 && beta == 1) {
|
||||
// Quick return if possible.
|
||||
if alpha == 0 && beta == 1 {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -112,11 +124,31 @@ func (Implementation) Dgbmv(tA blas.Transpose, m, n, kL, kU int, alpha float64,
|
||||
ky = -(lenY - 1) * incY
|
||||
}
|
||||
|
||||
// First form y = beta * y
|
||||
if incY > 0 {
|
||||
Implementation{}.Dscal(lenY, beta, y, incY)
|
||||
} else {
|
||||
Implementation{}.Dscal(lenY, beta, y, -incY)
|
||||
// Form y = beta * y.
|
||||
if beta != 1 {
|
||||
if incY == 1 {
|
||||
if beta == 0 {
|
||||
for i := range y[:lenY] {
|
||||
y[i] = 0
|
||||
}
|
||||
} else {
|
||||
f64.ScalUnitary(beta, y[:lenY])
|
||||
}
|
||||
} else {
|
||||
iy := ky
|
||||
if beta == 0 {
|
||||
for i := 0; i < lenY; i++ {
|
||||
y[iy] = 0
|
||||
iy += incY
|
||||
}
|
||||
} else {
|
||||
if incY > 0 {
|
||||
f64.ScalInc(beta, y, uintptr(lenY), uintptr(incY))
|
||||
} else {
|
||||
f64.ScalInc(beta, y, uintptr(lenY), uintptr(-incY))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if alpha == 0 {
|
||||
@@ -208,21 +240,26 @@ func (Implementation) Dtrmv(ul blas.Uplo, tA blas.Transpose, d blas.Diag, n int,
|
||||
if n < 0 {
|
||||
panic(nLT0)
|
||||
}
|
||||
if lda < n {
|
||||
if lda < max(1, n) {
|
||||
panic(badLdA)
|
||||
}
|
||||
if incX == 0 {
|
||||
panic(zeroIncX)
|
||||
}
|
||||
if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) {
|
||||
panic(badX)
|
||||
}
|
||||
if lda*(n-1)+n > len(a) || lda < max(1, n) {
|
||||
panic(badLdA)
|
||||
}
|
||||
|
||||
// Quick return if possible.
|
||||
if n == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// For zero matrix size the following slice length checks are trivially satisfied.
|
||||
if len(a) < lda*(n-1)+n {
|
||||
panic(shortA)
|
||||
}
|
||||
if (incX > 0 && len(x) <= (n-1)*incX) || (incX < 0 && len(x) <= (1-n)*incX) {
|
||||
panic(shortX)
|
||||
}
|
||||
|
||||
nonUnit := d != blas.Unit
|
||||
if n == 1 {
|
||||
if nonUnit {
|
||||
@@ -245,8 +282,7 @@ func (Implementation) Dtrmv(ul blas.Uplo, tA blas.Transpose, d blas.Diag, n int,
|
||||
} else {
|
||||
tmp = x[i]
|
||||
}
|
||||
xtmp := x[i+1:]
|
||||
x[i] = tmp + f64.DotUnitary(a[ilda+i+1:ilda+n], xtmp)
|
||||
x[i] = tmp + f64.DotUnitary(a[ilda+i+1:ilda+n], x[i+1:n])
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -273,7 +309,7 @@ func (Implementation) Dtrmv(ul blas.Uplo, tA blas.Transpose, d blas.Diag, n int,
|
||||
} else {
|
||||
tmp = x[i]
|
||||
}
|
||||
x[i] = tmp + f64.DotUnitary(a[ilda:ilda+i], x)
|
||||
x[i] = tmp + f64.DotUnitary(a[ilda:ilda+i], x[:i])
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -320,7 +356,7 @@ func (Implementation) Dtrmv(ul blas.Uplo, tA blas.Transpose, d blas.Diag, n int,
|
||||
for i := 0; i < n; i++ {
|
||||
ilda := i * lda
|
||||
xi := x[i]
|
||||
f64.AxpyUnitary(xi, a[ilda:ilda+i], x)
|
||||
f64.AxpyUnitary(xi, a[ilda:ilda+i], x[:i])
|
||||
if nonUnit {
|
||||
x[i] *= a[i*lda+i]
|
||||
}
|
||||
@@ -350,8 +386,6 @@ func (Implementation) Dtrmv(ul blas.Uplo, tA blas.Transpose, d blas.Diag, n int,
|
||||
// No test for singularity or near-singularity is included in this
|
||||
// routine. Such tests must be performed before calling this routine.
|
||||
func (Implementation) Dtrsv(ul blas.Uplo, tA blas.Transpose, d blas.Diag, n int, a []float64, lda int, x []float64, incX int) {
|
||||
// Test the input parameters
|
||||
// Verify inputs
|
||||
if ul != blas.Lower && ul != blas.Upper {
|
||||
panic(badUplo)
|
||||
}
|
||||
@@ -364,19 +398,26 @@ func (Implementation) Dtrsv(ul blas.Uplo, tA blas.Transpose, d blas.Diag, n int,
|
||||
if n < 0 {
|
||||
panic(nLT0)
|
||||
}
|
||||
if lda*(n-1)+n > len(a) || lda < max(1, n) {
|
||||
if lda < max(1, n) {
|
||||
panic(badLdA)
|
||||
}
|
||||
if incX == 0 {
|
||||
panic(zeroIncX)
|
||||
}
|
||||
if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) {
|
||||
panic(badX)
|
||||
}
|
||||
// Quick return if possible
|
||||
|
||||
// Quick return if possible.
|
||||
if n == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// For zero matrix size the following slice length checks are trivially satisfied.
|
||||
if len(a) < lda*(n-1)+n {
|
||||
panic(shortA)
|
||||
}
|
||||
if (incX > 0 && len(x) <= (n-1)*incX) || (incX < 0 && len(x) <= (1-n)*incX) {
|
||||
panic(shortX)
|
||||
}
|
||||
|
||||
if n == 1 {
|
||||
if d == blas.NonUnit {
|
||||
x[0] /= a[0]
|
||||
@@ -520,14 +561,13 @@ func (Implementation) Dtrsv(ul blas.Uplo, tA blas.Transpose, d blas.Diag, n int,
|
||||
// where A is an n×n symmetric matrix, x and y are vectors, and alpha and
|
||||
// beta are scalars.
|
||||
func (Implementation) Dsymv(ul blas.Uplo, n int, alpha float64, a []float64, lda int, x []float64, incX int, beta float64, y []float64, incY int) {
|
||||
// Check inputs
|
||||
if ul != blas.Lower && ul != blas.Upper {
|
||||
panic(badUplo)
|
||||
}
|
||||
if n < 0 {
|
||||
panic(nLT0)
|
||||
}
|
||||
if lda > 1 && lda < n {
|
||||
if lda < max(1, n) {
|
||||
panic(badLdA)
|
||||
}
|
||||
if incX == 0 {
|
||||
@@ -536,17 +576,25 @@ func (Implementation) Dsymv(ul blas.Uplo, n int, alpha float64, a []float64, lda
|
||||
if incY == 0 {
|
||||
panic(zeroIncY)
|
||||
}
|
||||
if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) {
|
||||
panic(badX)
|
||||
|
||||
// Quick return if possible.
|
||||
if n == 0 {
|
||||
return
|
||||
}
|
||||
if (incY > 0 && (n-1)*incY >= len(y)) || (incY < 0 && (1-n)*incY >= len(y)) {
|
||||
panic(badY)
|
||||
|
||||
// For zero matrix size the following slice length checks are trivially satisfied.
|
||||
if len(a) < lda*(n-1)+n {
|
||||
panic(shortA)
|
||||
}
|
||||
if lda*(n-1)+n > len(a) || lda < max(1, n) {
|
||||
panic(badLdA)
|
||||
if (incX > 0 && len(x) <= (n-1)*incX) || (incX < 0 && len(x) <= (1-n)*incX) {
|
||||
panic(shortX)
|
||||
}
|
||||
// Quick return if possible
|
||||
if n == 0 || (alpha == 0 && beta == 1) {
|
||||
if (incY > 0 && len(y) <= (n-1)*incY) || (incY < 0 && len(y) <= (1-n)*incY) {
|
||||
panic(shortY)
|
||||
}
|
||||
|
||||
// Quick return if possible.
|
||||
if alpha == 0 && beta == 1 {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -561,10 +609,28 @@ func (Implementation) Dsymv(ul blas.Uplo, n int, alpha float64, a []float64, lda
|
||||
|
||||
// Form y = beta * y
|
||||
if beta != 1 {
|
||||
if incY > 0 {
|
||||
Implementation{}.Dscal(n, beta, y, incY)
|
||||
if incY == 1 {
|
||||
if beta == 0 {
|
||||
for i := range y[:n] {
|
||||
y[i] = 0
|
||||
}
|
||||
} else {
|
||||
f64.ScalUnitary(beta, y[:n])
|
||||
}
|
||||
} else {
|
||||
Implementation{}.Dscal(n, beta, y, -incY)
|
||||
iy := ky
|
||||
if beta == 0 {
|
||||
for i := 0; i < n; i++ {
|
||||
y[iy] = 0
|
||||
iy += incY
|
||||
}
|
||||
} else {
|
||||
if incY > 0 {
|
||||
f64.ScalInc(beta, y, uintptr(n), uintptr(incY))
|
||||
} else {
|
||||
f64.ScalInc(beta, y, uintptr(n), uintptr(-incY))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -678,18 +744,26 @@ func (Implementation) Dtbmv(ul blas.Uplo, tA blas.Transpose, d blas.Diag, n, k i
|
||||
if k < 0 {
|
||||
panic(kLT0)
|
||||
}
|
||||
if lda*(n-1)+k+1 > len(a) || lda < k+1 {
|
||||
if lda < k+1 {
|
||||
panic(badLdA)
|
||||
}
|
||||
if incX == 0 {
|
||||
panic(zeroIncX)
|
||||
}
|
||||
if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) {
|
||||
panic(badX)
|
||||
}
|
||||
|
||||
// Quick return if possible.
|
||||
if n == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// For zero matrix size the following slice length checks are trivially satisfied.
|
||||
if len(a) < lda*(n-1)+k+1 {
|
||||
panic(shortA)
|
||||
}
|
||||
if (incX > 0 && len(x) <= (n-1)*incX) || (incX < 0 && len(x) <= (1-n)*incX) {
|
||||
panic(shortX)
|
||||
}
|
||||
|
||||
var kx int
|
||||
if incX < 0 {
|
||||
kx = -(n - 1) * incX
|
||||
@@ -864,7 +938,6 @@ func (Implementation) Dtbmv(ul blas.Uplo, tA blas.Transpose, d blas.Diag, n, k i
|
||||
// x = A^T * x if tA == blas.Trans or blas.ConjTrans
|
||||
// where A is an n×n triangular matrix in packed format, and x is a vector.
|
||||
func (Implementation) Dtpmv(ul blas.Uplo, tA blas.Transpose, d blas.Diag, n int, ap []float64, x []float64, incX int) {
|
||||
// Verify inputs
|
||||
if ul != blas.Lower && ul != blas.Upper {
|
||||
panic(badUplo)
|
||||
}
|
||||
@@ -877,18 +950,23 @@ func (Implementation) Dtpmv(ul blas.Uplo, tA blas.Transpose, d blas.Diag, n int,
|
||||
if n < 0 {
|
||||
panic(nLT0)
|
||||
}
|
||||
if len(ap) < (n*(n+1))/2 {
|
||||
panic(badLdA)
|
||||
}
|
||||
if incX == 0 {
|
||||
panic(zeroIncX)
|
||||
}
|
||||
if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) {
|
||||
panic(badX)
|
||||
}
|
||||
|
||||
// Quick return if possible.
|
||||
if n == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// For zero matrix size the following slice length checks are trivially satisfied.
|
||||
if len(ap) < n*(n+1)/2 {
|
||||
panic(shortAP)
|
||||
}
|
||||
if (incX > 0 && len(x) <= (n-1)*incX) || (incX < 0 && len(x) <= (1-n)*incX) {
|
||||
panic(shortX)
|
||||
}
|
||||
|
||||
var kx int
|
||||
if incX < 0 {
|
||||
kx = -(n - 1) * incX
|
||||
@@ -1058,18 +1136,29 @@ func (Implementation) Dtbsv(ul blas.Uplo, tA blas.Transpose, d blas.Diag, n, k i
|
||||
if n < 0 {
|
||||
panic(nLT0)
|
||||
}
|
||||
if lda*(n-1)+k+1 > len(a) || lda < k+1 {
|
||||
if k < 0 {
|
||||
panic(kLT0)
|
||||
}
|
||||
if lda < k+1 {
|
||||
panic(badLdA)
|
||||
}
|
||||
if incX == 0 {
|
||||
panic(zeroIncX)
|
||||
}
|
||||
if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) {
|
||||
panic(badX)
|
||||
}
|
||||
|
||||
// Quick return if possible.
|
||||
if n == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// For zero matrix size the following slice length checks are trivially satisfied.
|
||||
if len(a) < lda*(n-1)+k+1 {
|
||||
panic(shortA)
|
||||
}
|
||||
if (incX > 0 && len(x) <= (n-1)*incX) || (incX < 0 && len(x) <= (1-n)*incX) {
|
||||
panic(shortX)
|
||||
}
|
||||
|
||||
var kx int
|
||||
if incX < 0 {
|
||||
kx = -(n - 1) * incX
|
||||
@@ -1256,25 +1345,37 @@ func (Implementation) Dsbmv(ul blas.Uplo, n, k int, alpha float64, a []float64,
|
||||
if n < 0 {
|
||||
panic(nLT0)
|
||||
}
|
||||
|
||||
if k < 0 {
|
||||
panic(kLT0)
|
||||
}
|
||||
if lda < k+1 {
|
||||
panic(badLdA)
|
||||
}
|
||||
if incX == 0 {
|
||||
panic(zeroIncX)
|
||||
}
|
||||
if incY == 0 {
|
||||
panic(zeroIncY)
|
||||
}
|
||||
if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) {
|
||||
panic(badX)
|
||||
}
|
||||
if (incY > 0 && (n-1)*incY >= len(y)) || (incY < 0 && (1-n)*incY >= len(y)) {
|
||||
panic(badY)
|
||||
}
|
||||
if lda*(n-1)+k+1 > len(a) || lda < k+1 {
|
||||
panic(badLdA)
|
||||
|
||||
// Quick return if possible.
|
||||
if n == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// Quick return if possible
|
||||
if n == 0 || (alpha == 0 && beta == 1) {
|
||||
// For zero matrix size the following slice length checks are trivially satisfied.
|
||||
if len(a) < lda*(n-1)+k+1 {
|
||||
panic(shortA)
|
||||
}
|
||||
if (incX > 0 && len(x) <= (n-1)*incX) || (incX < 0 && len(x) <= (1-n)*incX) {
|
||||
panic(shortX)
|
||||
}
|
||||
if (incY > 0 && len(y) <= (n-1)*incY) || (incY < 0 && len(y) <= (1-n)*incY) {
|
||||
panic(shortY)
|
||||
}
|
||||
|
||||
// Quick return if possible.
|
||||
if alpha == 0 && beta == 1 {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1289,11 +1390,31 @@ func (Implementation) Dsbmv(ul blas.Uplo, n, k int, alpha float64, a []float64,
|
||||
ky = -(lenY - 1) * incY
|
||||
}
|
||||
|
||||
// First form y = beta * y
|
||||
if incY > 0 {
|
||||
Implementation{}.Dscal(lenY, beta, y, incY)
|
||||
} else {
|
||||
Implementation{}.Dscal(lenY, beta, y, -incY)
|
||||
// Form y = beta * y.
|
||||
if beta != 1 {
|
||||
if incY == 1 {
|
||||
if beta == 0 {
|
||||
for i := range y[:n] {
|
||||
y[i] = 0
|
||||
}
|
||||
} else {
|
||||
f64.ScalUnitary(beta, y[:n])
|
||||
}
|
||||
} else {
|
||||
iy := ky
|
||||
if beta == 0 {
|
||||
for i := 0; i < n; i++ {
|
||||
y[iy] = 0
|
||||
iy += incY
|
||||
}
|
||||
} else {
|
||||
if incY > 0 {
|
||||
f64.ScalInc(beta, y, uintptr(n), uintptr(incY))
|
||||
} else {
|
||||
f64.ScalInc(beta, y, uintptr(n), uintptr(-incY))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if alpha == 0 {
|
||||
@@ -1393,16 +1514,28 @@ func (Implementation) Dsyr(ul blas.Uplo, n int, alpha float64, x []float64, incX
|
||||
if n < 0 {
|
||||
panic(nLT0)
|
||||
}
|
||||
if lda < max(1, n) {
|
||||
panic(badLdA)
|
||||
}
|
||||
if incX == 0 {
|
||||
panic(zeroIncX)
|
||||
}
|
||||
if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) {
|
||||
panic(badX)
|
||||
|
||||
// Quick return if possible.
|
||||
if n == 0 {
|
||||
return
|
||||
}
|
||||
if lda*(n-1)+n > len(a) || lda < max(1, n) {
|
||||
panic(badLdA)
|
||||
|
||||
// For zero matrix size the following slice length checks are trivially satisfied.
|
||||
if (incX > 0 && len(x) <= (n-1)*incX) || (incX < 0 && len(x) <= (1-n)*incX) {
|
||||
panic(shortX)
|
||||
}
|
||||
if alpha == 0 || n == 0 {
|
||||
if len(a) < lda*(n-1)+n {
|
||||
panic(shortA)
|
||||
}
|
||||
|
||||
// Quick return if possible.
|
||||
if alpha == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1479,21 +1612,33 @@ func (Implementation) Dsyr2(ul blas.Uplo, n int, alpha float64, x []float64, inc
|
||||
if n < 0 {
|
||||
panic(nLT0)
|
||||
}
|
||||
if lda < max(1, n) {
|
||||
panic(badLdA)
|
||||
}
|
||||
if incX == 0 {
|
||||
panic(zeroIncX)
|
||||
}
|
||||
if incY == 0 {
|
||||
panic(zeroIncY)
|
||||
}
|
||||
if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) {
|
||||
panic(badX)
|
||||
|
||||
// Quick return if possible.
|
||||
if n == 0 {
|
||||
return
|
||||
}
|
||||
if (incY > 0 && (n-1)*incY >= len(y)) || (incY < 0 && (1-n)*incY >= len(y)) {
|
||||
panic(badY)
|
||||
|
||||
// For zero matrix size the following slice length checks are trivially satisfied.
|
||||
if (incX > 0 && len(x) <= (n-1)*incX) || (incX < 0 && len(x) <= (1-n)*incX) {
|
||||
panic(shortX)
|
||||
}
|
||||
if lda*(n-1)+n > len(a) || lda < max(1, n) {
|
||||
panic(badLdA)
|
||||
if (incY > 0 && len(y) <= (n-1)*incY) || (incY < 0 && len(y) <= (1-n)*incY) {
|
||||
panic(shortY)
|
||||
}
|
||||
if len(a) < lda*(n-1)+n {
|
||||
panic(shortA)
|
||||
}
|
||||
|
||||
// Quick return if possible.
|
||||
if alpha == 0 {
|
||||
return
|
||||
}
|
||||
@@ -1575,7 +1720,6 @@ func (Implementation) Dsyr2(ul blas.Uplo, n int, alpha float64, x []float64, inc
|
||||
// No test for singularity or near-singularity is included in this
|
||||
// routine. Such tests must be performed before calling this routine.
|
||||
func (Implementation) Dtpsv(ul blas.Uplo, tA blas.Transpose, d blas.Diag, n int, ap []float64, x []float64, incX int) {
|
||||
// Verify inputs
|
||||
if ul != blas.Lower && ul != blas.Upper {
|
||||
panic(badUplo)
|
||||
}
|
||||
@@ -1588,18 +1732,23 @@ func (Implementation) Dtpsv(ul blas.Uplo, tA blas.Transpose, d blas.Diag, n int,
|
||||
if n < 0 {
|
||||
panic(nLT0)
|
||||
}
|
||||
if len(ap) < (n*(n+1))/2 {
|
||||
panic(badLdA)
|
||||
}
|
||||
if incX == 0 {
|
||||
panic(zeroIncX)
|
||||
}
|
||||
if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) {
|
||||
panic(badX)
|
||||
}
|
||||
|
||||
// Quick return if possible.
|
||||
if n == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// For zero matrix size the following slice length checks are trivially satisfied.
|
||||
if len(ap) < n*(n+1)/2 {
|
||||
panic(shortAP)
|
||||
}
|
||||
if (incX > 0 && len(x) <= (n-1)*incX) || (incX < 0 && len(x) <= (1-n)*incX) {
|
||||
panic(shortX)
|
||||
}
|
||||
|
||||
var kx int
|
||||
if incX < 0 {
|
||||
kx = -(n - 1) * incX
|
||||
@@ -1748,31 +1897,38 @@ func (Implementation) Dtpsv(ul blas.Uplo, tA blas.Transpose, d blas.Diag, n int,
|
||||
// y = alpha * A * x + beta * y
|
||||
// where A is an n×n symmetric matrix in packed format, x and y are vectors,
|
||||
// and alpha and beta are scalars.
|
||||
func (Implementation) Dspmv(ul blas.Uplo, n int, alpha float64, a []float64, x []float64, incX int, beta float64, y []float64, incY int) {
|
||||
// Verify inputs
|
||||
func (Implementation) Dspmv(ul blas.Uplo, n int, alpha float64, ap []float64, x []float64, incX int, beta float64, y []float64, incY int) {
|
||||
if ul != blas.Lower && ul != blas.Upper {
|
||||
panic(badUplo)
|
||||
}
|
||||
if n < 0 {
|
||||
panic(nLT0)
|
||||
}
|
||||
if len(a) < (n*(n+1))/2 {
|
||||
panic(badLdA)
|
||||
}
|
||||
if incX == 0 {
|
||||
panic(zeroIncX)
|
||||
}
|
||||
if incY == 0 {
|
||||
panic(zeroIncY)
|
||||
}
|
||||
if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) {
|
||||
panic(badX)
|
||||
|
||||
// Quick return if possible.
|
||||
if n == 0 {
|
||||
return
|
||||
}
|
||||
if (incY > 0 && (n-1)*incY >= len(y)) || (incY < 0 && (1-n)*incY >= len(y)) {
|
||||
panic(badY)
|
||||
|
||||
// For zero matrix size the following slice length checks are trivially satisfied.
|
||||
if len(ap) < n*(n+1)/2 {
|
||||
panic(shortAP)
|
||||
}
|
||||
// Quick return if possible
|
||||
if n == 0 || (alpha == 0 && beta == 1) {
|
||||
if (incX > 0 && len(x) <= (n-1)*incX) || (incX < 0 && len(x) <= (1-n)*incX) {
|
||||
panic(shortX)
|
||||
}
|
||||
if (incY > 0 && len(y) <= (n-1)*incY) || (incY < 0 && len(y) <= (1-n)*incY) {
|
||||
panic(shortY)
|
||||
}
|
||||
|
||||
// Quick return if possible.
|
||||
if alpha == 0 && beta == 1 {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1785,12 +1941,30 @@ func (Implementation) Dspmv(ul blas.Uplo, n int, alpha float64, a []float64, x [
|
||||
ky = -(n - 1) * incY
|
||||
}
|
||||
|
||||
// Form y = beta * y
|
||||
// Form y = beta * y.
|
||||
if beta != 1 {
|
||||
if incY > 0 {
|
||||
Implementation{}.Dscal(n, beta, y, incY)
|
||||
if incY == 1 {
|
||||
if beta == 0 {
|
||||
for i := range y[:n] {
|
||||
y[i] = 0
|
||||
}
|
||||
} else {
|
||||
f64.ScalUnitary(beta, y[:n])
|
||||
}
|
||||
} else {
|
||||
Implementation{}.Dscal(n, beta, y, -incY)
|
||||
iy := ky
|
||||
if beta == 0 {
|
||||
for i := 0; i < n; i++ {
|
||||
y[iy] = 0
|
||||
iy += incY
|
||||
}
|
||||
} else {
|
||||
if incY > 0 {
|
||||
f64.ScalInc(beta, y, uintptr(n), uintptr(incY))
|
||||
} else {
|
||||
f64.ScalInc(beta, y, uintptr(n), uintptr(-incY))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1799,7 +1973,7 @@ func (Implementation) Dspmv(ul blas.Uplo, n int, alpha float64, a []float64, x [
|
||||
}
|
||||
|
||||
if n == 1 {
|
||||
y[0] += alpha * a[0] * x[0]
|
||||
y[0] += alpha * ap[0] * x[0]
|
||||
return
|
||||
}
|
||||
var offset int // Offset is the index of (i,i).
|
||||
@@ -1808,8 +1982,8 @@ func (Implementation) Dspmv(ul blas.Uplo, n int, alpha float64, a []float64, x [
|
||||
iy := ky
|
||||
for i := 0; i < n; i++ {
|
||||
xv := x[i] * alpha
|
||||
sum := a[offset] * x[i]
|
||||
atmp := a[offset+1 : offset+n-i]
|
||||
sum := ap[offset] * x[i]
|
||||
atmp := ap[offset+1 : offset+n-i]
|
||||
xtmp := x[i+1:]
|
||||
jy := ky + (i+1)*incY
|
||||
for j, v := range atmp {
|
||||
@@ -1827,8 +2001,8 @@ func (Implementation) Dspmv(ul blas.Uplo, n int, alpha float64, a []float64, x [
|
||||
iy := ky
|
||||
for i := 0; i < n; i++ {
|
||||
xv := x[ix] * alpha
|
||||
sum := a[offset] * x[ix]
|
||||
atmp := a[offset+1 : offset+n-i]
|
||||
sum := ap[offset] * x[ix]
|
||||
atmp := ap[offset+1 : offset+n-i]
|
||||
jx := kx + (i+1)*incX
|
||||
jy := ky + (i+1)*incY
|
||||
for _, v := range atmp {
|
||||
@@ -1848,7 +2022,7 @@ func (Implementation) Dspmv(ul blas.Uplo, n int, alpha float64, a []float64, x [
|
||||
iy := ky
|
||||
for i := 0; i < n; i++ {
|
||||
xv := x[i] * alpha
|
||||
atmp := a[offset-i : offset]
|
||||
atmp := ap[offset-i : offset]
|
||||
jy := ky
|
||||
var sum float64
|
||||
for j, v := range atmp {
|
||||
@@ -1856,7 +2030,7 @@ func (Implementation) Dspmv(ul blas.Uplo, n int, alpha float64, a []float64, x [
|
||||
y[jy] += v * xv
|
||||
jy += incY
|
||||
}
|
||||
sum += a[offset] * x[i]
|
||||
sum += ap[offset] * x[i]
|
||||
y[iy] += alpha * sum
|
||||
iy += incY
|
||||
offset += i + 2
|
||||
@@ -1867,7 +2041,7 @@ func (Implementation) Dspmv(ul blas.Uplo, n int, alpha float64, a []float64, x [
|
||||
iy := ky
|
||||
for i := 0; i < n; i++ {
|
||||
xv := x[ix] * alpha
|
||||
atmp := a[offset-i : offset]
|
||||
atmp := ap[offset-i : offset]
|
||||
jx := kx
|
||||
jy := ky
|
||||
var sum float64
|
||||
@@ -1878,7 +2052,7 @@ func (Implementation) Dspmv(ul blas.Uplo, n int, alpha float64, a []float64, x [
|
||||
jy += incY
|
||||
}
|
||||
|
||||
sum += a[offset] * x[ix]
|
||||
sum += ap[offset] * x[ix]
|
||||
y[iy] += alpha * sum
|
||||
ix += incX
|
||||
iy += incY
|
||||
@@ -1890,7 +2064,7 @@ func (Implementation) Dspmv(ul blas.Uplo, n int, alpha float64, a []float64, x [
|
||||
// A += alpha * x * x^T
|
||||
// where A is an n×n symmetric matrix in packed format, x is a vector, and
|
||||
// alpha is a scalar.
|
||||
func (Implementation) Dspr(ul blas.Uplo, n int, alpha float64, x []float64, incX int, a []float64) {
|
||||
func (Implementation) Dspr(ul blas.Uplo, n int, alpha float64, x []float64, incX int, ap []float64) {
|
||||
if ul != blas.Lower && ul != blas.Upper {
|
||||
panic(badUplo)
|
||||
}
|
||||
@@ -1900,15 +2074,25 @@ func (Implementation) Dspr(ul blas.Uplo, n int, alpha float64, x []float64, incX
|
||||
if incX == 0 {
|
||||
panic(zeroIncX)
|
||||
}
|
||||
if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) {
|
||||
panic(badX)
|
||||
}
|
||||
if len(a) < (n*(n+1))/2 {
|
||||
panic(badLdA)
|
||||
}
|
||||
if alpha == 0 || n == 0 {
|
||||
|
||||
// Quick return if possible.
|
||||
if n == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// For zero matrix size the following slice length checks are trivially satisfied.
|
||||
if (incX > 0 && len(x) <= (n-1)*incX) || (incX < 0 && len(x) <= (1-n)*incX) {
|
||||
panic(shortX)
|
||||
}
|
||||
if len(ap) < n*(n+1)/2 {
|
||||
panic(shortAP)
|
||||
}
|
||||
|
||||
// Quick return if possible.
|
||||
if alpha == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
lenX := n
|
||||
var kx int
|
||||
if incX < 0 {
|
||||
@@ -1918,7 +2102,7 @@ func (Implementation) Dspr(ul blas.Uplo, n int, alpha float64, x []float64, incX
|
||||
if ul == blas.Upper {
|
||||
if incX == 1 {
|
||||
for i := 0; i < n; i++ {
|
||||
atmp := a[offset:]
|
||||
atmp := ap[offset:]
|
||||
xv := alpha * x[i]
|
||||
xtmp := x[i:n]
|
||||
for j, v := range xtmp {
|
||||
@@ -1931,7 +2115,7 @@ func (Implementation) Dspr(ul blas.Uplo, n int, alpha float64, x []float64, incX
|
||||
ix := kx
|
||||
for i := 0; i < n; i++ {
|
||||
jx := kx + i*incX
|
||||
atmp := a[offset:]
|
||||
atmp := ap[offset:]
|
||||
xv := alpha * x[ix]
|
||||
for j := 0; j < n-i; j++ {
|
||||
atmp[j] += xv * x[jx]
|
||||
@@ -1944,7 +2128,7 @@ func (Implementation) Dspr(ul blas.Uplo, n int, alpha float64, x []float64, incX
|
||||
}
|
||||
if incX == 1 {
|
||||
for i := 0; i < n; i++ {
|
||||
atmp := a[offset-i:]
|
||||
atmp := ap[offset-i:]
|
||||
xv := alpha * x[i]
|
||||
xtmp := x[:i+1]
|
||||
for j, v := range xtmp {
|
||||
@@ -1957,7 +2141,7 @@ func (Implementation) Dspr(ul blas.Uplo, n int, alpha float64, x []float64, incX
|
||||
ix := kx
|
||||
for i := 0; i < n; i++ {
|
||||
jx := kx
|
||||
atmp := a[offset-i:]
|
||||
atmp := ap[offset-i:]
|
||||
xv := alpha * x[ix]
|
||||
for j := 0; j <= i; j++ {
|
||||
atmp[j] += xv * x[jx]
|
||||
@@ -1985,18 +2169,28 @@ func (Implementation) Dspr2(ul blas.Uplo, n int, alpha float64, x []float64, inc
|
||||
if incY == 0 {
|
||||
panic(zeroIncY)
|
||||
}
|
||||
if (incX > 0 && (n-1)*incX >= len(x)) || (incX < 0 && (1-n)*incX >= len(x)) {
|
||||
panic(badX)
|
||||
|
||||
// Quick return if possible.
|
||||
if n == 0 {
|
||||
return
|
||||
}
|
||||
if (incY > 0 && (n-1)*incY >= len(y)) || (incY < 0 && (1-n)*incY >= len(y)) {
|
||||
panic(badY)
|
||||
|
||||
// For zero matrix size the following slice length checks are trivially satisfied.
|
||||
if (incX > 0 && len(x) <= (n-1)*incX) || (incX < 0 && len(x) <= (1-n)*incX) {
|
||||
panic(shortX)
|
||||
}
|
||||
if len(ap) < (n*(n+1))/2 {
|
||||
panic(badLdA)
|
||||
if (incY > 0 && len(y) <= (n-1)*incY) || (incY < 0 && len(y) <= (1-n)*incY) {
|
||||
panic(shortY)
|
||||
}
|
||||
if len(ap) < n*(n+1)/2 {
|
||||
panic(shortAP)
|
||||
}
|
||||
|
||||
// Quick return if possible.
|
||||
if alpha == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
var ky, kx int
|
||||
if incY < 0 {
|
||||
ky = -(n - 1) * incY
|
||||
1715
vendor/gonum.org/v1/gonum/blas/gonum/level3cmplx128.go
generated
vendored
Normal file
1715
vendor/gonum.org/v1/gonum/blas/gonum/level3cmplx128.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1735
vendor/gonum.org/v1/gonum/blas/gonum/level3cmplx64.go
generated
vendored
Normal file
1735
vendor/gonum.org/v1/gonum/blas/gonum/level3cmplx64.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
@@ -46,26 +46,30 @@ func (Implementation) Strsm(s blas.Side, ul blas.Uplo, tA blas.Transpose, d blas
|
||||
if n < 0 {
|
||||
panic(nLT0)
|
||||
}
|
||||
if ldb < n {
|
||||
panic(badLdB)
|
||||
}
|
||||
var k int
|
||||
k := n
|
||||
if s == blas.Left {
|
||||
k = m
|
||||
} else {
|
||||
k = n
|
||||
}
|
||||
if lda*(k-1)+k > len(a) || lda < max(1, k) {
|
||||
if lda < max(1, k) {
|
||||
panic(badLdA)
|
||||
}
|
||||
if ldb*(m-1)+n > len(b) || ldb < max(1, n) {
|
||||
if ldb < max(1, n) {
|
||||
panic(badLdB)
|
||||
}
|
||||
|
||||
// Quick return if possible.
|
||||
if m == 0 || n == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// For zero matrix size the following slice length checks are trivially satisfied.
|
||||
if len(a) < lda*(k-1)+k {
|
||||
panic(shortA)
|
||||
}
|
||||
if len(b) < ldb*(m-1)+n {
|
||||
panic(shortB)
|
||||
}
|
||||
|
||||
if alpha == 0 {
|
||||
for i := 0; i < m; i++ {
|
||||
btmp := b[i*ldb : i*ldb+n]
|
||||
@@ -82,21 +86,17 @@ func (Implementation) Strsm(s blas.Side, ul blas.Uplo, tA blas.Transpose, d blas
|
||||
for i := m - 1; i >= 0; i-- {
|
||||
btmp := b[i*ldb : i*ldb+n]
|
||||
if alpha != 1 {
|
||||
for j := range btmp {
|
||||
btmp[j] *= alpha
|
||||
}
|
||||
f32.ScalUnitary(alpha, btmp)
|
||||
}
|
||||
for ka, va := range a[i*lda+i+1 : i*lda+m] {
|
||||
k := ka + i + 1
|
||||
if va != 0 {
|
||||
f32.AxpyUnitaryTo(btmp, -va, b[k*ldb:k*ldb+n], btmp)
|
||||
k := ka + i + 1
|
||||
f32.AxpyUnitary(-va, b[k*ldb:k*ldb+n], btmp)
|
||||
}
|
||||
}
|
||||
if nonUnit {
|
||||
tmp := 1 / a[i*lda+i]
|
||||
for j := 0; j < n; j++ {
|
||||
btmp[j] *= tmp
|
||||
}
|
||||
f32.ScalUnitary(tmp, btmp)
|
||||
}
|
||||
}
|
||||
return
|
||||
@@ -104,20 +104,16 @@ func (Implementation) Strsm(s blas.Side, ul blas.Uplo, tA blas.Transpose, d blas
|
||||
for i := 0; i < m; i++ {
|
||||
btmp := b[i*ldb : i*ldb+n]
|
||||
if alpha != 1 {
|
||||
for j := 0; j < n; j++ {
|
||||
btmp[j] *= alpha
|
||||
}
|
||||
f32.ScalUnitary(alpha, btmp)
|
||||
}
|
||||
for k, va := range a[i*lda : i*lda+i] {
|
||||
if va != 0 {
|
||||
f32.AxpyUnitaryTo(btmp, -va, b[k*ldb:k*ldb+n], btmp)
|
||||
f32.AxpyUnitary(-va, b[k*ldb:k*ldb+n], btmp)
|
||||
}
|
||||
}
|
||||
if nonUnit {
|
||||
tmp := 1 / a[i*lda+i]
|
||||
for j := 0; j < n; j++ {
|
||||
btmp[j] *= tmp
|
||||
}
|
||||
f32.ScalUnitary(tmp, btmp)
|
||||
}
|
||||
}
|
||||
return
|
||||
@@ -128,21 +124,16 @@ func (Implementation) Strsm(s blas.Side, ul blas.Uplo, tA blas.Transpose, d blas
|
||||
btmpk := b[k*ldb : k*ldb+n]
|
||||
if nonUnit {
|
||||
tmp := 1 / a[k*lda+k]
|
||||
for j := 0; j < n; j++ {
|
||||
btmpk[j] *= tmp
|
||||
}
|
||||
f32.ScalUnitary(tmp, btmpk)
|
||||
}
|
||||
for ia, va := range a[k*lda+k+1 : k*lda+m] {
|
||||
i := ia + k + 1
|
||||
if va != 0 {
|
||||
btmp := b[i*ldb : i*ldb+n]
|
||||
f32.AxpyUnitaryTo(btmp, -va, btmpk, btmp)
|
||||
i := ia + k + 1
|
||||
f32.AxpyUnitary(-va, btmpk, b[i*ldb:i*ldb+n])
|
||||
}
|
||||
}
|
||||
if alpha != 1 {
|
||||
for j := 0; j < n; j++ {
|
||||
btmpk[j] *= alpha
|
||||
}
|
||||
f32.ScalUnitary(alpha, btmpk)
|
||||
}
|
||||
}
|
||||
return
|
||||
@@ -151,20 +142,15 @@ func (Implementation) Strsm(s blas.Side, ul blas.Uplo, tA blas.Transpose, d blas
|
||||
btmpk := b[k*ldb : k*ldb+n]
|
||||
if nonUnit {
|
||||
tmp := 1 / a[k*lda+k]
|
||||
for j := 0; j < n; j++ {
|
||||
btmpk[j] *= tmp
|
||||
}
|
||||
f32.ScalUnitary(tmp, btmpk)
|
||||
}
|
||||
for i, va := range a[k*lda : k*lda+k] {
|
||||
if va != 0 {
|
||||
btmp := b[i*ldb : i*ldb+n]
|
||||
f32.AxpyUnitaryTo(btmp, -va, btmpk, btmp)
|
||||
f32.AxpyUnitary(-va, btmpk, b[i*ldb:i*ldb+n])
|
||||
}
|
||||
}
|
||||
if alpha != 1 {
|
||||
for j := 0; j < n; j++ {
|
||||
btmpk[j] *= alpha
|
||||
}
|
||||
f32.ScalUnitary(alpha, btmpk)
|
||||
}
|
||||
}
|
||||
return
|
||||
@@ -175,38 +161,33 @@ func (Implementation) Strsm(s blas.Side, ul blas.Uplo, tA blas.Transpose, d blas
|
||||
for i := 0; i < m; i++ {
|
||||
btmp := b[i*ldb : i*ldb+n]
|
||||
if alpha != 1 {
|
||||
for j := 0; j < n; j++ {
|
||||
btmp[j] *= alpha
|
||||
}
|
||||
f32.ScalUnitary(alpha, btmp)
|
||||
}
|
||||
for k, vb := range btmp {
|
||||
if vb != 0 {
|
||||
if btmp[k] != 0 {
|
||||
if nonUnit {
|
||||
btmp[k] /= a[k*lda+k]
|
||||
}
|
||||
btmpk := btmp[k+1 : n]
|
||||
f32.AxpyUnitaryTo(btmpk, -btmp[k], a[k*lda+k+1:k*lda+n], btmpk)
|
||||
}
|
||||
if vb == 0 {
|
||||
continue
|
||||
}
|
||||
if nonUnit {
|
||||
btmp[k] /= a[k*lda+k]
|
||||
}
|
||||
f32.AxpyUnitary(-btmp[k], a[k*lda+k+1:k*lda+n], btmp[k+1:n])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
for i := 0; i < m; i++ {
|
||||
btmp := b[i*lda : i*lda+n]
|
||||
btmp := b[i*ldb : i*ldb+n]
|
||||
if alpha != 1 {
|
||||
for j := 0; j < n; j++ {
|
||||
btmp[j] *= alpha
|
||||
}
|
||||
f32.ScalUnitary(alpha, btmp)
|
||||
}
|
||||
for k := n - 1; k >= 0; k-- {
|
||||
if btmp[k] != 0 {
|
||||
if nonUnit {
|
||||
btmp[k] /= a[k*lda+k]
|
||||
}
|
||||
f32.AxpyUnitaryTo(btmp, -btmp[k], a[k*lda:k*lda+k], btmp)
|
||||
if btmp[k] == 0 {
|
||||
continue
|
||||
}
|
||||
if nonUnit {
|
||||
btmp[k] /= a[k*lda+k]
|
||||
}
|
||||
f32.AxpyUnitary(-btmp[k], a[k*lda:k*lda+k], btmp[:k])
|
||||
}
|
||||
}
|
||||
return
|
||||
@@ -214,7 +195,7 @@ func (Implementation) Strsm(s blas.Side, ul blas.Uplo, tA blas.Transpose, d blas
|
||||
// Cases where a is transposed.
|
||||
if ul == blas.Upper {
|
||||
for i := 0; i < m; i++ {
|
||||
btmp := b[i*lda : i*lda+n]
|
||||
btmp := b[i*ldb : i*ldb+n]
|
||||
for j := n - 1; j >= 0; j-- {
|
||||
tmp := alpha*btmp[j] - f32.DotUnitary(a[j*lda+j+1:j*lda+n], btmp[j+1:])
|
||||
if nonUnit {
|
||||
@@ -226,9 +207,9 @@ func (Implementation) Strsm(s blas.Side, ul blas.Uplo, tA blas.Transpose, d blas
|
||||
return
|
||||
}
|
||||
for i := 0; i < m; i++ {
|
||||
btmp := b[i*lda : i*lda+n]
|
||||
btmp := b[i*ldb : i*ldb+n]
|
||||
for j := 0; j < n; j++ {
|
||||
tmp := alpha*btmp[j] - f32.DotUnitary(a[j*lda:j*lda+j], btmp)
|
||||
tmp := alpha*btmp[j] - f32.DotUnitary(a[j*lda:j*lda+j], btmp[:j])
|
||||
if nonUnit {
|
||||
tmp /= a[j*lda+j]
|
||||
}
|
||||
@@ -246,7 +227,7 @@ func (Implementation) Strsm(s blas.Side, ul blas.Uplo, tA blas.Transpose, d blas
|
||||
// Float32 implementations are autogenerated and not directly tested.
|
||||
func (Implementation) Ssymm(s blas.Side, ul blas.Uplo, m, n int, alpha float32, a []float32, lda int, b []float32, ldb int, beta float32, c []float32, ldc int) {
|
||||
if s != blas.Right && s != blas.Left {
|
||||
panic("goblas: bad side")
|
||||
panic(badSide)
|
||||
}
|
||||
if ul != blas.Lower && ul != blas.Upper {
|
||||
panic(badUplo)
|
||||
@@ -257,27 +238,41 @@ func (Implementation) Ssymm(s blas.Side, ul blas.Uplo, m, n int, alpha float32,
|
||||
if n < 0 {
|
||||
panic(nLT0)
|
||||
}
|
||||
var k int
|
||||
k := n
|
||||
if s == blas.Left {
|
||||
k = m
|
||||
} else {
|
||||
k = n
|
||||
}
|
||||
if lda*(k-1)+k > len(a) || lda < max(1, k) {
|
||||
if lda < max(1, k) {
|
||||
panic(badLdA)
|
||||
}
|
||||
if ldb*(m-1)+n > len(b) || ldb < max(1, n) {
|
||||
if ldb < max(1, n) {
|
||||
panic(badLdB)
|
||||
}
|
||||
if ldc*(m-1)+n > len(c) || ldc < max(1, n) {
|
||||
if ldc < max(1, n) {
|
||||
panic(badLdC)
|
||||
}
|
||||
|
||||
// Quick return if possible.
|
||||
if m == 0 || n == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// For zero matrix size the following slice length checks are trivially satisfied.
|
||||
if len(a) < lda*(k-1)+k {
|
||||
panic(shortA)
|
||||
}
|
||||
if len(b) < ldb*(m-1)+n {
|
||||
panic(shortB)
|
||||
}
|
||||
if len(c) < ldc*(m-1)+n {
|
||||
panic(shortC)
|
||||
}
|
||||
|
||||
// Quick return if possible.
|
||||
if alpha == 0 && beta == 1 {
|
||||
return
|
||||
}
|
||||
|
||||
if alpha == 0 {
|
||||
if beta == 0 {
|
||||
for i := 0; i < m; i++ {
|
||||
@@ -316,8 +311,7 @@ func (Implementation) Ssymm(s blas.Side, ul blas.Uplo, m, n int, alpha float32,
|
||||
atmp = a[i*lda+k]
|
||||
}
|
||||
atmp *= alpha
|
||||
ctmp := c[i*ldc : i*ldc+n]
|
||||
f32.AxpyUnitaryTo(ctmp, atmp, b[k*ldb:k*ldb+n], ctmp)
|
||||
f32.AxpyUnitary(atmp, b[k*ldb:k*ldb+n], ctmp)
|
||||
}
|
||||
for k := i + 1; k < m; k++ {
|
||||
var atmp float32
|
||||
@@ -327,8 +321,7 @@ func (Implementation) Ssymm(s blas.Side, ul blas.Uplo, m, n int, alpha float32,
|
||||
atmp = a[k*lda+i]
|
||||
}
|
||||
atmp *= alpha
|
||||
ctmp := c[i*ldc : i*ldc+n]
|
||||
f32.AxpyUnitaryTo(ctmp, atmp, b[k*ldb:k*ldb+n], ctmp)
|
||||
f32.AxpyUnitary(atmp, b[k*ldb:k*ldb+n], ctmp)
|
||||
}
|
||||
}
|
||||
return
|
||||
@@ -388,21 +381,30 @@ func (Implementation) Ssyrk(ul blas.Uplo, tA blas.Transpose, n, k int, alpha flo
|
||||
if k < 0 {
|
||||
panic(kLT0)
|
||||
}
|
||||
if ldc < n {
|
||||
panic(badLdC)
|
||||
}
|
||||
var row, col int
|
||||
row, col := k, n
|
||||
if tA == blas.NoTrans {
|
||||
row, col = n, k
|
||||
} else {
|
||||
row, col = k, n
|
||||
}
|
||||
if lda*(row-1)+col > len(a) || lda < max(1, col) {
|
||||
if lda < max(1, col) {
|
||||
panic(badLdA)
|
||||
}
|
||||
if ldc*(n-1)+n > len(c) || ldc < max(1, n) {
|
||||
if ldc < max(1, n) {
|
||||
panic(badLdC)
|
||||
}
|
||||
|
||||
// Quick return if possible.
|
||||
if n == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// For zero matrix size the following slice length checks are trivially satisfied.
|
||||
if len(a) < lda*(row-1)+col {
|
||||
panic(shortA)
|
||||
}
|
||||
if len(c) < ldc*(n-1)+n {
|
||||
panic(shortC)
|
||||
}
|
||||
|
||||
if alpha == 0 {
|
||||
if beta == 0 {
|
||||
if ul == blas.Upper {
|
||||
@@ -444,17 +446,31 @@ func (Implementation) Ssyrk(ul blas.Uplo, tA blas.Transpose, n, k int, alpha flo
|
||||
for i := 0; i < n; i++ {
|
||||
ctmp := c[i*ldc+i : i*ldc+n]
|
||||
atmp := a[i*lda : i*lda+k]
|
||||
for jc, vc := range ctmp {
|
||||
j := jc + i
|
||||
ctmp[jc] = vc*beta + alpha*f32.DotUnitary(atmp, a[j*lda:j*lda+k])
|
||||
if beta == 0 {
|
||||
for jc := range ctmp {
|
||||
j := jc + i
|
||||
ctmp[jc] = alpha * f32.DotUnitary(atmp, a[j*lda:j*lda+k])
|
||||
}
|
||||
} else {
|
||||
for jc, vc := range ctmp {
|
||||
j := jc + i
|
||||
ctmp[jc] = vc*beta + alpha*f32.DotUnitary(atmp, a[j*lda:j*lda+k])
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
for i := 0; i < n; i++ {
|
||||
ctmp := c[i*ldc : i*ldc+i+1]
|
||||
atmp := a[i*lda : i*lda+k]
|
||||
for j, vc := range c[i*ldc : i*ldc+i+1] {
|
||||
c[i*ldc+j] = vc*beta + alpha*f32.DotUnitary(a[j*lda:j*lda+k], atmp)
|
||||
if beta == 0 {
|
||||
for j := range ctmp {
|
||||
ctmp[j] = alpha * f32.DotUnitary(a[j*lda:j*lda+k], atmp)
|
||||
}
|
||||
} else {
|
||||
for j, vc := range ctmp {
|
||||
ctmp[j] = vc*beta + alpha*f32.DotUnitary(a[j*lda:j*lda+k], atmp)
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
@@ -463,7 +479,11 @@ func (Implementation) Ssyrk(ul blas.Uplo, tA blas.Transpose, n, k int, alpha flo
|
||||
if ul == blas.Upper {
|
||||
for i := 0; i < n; i++ {
|
||||
ctmp := c[i*ldc+i : i*ldc+n]
|
||||
if beta != 1 {
|
||||
if beta == 0 {
|
||||
for j := range ctmp {
|
||||
ctmp[j] = 0
|
||||
}
|
||||
} else if beta != 1 {
|
||||
for j := range ctmp {
|
||||
ctmp[j] *= beta
|
||||
}
|
||||
@@ -471,7 +491,7 @@ func (Implementation) Ssyrk(ul blas.Uplo, tA blas.Transpose, n, k int, alpha flo
|
||||
for l := 0; l < k; l++ {
|
||||
tmp := alpha * a[l*lda+i]
|
||||
if tmp != 0 {
|
||||
f32.AxpyUnitaryTo(ctmp, tmp, a[l*lda+i:l*lda+n], ctmp)
|
||||
f32.AxpyUnitary(tmp, a[l*lda+i:l*lda+n], ctmp)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -479,7 +499,7 @@ func (Implementation) Ssyrk(ul blas.Uplo, tA blas.Transpose, n, k int, alpha flo
|
||||
}
|
||||
for i := 0; i < n; i++ {
|
||||
ctmp := c[i*ldc : i*ldc+i+1]
|
||||
if beta != 0 {
|
||||
if beta != 1 {
|
||||
for j := range ctmp {
|
||||
ctmp[j] *= beta
|
||||
}
|
||||
@@ -487,7 +507,7 @@ func (Implementation) Ssyrk(ul blas.Uplo, tA blas.Transpose, n, k int, alpha flo
|
||||
for l := 0; l < k; l++ {
|
||||
tmp := alpha * a[l*lda+i]
|
||||
if tmp != 0 {
|
||||
f32.AxpyUnitaryTo(ctmp, tmp, a[l*lda:l*lda+i+1], ctmp)
|
||||
f32.AxpyUnitary(tmp, a[l*lda:l*lda+i+1], ctmp)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -513,24 +533,36 @@ func (Implementation) Ssyr2k(ul blas.Uplo, tA blas.Transpose, n, k int, alpha fl
|
||||
if k < 0 {
|
||||
panic(kLT0)
|
||||
}
|
||||
if ldc < n {
|
||||
panic(badLdC)
|
||||
}
|
||||
var row, col int
|
||||
row, col := k, n
|
||||
if tA == blas.NoTrans {
|
||||
row, col = n, k
|
||||
} else {
|
||||
row, col = k, n
|
||||
}
|
||||
if lda*(row-1)+col > len(a) || lda < max(1, col) {
|
||||
if lda < max(1, col) {
|
||||
panic(badLdA)
|
||||
}
|
||||
if ldb*(row-1)+col > len(b) || ldb < max(1, col) {
|
||||
if ldb < max(1, col) {
|
||||
panic(badLdB)
|
||||
}
|
||||
if ldc*(n-1)+n > len(c) || ldc < max(1, n) {
|
||||
if ldc < max(1, n) {
|
||||
panic(badLdC)
|
||||
}
|
||||
|
||||
// Quick return if possible.
|
||||
if n == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// For zero matrix size the following slice length checks are trivially satisfied.
|
||||
if len(a) < lda*(row-1)+col {
|
||||
panic(shortA)
|
||||
}
|
||||
if len(b) < ldb*(row-1)+col {
|
||||
panic(shortB)
|
||||
}
|
||||
if len(c) < ldc*(n-1)+n {
|
||||
panic(shortC)
|
||||
}
|
||||
|
||||
if alpha == 0 {
|
||||
if beta == 0 {
|
||||
if ul == blas.Upper {
|
||||
@@ -613,7 +645,7 @@ func (Implementation) Ssyr2k(ul blas.Uplo, tA blas.Transpose, n, k int, alpha fl
|
||||
}
|
||||
}
|
||||
for l := 0; l < k; l++ {
|
||||
tmp1 := alpha * b[l*lda+i]
|
||||
tmp1 := alpha * b[l*ldb+i]
|
||||
tmp2 := alpha * a[l*lda+i]
|
||||
btmp := b[l*ldb+i : l*ldb+n]
|
||||
if tmp1 != 0 || tmp2 != 0 {
|
||||
@@ -633,7 +665,7 @@ func (Implementation) Ssyr2k(ul blas.Uplo, tA blas.Transpose, n, k int, alpha fl
|
||||
}
|
||||
}
|
||||
for l := 0; l < k; l++ {
|
||||
tmp1 := alpha * b[l*lda+i]
|
||||
tmp1 := alpha * b[l*ldb+i]
|
||||
tmp2 := alpha * a[l*lda+i]
|
||||
btmp := b[l*ldb : l*ldb+i+1]
|
||||
if tmp1 != 0 || tmp2 != 0 {
|
||||
@@ -672,18 +704,30 @@ func (Implementation) Strmm(s blas.Side, ul blas.Uplo, tA blas.Transpose, d blas
|
||||
if n < 0 {
|
||||
panic(nLT0)
|
||||
}
|
||||
var k int
|
||||
k := n
|
||||
if s == blas.Left {
|
||||
k = m
|
||||
} else {
|
||||
k = n
|
||||
}
|
||||
if lda*(k-1)+k > len(a) || lda < max(1, k) {
|
||||
if lda < max(1, k) {
|
||||
panic(badLdA)
|
||||
}
|
||||
if ldb*(m-1)+n > len(b) || ldb < max(1, n) {
|
||||
if ldb < max(1, n) {
|
||||
panic(badLdB)
|
||||
}
|
||||
|
||||
// Quick return if possible.
|
||||
if m == 0 || n == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// For zero matrix size the following slice length checks are trivially satisfied.
|
||||
if len(a) < lda*(k-1)+k {
|
||||
panic(shortA)
|
||||
}
|
||||
if len(b) < ldb*(m-1)+n {
|
||||
panic(shortB)
|
||||
}
|
||||
|
||||
if alpha == 0 {
|
||||
for i := 0; i < m; i++ {
|
||||
btmp := b[i*ldb : i*ldb+n]
|
||||
@@ -704,14 +748,11 @@ func (Implementation) Strmm(s blas.Side, ul blas.Uplo, tA blas.Transpose, d blas
|
||||
tmp *= a[i*lda+i]
|
||||
}
|
||||
btmp := b[i*ldb : i*ldb+n]
|
||||
for j := range btmp {
|
||||
btmp[j] *= tmp
|
||||
}
|
||||
f32.ScalUnitary(tmp, btmp)
|
||||
for ka, va := range a[i*lda+i+1 : i*lda+m] {
|
||||
k := ka + i + 1
|
||||
tmp := alpha * va
|
||||
if tmp != 0 {
|
||||
f32.AxpyUnitaryTo(btmp, tmp, b[k*ldb:k*ldb+n], btmp)
|
||||
if va != 0 {
|
||||
f32.AxpyUnitary(alpha*va, b[k*ldb:k*ldb+n], btmp)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -723,13 +764,10 @@ func (Implementation) Strmm(s blas.Side, ul blas.Uplo, tA blas.Transpose, d blas
|
||||
tmp *= a[i*lda+i]
|
||||
}
|
||||
btmp := b[i*ldb : i*ldb+n]
|
||||
for j := range btmp {
|
||||
btmp[j] *= tmp
|
||||
}
|
||||
f32.ScalUnitary(tmp, btmp)
|
||||
for k, va := range a[i*lda : i*lda+i] {
|
||||
tmp := alpha * va
|
||||
if tmp != 0 {
|
||||
f32.AxpyUnitaryTo(btmp, tmp, b[k*ldb:k*ldb+n], btmp)
|
||||
if va != 0 {
|
||||
f32.AxpyUnitary(alpha*va, b[k*ldb:k*ldb+n], btmp)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -742,9 +780,8 @@ func (Implementation) Strmm(s blas.Side, ul blas.Uplo, tA blas.Transpose, d blas
|
||||
for ia, va := range a[k*lda+k+1 : k*lda+m] {
|
||||
i := ia + k + 1
|
||||
btmp := b[i*ldb : i*ldb+n]
|
||||
tmp := alpha * va
|
||||
if tmp != 0 {
|
||||
f32.AxpyUnitaryTo(btmp, tmp, btmpk, btmp)
|
||||
if va != 0 {
|
||||
f32.AxpyUnitary(alpha*va, btmpk, btmp)
|
||||
}
|
||||
}
|
||||
tmp := alpha
|
||||
@@ -752,9 +789,7 @@ func (Implementation) Strmm(s blas.Side, ul blas.Uplo, tA blas.Transpose, d blas
|
||||
tmp *= a[k*lda+k]
|
||||
}
|
||||
if tmp != 1 {
|
||||
for j := 0; j < n; j++ {
|
||||
btmpk[j] *= tmp
|
||||
}
|
||||
f32.ScalUnitary(tmp, btmpk)
|
||||
}
|
||||
}
|
||||
return
|
||||
@@ -763,9 +798,8 @@ func (Implementation) Strmm(s blas.Side, ul blas.Uplo, tA blas.Transpose, d blas
|
||||
btmpk := b[k*ldb : k*ldb+n]
|
||||
for i, va := range a[k*lda : k*lda+k] {
|
||||
btmp := b[i*ldb : i*ldb+n]
|
||||
tmp := alpha * va
|
||||
if tmp != 0 {
|
||||
f32.AxpyUnitaryTo(btmp, tmp, btmpk, btmp)
|
||||
if va != 0 {
|
||||
f32.AxpyUnitary(alpha*va, btmpk, btmp)
|
||||
}
|
||||
}
|
||||
tmp := alpha
|
||||
@@ -773,9 +807,7 @@ func (Implementation) Strmm(s blas.Side, ul blas.Uplo, tA blas.Transpose, d blas
|
||||
tmp *= a[k*lda+k]
|
||||
}
|
||||
if tmp != 1 {
|
||||
for j := 0; j < n; j++ {
|
||||
btmpk[j] *= tmp
|
||||
}
|
||||
f32.ScalUnitary(tmp, btmpk)
|
||||
}
|
||||
}
|
||||
return
|
||||
@@ -787,16 +819,14 @@ func (Implementation) Strmm(s blas.Side, ul blas.Uplo, tA blas.Transpose, d blas
|
||||
btmp := b[i*ldb : i*ldb+n]
|
||||
for k := n - 1; k >= 0; k-- {
|
||||
tmp := alpha * btmp[k]
|
||||
if tmp != 0 {
|
||||
btmp[k] = tmp
|
||||
if nonUnit {
|
||||
btmp[k] *= a[k*lda+k]
|
||||
}
|
||||
for ja, v := range a[k*lda+k+1 : k*lda+n] {
|
||||
j := ja + k + 1
|
||||
btmp[j] += tmp * v
|
||||
}
|
||||
if tmp == 0 {
|
||||
continue
|
||||
}
|
||||
btmp[k] = tmp
|
||||
if nonUnit {
|
||||
btmp[k] *= a[k*lda+k]
|
||||
}
|
||||
f32.AxpyUnitary(tmp, a[k*lda+k+1:k*lda+n], btmp[k+1:n])
|
||||
}
|
||||
}
|
||||
return
|
||||
@@ -805,13 +835,14 @@ func (Implementation) Strmm(s blas.Side, ul blas.Uplo, tA blas.Transpose, d blas
|
||||
btmp := b[i*ldb : i*ldb+n]
|
||||
for k := 0; k < n; k++ {
|
||||
tmp := alpha * btmp[k]
|
||||
if tmp != 0 {
|
||||
btmp[k] = tmp
|
||||
if nonUnit {
|
||||
btmp[k] *= a[k*lda+k]
|
||||
}
|
||||
f32.AxpyUnitaryTo(btmp, tmp, a[k*lda:k*lda+k], btmp)
|
||||
if tmp == 0 {
|
||||
continue
|
||||
}
|
||||
btmp[k] = tmp
|
||||
if nonUnit {
|
||||
btmp[k] *= a[k*lda+k]
|
||||
}
|
||||
f32.AxpyUnitary(tmp, a[k*lda:k*lda+k], btmp[:k])
|
||||
}
|
||||
}
|
||||
return
|
||||
@@ -42,26 +42,30 @@ func (Implementation) Dtrsm(s blas.Side, ul blas.Uplo, tA blas.Transpose, d blas
|
||||
if n < 0 {
|
||||
panic(nLT0)
|
||||
}
|
||||
if ldb < n {
|
||||
panic(badLdB)
|
||||
}
|
||||
var k int
|
||||
k := n
|
||||
if s == blas.Left {
|
||||
k = m
|
||||
} else {
|
||||
k = n
|
||||
}
|
||||
if lda*(k-1)+k > len(a) || lda < max(1, k) {
|
||||
if lda < max(1, k) {
|
||||
panic(badLdA)
|
||||
}
|
||||
if ldb*(m-1)+n > len(b) || ldb < max(1, n) {
|
||||
if ldb < max(1, n) {
|
||||
panic(badLdB)
|
||||
}
|
||||
|
||||
// Quick return if possible.
|
||||
if m == 0 || n == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// For zero matrix size the following slice length checks are trivially satisfied.
|
||||
if len(a) < lda*(k-1)+k {
|
||||
panic(shortA)
|
||||
}
|
||||
if len(b) < ldb*(m-1)+n {
|
||||
panic(shortB)
|
||||
}
|
||||
|
||||
if alpha == 0 {
|
||||
for i := 0; i < m; i++ {
|
||||
btmp := b[i*ldb : i*ldb+n]
|
||||
@@ -78,21 +82,17 @@ func (Implementation) Dtrsm(s blas.Side, ul blas.Uplo, tA blas.Transpose, d blas
|
||||
for i := m - 1; i >= 0; i-- {
|
||||
btmp := b[i*ldb : i*ldb+n]
|
||||
if alpha != 1 {
|
||||
for j := range btmp {
|
||||
btmp[j] *= alpha
|
||||
}
|
||||
f64.ScalUnitary(alpha, btmp)
|
||||
}
|
||||
for ka, va := range a[i*lda+i+1 : i*lda+m] {
|
||||
k := ka + i + 1
|
||||
if va != 0 {
|
||||
f64.AxpyUnitaryTo(btmp, -va, b[k*ldb:k*ldb+n], btmp)
|
||||
k := ka + i + 1
|
||||
f64.AxpyUnitary(-va, b[k*ldb:k*ldb+n], btmp)
|
||||
}
|
||||
}
|
||||
if nonUnit {
|
||||
tmp := 1 / a[i*lda+i]
|
||||
for j := 0; j < n; j++ {
|
||||
btmp[j] *= tmp
|
||||
}
|
||||
f64.ScalUnitary(tmp, btmp)
|
||||
}
|
||||
}
|
||||
return
|
||||
@@ -100,20 +100,16 @@ func (Implementation) Dtrsm(s blas.Side, ul blas.Uplo, tA blas.Transpose, d blas
|
||||
for i := 0; i < m; i++ {
|
||||
btmp := b[i*ldb : i*ldb+n]
|
||||
if alpha != 1 {
|
||||
for j := 0; j < n; j++ {
|
||||
btmp[j] *= alpha
|
||||
}
|
||||
f64.ScalUnitary(alpha, btmp)
|
||||
}
|
||||
for k, va := range a[i*lda : i*lda+i] {
|
||||
if va != 0 {
|
||||
f64.AxpyUnitaryTo(btmp, -va, b[k*ldb:k*ldb+n], btmp)
|
||||
f64.AxpyUnitary(-va, b[k*ldb:k*ldb+n], btmp)
|
||||
}
|
||||
}
|
||||
if nonUnit {
|
||||
tmp := 1 / a[i*lda+i]
|
||||
for j := 0; j < n; j++ {
|
||||
btmp[j] *= tmp
|
||||
}
|
||||
f64.ScalUnitary(tmp, btmp)
|
||||
}
|
||||
}
|
||||
return
|
||||
@@ -124,21 +120,16 @@ func (Implementation) Dtrsm(s blas.Side, ul blas.Uplo, tA blas.Transpose, d blas
|
||||
btmpk := b[k*ldb : k*ldb+n]
|
||||
if nonUnit {
|
||||
tmp := 1 / a[k*lda+k]
|
||||
for j := 0; j < n; j++ {
|
||||
btmpk[j] *= tmp
|
||||
}
|
||||
f64.ScalUnitary(tmp, btmpk)
|
||||
}
|
||||
for ia, va := range a[k*lda+k+1 : k*lda+m] {
|
||||
i := ia + k + 1
|
||||
if va != 0 {
|
||||
btmp := b[i*ldb : i*ldb+n]
|
||||
f64.AxpyUnitaryTo(btmp, -va, btmpk, btmp)
|
||||
i := ia + k + 1
|
||||
f64.AxpyUnitary(-va, btmpk, b[i*ldb:i*ldb+n])
|
||||
}
|
||||
}
|
||||
if alpha != 1 {
|
||||
for j := 0; j < n; j++ {
|
||||
btmpk[j] *= alpha
|
||||
}
|
||||
f64.ScalUnitary(alpha, btmpk)
|
||||
}
|
||||
}
|
||||
return
|
||||
@@ -147,20 +138,15 @@ func (Implementation) Dtrsm(s blas.Side, ul blas.Uplo, tA blas.Transpose, d blas
|
||||
btmpk := b[k*ldb : k*ldb+n]
|
||||
if nonUnit {
|
||||
tmp := 1 / a[k*lda+k]
|
||||
for j := 0; j < n; j++ {
|
||||
btmpk[j] *= tmp
|
||||
}
|
||||
f64.ScalUnitary(tmp, btmpk)
|
||||
}
|
||||
for i, va := range a[k*lda : k*lda+k] {
|
||||
if va != 0 {
|
||||
btmp := b[i*ldb : i*ldb+n]
|
||||
f64.AxpyUnitaryTo(btmp, -va, btmpk, btmp)
|
||||
f64.AxpyUnitary(-va, btmpk, b[i*ldb:i*ldb+n])
|
||||
}
|
||||
}
|
||||
if alpha != 1 {
|
||||
for j := 0; j < n; j++ {
|
||||
btmpk[j] *= alpha
|
||||
}
|
||||
f64.ScalUnitary(alpha, btmpk)
|
||||
}
|
||||
}
|
||||
return
|
||||
@@ -171,38 +157,33 @@ func (Implementation) Dtrsm(s blas.Side, ul blas.Uplo, tA blas.Transpose, d blas
|
||||
for i := 0; i < m; i++ {
|
||||
btmp := b[i*ldb : i*ldb+n]
|
||||
if alpha != 1 {
|
||||
for j := 0; j < n; j++ {
|
||||
btmp[j] *= alpha
|
||||
}
|
||||
f64.ScalUnitary(alpha, btmp)
|
||||
}
|
||||
for k, vb := range btmp {
|
||||
if vb != 0 {
|
||||
if btmp[k] != 0 {
|
||||
if nonUnit {
|
||||
btmp[k] /= a[k*lda+k]
|
||||
}
|
||||
btmpk := btmp[k+1 : n]
|
||||
f64.AxpyUnitaryTo(btmpk, -btmp[k], a[k*lda+k+1:k*lda+n], btmpk)
|
||||
}
|
||||
if vb == 0 {
|
||||
continue
|
||||
}
|
||||
if nonUnit {
|
||||
btmp[k] /= a[k*lda+k]
|
||||
}
|
||||
f64.AxpyUnitary(-btmp[k], a[k*lda+k+1:k*lda+n], btmp[k+1:n])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
for i := 0; i < m; i++ {
|
||||
btmp := b[i*lda : i*lda+n]
|
||||
btmp := b[i*ldb : i*ldb+n]
|
||||
if alpha != 1 {
|
||||
for j := 0; j < n; j++ {
|
||||
btmp[j] *= alpha
|
||||
}
|
||||
f64.ScalUnitary(alpha, btmp)
|
||||
}
|
||||
for k := n - 1; k >= 0; k-- {
|
||||
if btmp[k] != 0 {
|
||||
if nonUnit {
|
||||
btmp[k] /= a[k*lda+k]
|
||||
}
|
||||
f64.AxpyUnitaryTo(btmp, -btmp[k], a[k*lda:k*lda+k], btmp)
|
||||
if btmp[k] == 0 {
|
||||
continue
|
||||
}
|
||||
if nonUnit {
|
||||
btmp[k] /= a[k*lda+k]
|
||||
}
|
||||
f64.AxpyUnitary(-btmp[k], a[k*lda:k*lda+k], btmp[:k])
|
||||
}
|
||||
}
|
||||
return
|
||||
@@ -210,7 +191,7 @@ func (Implementation) Dtrsm(s blas.Side, ul blas.Uplo, tA blas.Transpose, d blas
|
||||
// Cases where a is transposed.
|
||||
if ul == blas.Upper {
|
||||
for i := 0; i < m; i++ {
|
||||
btmp := b[i*lda : i*lda+n]
|
||||
btmp := b[i*ldb : i*ldb+n]
|
||||
for j := n - 1; j >= 0; j-- {
|
||||
tmp := alpha*btmp[j] - f64.DotUnitary(a[j*lda+j+1:j*lda+n], btmp[j+1:])
|
||||
if nonUnit {
|
||||
@@ -222,9 +203,9 @@ func (Implementation) Dtrsm(s blas.Side, ul blas.Uplo, tA blas.Transpose, d blas
|
||||
return
|
||||
}
|
||||
for i := 0; i < m; i++ {
|
||||
btmp := b[i*lda : i*lda+n]
|
||||
btmp := b[i*ldb : i*ldb+n]
|
||||
for j := 0; j < n; j++ {
|
||||
tmp := alpha*btmp[j] - f64.DotUnitary(a[j*lda:j*lda+j], btmp)
|
||||
tmp := alpha*btmp[j] - f64.DotUnitary(a[j*lda:j*lda+j], btmp[:j])
|
||||
if nonUnit {
|
||||
tmp /= a[j*lda+j]
|
||||
}
|
||||
@@ -240,7 +221,7 @@ func (Implementation) Dtrsm(s blas.Side, ul blas.Uplo, tA blas.Transpose, d blas
|
||||
// is a scalar.
|
||||
func (Implementation) Dsymm(s blas.Side, ul blas.Uplo, m, n int, alpha float64, a []float64, lda int, b []float64, ldb int, beta float64, c []float64, ldc int) {
|
||||
if s != blas.Right && s != blas.Left {
|
||||
panic("goblas: bad side")
|
||||
panic(badSide)
|
||||
}
|
||||
if ul != blas.Lower && ul != blas.Upper {
|
||||
panic(badUplo)
|
||||
@@ -251,27 +232,41 @@ func (Implementation) Dsymm(s blas.Side, ul blas.Uplo, m, n int, alpha float64,
|
||||
if n < 0 {
|
||||
panic(nLT0)
|
||||
}
|
||||
var k int
|
||||
k := n
|
||||
if s == blas.Left {
|
||||
k = m
|
||||
} else {
|
||||
k = n
|
||||
}
|
||||
if lda*(k-1)+k > len(a) || lda < max(1, k) {
|
||||
if lda < max(1, k) {
|
||||
panic(badLdA)
|
||||
}
|
||||
if ldb*(m-1)+n > len(b) || ldb < max(1, n) {
|
||||
if ldb < max(1, n) {
|
||||
panic(badLdB)
|
||||
}
|
||||
if ldc*(m-1)+n > len(c) || ldc < max(1, n) {
|
||||
if ldc < max(1, n) {
|
||||
panic(badLdC)
|
||||
}
|
||||
|
||||
// Quick return if possible.
|
||||
if m == 0 || n == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// For zero matrix size the following slice length checks are trivially satisfied.
|
||||
if len(a) < lda*(k-1)+k {
|
||||
panic(shortA)
|
||||
}
|
||||
if len(b) < ldb*(m-1)+n {
|
||||
panic(shortB)
|
||||
}
|
||||
if len(c) < ldc*(m-1)+n {
|
||||
panic(shortC)
|
||||
}
|
||||
|
||||
// Quick return if possible.
|
||||
if alpha == 0 && beta == 1 {
|
||||
return
|
||||
}
|
||||
|
||||
if alpha == 0 {
|
||||
if beta == 0 {
|
||||
for i := 0; i < m; i++ {
|
||||
@@ -310,8 +305,7 @@ func (Implementation) Dsymm(s blas.Side, ul blas.Uplo, m, n int, alpha float64,
|
||||
atmp = a[i*lda+k]
|
||||
}
|
||||
atmp *= alpha
|
||||
ctmp := c[i*ldc : i*ldc+n]
|
||||
f64.AxpyUnitaryTo(ctmp, atmp, b[k*ldb:k*ldb+n], ctmp)
|
||||
f64.AxpyUnitary(atmp, b[k*ldb:k*ldb+n], ctmp)
|
||||
}
|
||||
for k := i + 1; k < m; k++ {
|
||||
var atmp float64
|
||||
@@ -321,8 +315,7 @@ func (Implementation) Dsymm(s blas.Side, ul blas.Uplo, m, n int, alpha float64,
|
||||
atmp = a[k*lda+i]
|
||||
}
|
||||
atmp *= alpha
|
||||
ctmp := c[i*ldc : i*ldc+n]
|
||||
f64.AxpyUnitaryTo(ctmp, atmp, b[k*ldb:k*ldb+n], ctmp)
|
||||
f64.AxpyUnitary(atmp, b[k*ldb:k*ldb+n], ctmp)
|
||||
}
|
||||
}
|
||||
return
|
||||
@@ -380,21 +373,30 @@ func (Implementation) Dsyrk(ul blas.Uplo, tA blas.Transpose, n, k int, alpha flo
|
||||
if k < 0 {
|
||||
panic(kLT0)
|
||||
}
|
||||
if ldc < n {
|
||||
panic(badLdC)
|
||||
}
|
||||
var row, col int
|
||||
row, col := k, n
|
||||
if tA == blas.NoTrans {
|
||||
row, col = n, k
|
||||
} else {
|
||||
row, col = k, n
|
||||
}
|
||||
if lda*(row-1)+col > len(a) || lda < max(1, col) {
|
||||
if lda < max(1, col) {
|
||||
panic(badLdA)
|
||||
}
|
||||
if ldc*(n-1)+n > len(c) || ldc < max(1, n) {
|
||||
if ldc < max(1, n) {
|
||||
panic(badLdC)
|
||||
}
|
||||
|
||||
// Quick return if possible.
|
||||
if n == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// For zero matrix size the following slice length checks are trivially satisfied.
|
||||
if len(a) < lda*(row-1)+col {
|
||||
panic(shortA)
|
||||
}
|
||||
if len(c) < ldc*(n-1)+n {
|
||||
panic(shortC)
|
||||
}
|
||||
|
||||
if alpha == 0 {
|
||||
if beta == 0 {
|
||||
if ul == blas.Upper {
|
||||
@@ -436,17 +438,31 @@ func (Implementation) Dsyrk(ul blas.Uplo, tA blas.Transpose, n, k int, alpha flo
|
||||
for i := 0; i < n; i++ {
|
||||
ctmp := c[i*ldc+i : i*ldc+n]
|
||||
atmp := a[i*lda : i*lda+k]
|
||||
for jc, vc := range ctmp {
|
||||
j := jc + i
|
||||
ctmp[jc] = vc*beta + alpha*f64.DotUnitary(atmp, a[j*lda:j*lda+k])
|
||||
if beta == 0 {
|
||||
for jc := range ctmp {
|
||||
j := jc + i
|
||||
ctmp[jc] = alpha * f64.DotUnitary(atmp, a[j*lda:j*lda+k])
|
||||
}
|
||||
} else {
|
||||
for jc, vc := range ctmp {
|
||||
j := jc + i
|
||||
ctmp[jc] = vc*beta + alpha*f64.DotUnitary(atmp, a[j*lda:j*lda+k])
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
for i := 0; i < n; i++ {
|
||||
ctmp := c[i*ldc : i*ldc+i+1]
|
||||
atmp := a[i*lda : i*lda+k]
|
||||
for j, vc := range c[i*ldc : i*ldc+i+1] {
|
||||
c[i*ldc+j] = vc*beta + alpha*f64.DotUnitary(a[j*lda:j*lda+k], atmp)
|
||||
if beta == 0 {
|
||||
for j := range ctmp {
|
||||
ctmp[j] = alpha * f64.DotUnitary(a[j*lda:j*lda+k], atmp)
|
||||
}
|
||||
} else {
|
||||
for j, vc := range ctmp {
|
||||
ctmp[j] = vc*beta + alpha*f64.DotUnitary(a[j*lda:j*lda+k], atmp)
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
@@ -455,7 +471,11 @@ func (Implementation) Dsyrk(ul blas.Uplo, tA blas.Transpose, n, k int, alpha flo
|
||||
if ul == blas.Upper {
|
||||
for i := 0; i < n; i++ {
|
||||
ctmp := c[i*ldc+i : i*ldc+n]
|
||||
if beta != 1 {
|
||||
if beta == 0 {
|
||||
for j := range ctmp {
|
||||
ctmp[j] = 0
|
||||
}
|
||||
} else if beta != 1 {
|
||||
for j := range ctmp {
|
||||
ctmp[j] *= beta
|
||||
}
|
||||
@@ -463,7 +483,7 @@ func (Implementation) Dsyrk(ul blas.Uplo, tA blas.Transpose, n, k int, alpha flo
|
||||
for l := 0; l < k; l++ {
|
||||
tmp := alpha * a[l*lda+i]
|
||||
if tmp != 0 {
|
||||
f64.AxpyUnitaryTo(ctmp, tmp, a[l*lda+i:l*lda+n], ctmp)
|
||||
f64.AxpyUnitary(tmp, a[l*lda+i:l*lda+n], ctmp)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -471,7 +491,7 @@ func (Implementation) Dsyrk(ul blas.Uplo, tA blas.Transpose, n, k int, alpha flo
|
||||
}
|
||||
for i := 0; i < n; i++ {
|
||||
ctmp := c[i*ldc : i*ldc+i+1]
|
||||
if beta != 0 {
|
||||
if beta != 1 {
|
||||
for j := range ctmp {
|
||||
ctmp[j] *= beta
|
||||
}
|
||||
@@ -479,7 +499,7 @@ func (Implementation) Dsyrk(ul blas.Uplo, tA blas.Transpose, n, k int, alpha flo
|
||||
for l := 0; l < k; l++ {
|
||||
tmp := alpha * a[l*lda+i]
|
||||
if tmp != 0 {
|
||||
f64.AxpyUnitaryTo(ctmp, tmp, a[l*lda:l*lda+i+1], ctmp)
|
||||
f64.AxpyUnitary(tmp, a[l*lda:l*lda+i+1], ctmp)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -503,24 +523,36 @@ func (Implementation) Dsyr2k(ul blas.Uplo, tA blas.Transpose, n, k int, alpha fl
|
||||
if k < 0 {
|
||||
panic(kLT0)
|
||||
}
|
||||
if ldc < n {
|
||||
panic(badLdC)
|
||||
}
|
||||
var row, col int
|
||||
row, col := k, n
|
||||
if tA == blas.NoTrans {
|
||||
row, col = n, k
|
||||
} else {
|
||||
row, col = k, n
|
||||
}
|
||||
if lda*(row-1)+col > len(a) || lda < max(1, col) {
|
||||
if lda < max(1, col) {
|
||||
panic(badLdA)
|
||||
}
|
||||
if ldb*(row-1)+col > len(b) || ldb < max(1, col) {
|
||||
if ldb < max(1, col) {
|
||||
panic(badLdB)
|
||||
}
|
||||
if ldc*(n-1)+n > len(c) || ldc < max(1, n) {
|
||||
if ldc < max(1, n) {
|
||||
panic(badLdC)
|
||||
}
|
||||
|
||||
// Quick return if possible.
|
||||
if n == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// For zero matrix size the following slice length checks are trivially satisfied.
|
||||
if len(a) < lda*(row-1)+col {
|
||||
panic(shortA)
|
||||
}
|
||||
if len(b) < ldb*(row-1)+col {
|
||||
panic(shortB)
|
||||
}
|
||||
if len(c) < ldc*(n-1)+n {
|
||||
panic(shortC)
|
||||
}
|
||||
|
||||
if alpha == 0 {
|
||||
if beta == 0 {
|
||||
if ul == blas.Upper {
|
||||
@@ -603,7 +635,7 @@ func (Implementation) Dsyr2k(ul blas.Uplo, tA blas.Transpose, n, k int, alpha fl
|
||||
}
|
||||
}
|
||||
for l := 0; l < k; l++ {
|
||||
tmp1 := alpha * b[l*lda+i]
|
||||
tmp1 := alpha * b[l*ldb+i]
|
||||
tmp2 := alpha * a[l*lda+i]
|
||||
btmp := b[l*ldb+i : l*ldb+n]
|
||||
if tmp1 != 0 || tmp2 != 0 {
|
||||
@@ -623,7 +655,7 @@ func (Implementation) Dsyr2k(ul blas.Uplo, tA blas.Transpose, n, k int, alpha fl
|
||||
}
|
||||
}
|
||||
for l := 0; l < k; l++ {
|
||||
tmp1 := alpha * b[l*lda+i]
|
||||
tmp1 := alpha * b[l*ldb+i]
|
||||
tmp2 := alpha * a[l*lda+i]
|
||||
btmp := b[l*ldb : l*ldb+i+1]
|
||||
if tmp1 != 0 || tmp2 != 0 {
|
||||
@@ -660,18 +692,30 @@ func (Implementation) Dtrmm(s blas.Side, ul blas.Uplo, tA blas.Transpose, d blas
|
||||
if n < 0 {
|
||||
panic(nLT0)
|
||||
}
|
||||
var k int
|
||||
k := n
|
||||
if s == blas.Left {
|
||||
k = m
|
||||
} else {
|
||||
k = n
|
||||
}
|
||||
if lda*(k-1)+k > len(a) || lda < max(1, k) {
|
||||
if lda < max(1, k) {
|
||||
panic(badLdA)
|
||||
}
|
||||
if ldb*(m-1)+n > len(b) || ldb < max(1, n) {
|
||||
if ldb < max(1, n) {
|
||||
panic(badLdB)
|
||||
}
|
||||
|
||||
// Quick return if possible.
|
||||
if m == 0 || n == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// For zero matrix size the following slice length checks are trivially satisfied.
|
||||
if len(a) < lda*(k-1)+k {
|
||||
panic(shortA)
|
||||
}
|
||||
if len(b) < ldb*(m-1)+n {
|
||||
panic(shortB)
|
||||
}
|
||||
|
||||
if alpha == 0 {
|
||||
for i := 0; i < m; i++ {
|
||||
btmp := b[i*ldb : i*ldb+n]
|
||||
@@ -692,14 +736,11 @@ func (Implementation) Dtrmm(s blas.Side, ul blas.Uplo, tA blas.Transpose, d blas
|
||||
tmp *= a[i*lda+i]
|
||||
}
|
||||
btmp := b[i*ldb : i*ldb+n]
|
||||
for j := range btmp {
|
||||
btmp[j] *= tmp
|
||||
}
|
||||
f64.ScalUnitary(tmp, btmp)
|
||||
for ka, va := range a[i*lda+i+1 : i*lda+m] {
|
||||
k := ka + i + 1
|
||||
tmp := alpha * va
|
||||
if tmp != 0 {
|
||||
f64.AxpyUnitaryTo(btmp, tmp, b[k*ldb:k*ldb+n], btmp)
|
||||
if va != 0 {
|
||||
f64.AxpyUnitary(alpha*va, b[k*ldb:k*ldb+n], btmp)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -711,13 +752,10 @@ func (Implementation) Dtrmm(s blas.Side, ul blas.Uplo, tA blas.Transpose, d blas
|
||||
tmp *= a[i*lda+i]
|
||||
}
|
||||
btmp := b[i*ldb : i*ldb+n]
|
||||
for j := range btmp {
|
||||
btmp[j] *= tmp
|
||||
}
|
||||
f64.ScalUnitary(tmp, btmp)
|
||||
for k, va := range a[i*lda : i*lda+i] {
|
||||
tmp := alpha * va
|
||||
if tmp != 0 {
|
||||
f64.AxpyUnitaryTo(btmp, tmp, b[k*ldb:k*ldb+n], btmp)
|
||||
if va != 0 {
|
||||
f64.AxpyUnitary(alpha*va, b[k*ldb:k*ldb+n], btmp)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -730,9 +768,8 @@ func (Implementation) Dtrmm(s blas.Side, ul blas.Uplo, tA blas.Transpose, d blas
|
||||
for ia, va := range a[k*lda+k+1 : k*lda+m] {
|
||||
i := ia + k + 1
|
||||
btmp := b[i*ldb : i*ldb+n]
|
||||
tmp := alpha * va
|
||||
if tmp != 0 {
|
||||
f64.AxpyUnitaryTo(btmp, tmp, btmpk, btmp)
|
||||
if va != 0 {
|
||||
f64.AxpyUnitary(alpha*va, btmpk, btmp)
|
||||
}
|
||||
}
|
||||
tmp := alpha
|
||||
@@ -740,9 +777,7 @@ func (Implementation) Dtrmm(s blas.Side, ul blas.Uplo, tA blas.Transpose, d blas
|
||||
tmp *= a[k*lda+k]
|
||||
}
|
||||
if tmp != 1 {
|
||||
for j := 0; j < n; j++ {
|
||||
btmpk[j] *= tmp
|
||||
}
|
||||
f64.ScalUnitary(tmp, btmpk)
|
||||
}
|
||||
}
|
||||
return
|
||||
@@ -751,9 +786,8 @@ func (Implementation) Dtrmm(s blas.Side, ul blas.Uplo, tA blas.Transpose, d blas
|
||||
btmpk := b[k*ldb : k*ldb+n]
|
||||
for i, va := range a[k*lda : k*lda+k] {
|
||||
btmp := b[i*ldb : i*ldb+n]
|
||||
tmp := alpha * va
|
||||
if tmp != 0 {
|
||||
f64.AxpyUnitaryTo(btmp, tmp, btmpk, btmp)
|
||||
if va != 0 {
|
||||
f64.AxpyUnitary(alpha*va, btmpk, btmp)
|
||||
}
|
||||
}
|
||||
tmp := alpha
|
||||
@@ -761,9 +795,7 @@ func (Implementation) Dtrmm(s blas.Side, ul blas.Uplo, tA blas.Transpose, d blas
|
||||
tmp *= a[k*lda+k]
|
||||
}
|
||||
if tmp != 1 {
|
||||
for j := 0; j < n; j++ {
|
||||
btmpk[j] *= tmp
|
||||
}
|
||||
f64.ScalUnitary(tmp, btmpk)
|
||||
}
|
||||
}
|
||||
return
|
||||
@@ -775,16 +807,14 @@ func (Implementation) Dtrmm(s blas.Side, ul blas.Uplo, tA blas.Transpose, d blas
|
||||
btmp := b[i*ldb : i*ldb+n]
|
||||
for k := n - 1; k >= 0; k-- {
|
||||
tmp := alpha * btmp[k]
|
||||
if tmp != 0 {
|
||||
btmp[k] = tmp
|
||||
if nonUnit {
|
||||
btmp[k] *= a[k*lda+k]
|
||||
}
|
||||
for ja, v := range a[k*lda+k+1 : k*lda+n] {
|
||||
j := ja + k + 1
|
||||
btmp[j] += tmp * v
|
||||
}
|
||||
if tmp == 0 {
|
||||
continue
|
||||
}
|
||||
btmp[k] = tmp
|
||||
if nonUnit {
|
||||
btmp[k] *= a[k*lda+k]
|
||||
}
|
||||
f64.AxpyUnitary(tmp, a[k*lda+k+1:k*lda+n], btmp[k+1:n])
|
||||
}
|
||||
}
|
||||
return
|
||||
@@ -793,13 +823,14 @@ func (Implementation) Dtrmm(s blas.Side, ul blas.Uplo, tA blas.Transpose, d blas
|
||||
btmp := b[i*ldb : i*ldb+n]
|
||||
for k := 0; k < n; k++ {
|
||||
tmp := alpha * btmp[k]
|
||||
if tmp != 0 {
|
||||
btmp[k] = tmp
|
||||
if nonUnit {
|
||||
btmp[k] *= a[k*lda+k]
|
||||
}
|
||||
f64.AxpyUnitaryTo(btmp, tmp, a[k*lda:k*lda+k], btmp)
|
||||
if tmp == 0 {
|
||||
continue
|
||||
}
|
||||
btmp[k] = tmp
|
||||
if nonUnit {
|
||||
btmp[k] *= a[k*lda+k]
|
||||
}
|
||||
f64.AxpyUnitary(tmp, a[k*lda:k*lda+k], btmp[:k])
|
||||
}
|
||||
}
|
||||
return
|
||||
81
vendor/gonum.org/v1/gonum/blas/gonum/sgemm.go
generated
vendored
81
vendor/gonum.org/v1/gonum/blas/gonum/sgemm.go
generated
vendored
@@ -25,25 +25,81 @@ import (
|
||||
//
|
||||
// Float32 implementations are autogenerated and not directly tested.
|
||||
func (Implementation) Sgemm(tA, tB blas.Transpose, m, n, k int, alpha float32, a []float32, lda int, b []float32, ldb int, beta float32, c []float32, ldc int) {
|
||||
if tA != blas.NoTrans && tA != blas.Trans && tA != blas.ConjTrans {
|
||||
switch tA {
|
||||
default:
|
||||
panic(badTranspose)
|
||||
case blas.NoTrans, blas.Trans, blas.ConjTrans:
|
||||
}
|
||||
if tB != blas.NoTrans && tB != blas.Trans && tB != blas.ConjTrans {
|
||||
switch tB {
|
||||
default:
|
||||
panic(badTranspose)
|
||||
case blas.NoTrans, blas.Trans, blas.ConjTrans:
|
||||
}
|
||||
if m < 0 {
|
||||
panic(mLT0)
|
||||
}
|
||||
if n < 0 {
|
||||
panic(nLT0)
|
||||
}
|
||||
if k < 0 {
|
||||
panic(kLT0)
|
||||
}
|
||||
aTrans := tA == blas.Trans || tA == blas.ConjTrans
|
||||
if aTrans {
|
||||
checkSMatrix('a', k, m, a, lda)
|
||||
if lda < max(1, m) {
|
||||
panic(badLdA)
|
||||
}
|
||||
} else {
|
||||
checkSMatrix('a', m, k, a, lda)
|
||||
if lda < max(1, k) {
|
||||
panic(badLdA)
|
||||
}
|
||||
}
|
||||
bTrans := tB == blas.Trans || tB == blas.ConjTrans
|
||||
if bTrans {
|
||||
checkSMatrix('b', n, k, b, ldb)
|
||||
if ldb < max(1, k) {
|
||||
panic(badLdB)
|
||||
}
|
||||
} else {
|
||||
checkSMatrix('b', k, n, b, ldb)
|
||||
if ldb < max(1, n) {
|
||||
panic(badLdB)
|
||||
}
|
||||
}
|
||||
if ldc < max(1, n) {
|
||||
panic(badLdC)
|
||||
}
|
||||
|
||||
// Quick return if possible.
|
||||
if m == 0 || n == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// For zero matrix size the following slice length checks are trivially satisfied.
|
||||
if aTrans {
|
||||
if len(a) < (k-1)*lda+m {
|
||||
panic(shortA)
|
||||
}
|
||||
} else {
|
||||
if len(a) < (m-1)*lda+k {
|
||||
panic(shortA)
|
||||
}
|
||||
}
|
||||
if bTrans {
|
||||
if len(b) < (n-1)*ldb+k {
|
||||
panic(shortB)
|
||||
}
|
||||
} else {
|
||||
if len(b) < (k-1)*ldb+n {
|
||||
panic(shortB)
|
||||
}
|
||||
}
|
||||
if len(c) < (m-1)*ldc+n {
|
||||
panic(shortC)
|
||||
}
|
||||
|
||||
// Quick return if possible.
|
||||
if (alpha == 0 || k == 0) && beta == 1 {
|
||||
return
|
||||
}
|
||||
checkSMatrix('c', m, n, c, ldc)
|
||||
|
||||
// scale c
|
||||
if beta != 1 {
|
||||
@@ -128,13 +184,6 @@ func sgemmParallel(aTrans, bTrans bool, m, n, k int, a []float32, lda int, b []f
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
// Make local copies of otherwise global variables to reduce shared memory.
|
||||
// This has a noticeable effect on benchmarks in some cases.
|
||||
alpha := alpha
|
||||
aTrans := aTrans
|
||||
bTrans := bTrans
|
||||
m := m
|
||||
n := n
|
||||
for sub := range sendChan {
|
||||
i := sub.i
|
||||
j := sub.j
|
||||
@@ -214,7 +263,7 @@ func sgemmSerialNotNot(m, n, k int, a []float32, lda int, b []float32, ldb int,
|
||||
for l, v := range a[i*lda : i*lda+k] {
|
||||
tmp := alpha * v
|
||||
if tmp != 0 {
|
||||
f32.AxpyUnitaryTo(ctmp, tmp, b[l*ldb:l*ldb+n], ctmp)
|
||||
f32.AxpyUnitary(tmp, b[l*ldb:l*ldb+n], ctmp)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -230,7 +279,7 @@ func sgemmSerialTransNot(m, n, k int, a []float32, lda int, b []float32, ldb int
|
||||
tmp := alpha * v
|
||||
if tmp != 0 {
|
||||
ctmp := c[i*ldc : i*ldc+n]
|
||||
f32.AxpyUnitaryTo(ctmp, tmp, btmp, ctmp)
|
||||
f32.AxpyUnitary(tmp, btmp, ctmp)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
153
vendor/gonum.org/v1/gonum/blas/gonum/single_precision.bash
generated
vendored
153
vendor/gonum.org/v1/gonum/blas/gonum/single_precision.bash
generated
vendored
@@ -4,126 +4,180 @@
|
||||
# Use of this source code is governed by a BSD-style
|
||||
# license that can be found in the LICENSE file.
|
||||
|
||||
WARNING='//\
|
||||
WARNINGF32='//\
|
||||
// Float32 implementations are autogenerated and not directly tested.\
|
||||
'
|
||||
WARNINGC64='//\
|
||||
// Complex64 implementations are autogenerated and not directly tested.\
|
||||
'
|
||||
|
||||
# Level1 routines.
|
||||
|
||||
echo Generating level1single.go
|
||||
echo -e '// Code generated by "go generate gonum.org/v1/gonum/blas/gonum”; DO NOT EDIT.\n' > level1single.go
|
||||
cat level1double.go \
|
||||
echo Generating level1float32.go
|
||||
echo -e '// Code generated by "go generate gonum.org/v1/gonum/blas/gonum”; DO NOT EDIT.\n' > level1float32.go
|
||||
cat level1float64.go \
|
||||
| gofmt -r 'blas.Float64Level1 -> blas.Float32Level1' \
|
||||
\
|
||||
| gofmt -r 'float64 -> float32' \
|
||||
| gofmt -r 'blas.DrotmParams -> blas.SrotmParams' \
|
||||
\
|
||||
| gofmt -r 'f64.AxpyInc -> f32.AxpyInc' \
|
||||
| gofmt -r 'f64.AxpyIncTo -> f32.AxpyIncTo' \
|
||||
| gofmt -r 'f64.AxpyUnitary -> f32.AxpyUnitary' \
|
||||
| gofmt -r 'f64.AxpyUnitaryTo -> f32.AxpyUnitaryTo' \
|
||||
| gofmt -r 'f64.DotUnitary -> f32.DotUnitary' \
|
||||
| gofmt -r 'f64.ScalInc -> f32.ScalInc' \
|
||||
| gofmt -r 'f64.ScalUnitary -> f32.ScalUnitary' \
|
||||
\
|
||||
| sed -e "s_^\(func (Implementation) \)D\(.*\)\$_$WARNING\1S\2_" \
|
||||
| sed -e "s_^\(func (Implementation) \)D\(.*\)\$_$WARNINGF32\1S\2_" \
|
||||
-e 's_^// D_// S_' \
|
||||
-e "s_^\(func (Implementation) \)Id\(.*\)\$_$WARNING\1Is\2_" \
|
||||
-e "s_^\(func (Implementation) \)Id\(.*\)\$_$WARNINGF32\1Is\2_" \
|
||||
-e 's_^// Id_// Is_' \
|
||||
-e 's_"gonum.org/v1/gonum/internal/asm/f64"_"gonum.org/v1/gonum/internal/asm/f32"_' \
|
||||
-e 's_"math"_math "gonum.org/v1/gonum/internal/math32"_' \
|
||||
>> level1single.go
|
||||
>> level1float32.go
|
||||
|
||||
echo Generating level1single_sdot.go
|
||||
echo -e '// Code generated by "go generate gonum.org/v1/gonum/blas/gonum”; DO NOT EDIT.\n' > level1single_sdot.go
|
||||
cat level1double_ddot.go \
|
||||
echo Generating level1cmplx64.go
|
||||
echo -e '// Code generated by "go generate gonum.org/v1/gonum/blas/gonum”; DO NOT EDIT.\n' > level1cmplx64.go
|
||||
cat level1cmplx128.go \
|
||||
| gofmt -r 'blas.Complex128Level1 -> blas.Complex64Level1' \
|
||||
\
|
||||
| gofmt -r 'float64 -> float32' \
|
||||
| gofmt -r 'complex128 -> complex64' \
|
||||
\
|
||||
| gofmt -r 'c128.AxpyInc -> c64.AxpyInc' \
|
||||
| gofmt -r 'c128.AxpyUnitary -> c64.AxpyUnitary' \
|
||||
| gofmt -r 'c128.DotcInc -> c64.DotcInc' \
|
||||
| gofmt -r 'c128.DotcUnitary -> c64.DotcUnitary' \
|
||||
| gofmt -r 'c128.DotuInc -> c64.DotuInc' \
|
||||
| gofmt -r 'c128.DotuUnitary -> c64.DotuUnitary' \
|
||||
| gofmt -r 'c128.ScalInc -> c64.ScalInc' \
|
||||
| gofmt -r 'c128.ScalUnitary -> c64.ScalUnitary' \
|
||||
| gofmt -r 'dcabs1 -> scabs1' \
|
||||
\
|
||||
| sed -e "s_^\(func (Implementation) \)Zdot\(.*\)\$_$WARNINGC64\1Cdot\2_" \
|
||||
-e 's_^// Zdot_// Cdot_' \
|
||||
-e "s_^\(func (Implementation) \)Zdscal\(.*\)\$_$WARNINGC64\1Csscal\2_" \
|
||||
-e 's_^// Zdscal_// Csscal_' \
|
||||
-e "s_^\(func (Implementation) \)Z\(.*\)\$_$WARNINGC64\1C\2_" \
|
||||
-e 's_^// Z_// C_' \
|
||||
-e "s_^\(func (Implementation) \)Iz\(.*\)\$_$WARNINGC64\1Ic\2_" \
|
||||
-e 's_^// Iz_// Ic_' \
|
||||
-e "s_^\(func (Implementation) \)Dz\(.*\)\$_$WARNINGC64\1Sc\2_" \
|
||||
-e 's_^// Dz_// Sc_' \
|
||||
-e 's_"gonum.org/v1/gonum/internal/asm/c128"_"gonum.org/v1/gonum/internal/asm/c64"_' \
|
||||
-e 's_"math"_math "gonum.org/v1/gonum/internal/math32"_' \
|
||||
>> level1cmplx64.go
|
||||
|
||||
echo Generating level1float32_sdot.go
|
||||
echo -e '// Code generated by "go generate gonum.org/v1/gonum/blas/gonum”; DO NOT EDIT.\n' > level1float32_sdot.go
|
||||
cat level1float64_ddot.go \
|
||||
| gofmt -r 'float64 -> float32' \
|
||||
\
|
||||
| gofmt -r 'f64.DotInc -> f32.DotInc' \
|
||||
| gofmt -r 'f64.DotUnitary -> f32.DotUnitary' \
|
||||
\
|
||||
| sed -e "s_^\(func (Implementation) \)D\(.*\)\$_$WARNING\1S\2_" \
|
||||
| sed -e "s_^\(func (Implementation) \)D\(.*\)\$_$WARNINGF32\1S\2_" \
|
||||
-e 's_^// D_// S_' \
|
||||
-e 's_"gonum.org/v1/gonum/internal/asm/f64"_"gonum.org/v1/gonum/internal/asm/f32"_' \
|
||||
>> level1single_sdot.go
|
||||
>> level1float32_sdot.go
|
||||
|
||||
echo Generating level1single_dsdot.go
|
||||
echo -e '// Code generated by "go generate gonum.org/v1/gonum/blas/gonum”; DO NOT EDIT.\n' > level1single_dsdot.go
|
||||
cat level1double_ddot.go \
|
||||
echo Generating level1float32_dsdot.go
|
||||
echo -e '// Code generated by "go generate gonum.org/v1/gonum/blas/gonum”; DO NOT EDIT.\n' > level1float32_dsdot.go
|
||||
cat level1float64_ddot.go \
|
||||
| gofmt -r '[]float64 -> []float32' \
|
||||
\
|
||||
| gofmt -r 'f64.DotInc -> f32.DdotInc' \
|
||||
| gofmt -r 'f64.DotUnitary -> f32.DdotUnitary' \
|
||||
\
|
||||
| sed -e "s_^\(func (Implementation) \)D\(.*\)\$_$WARNING\1Ds\2_" \
|
||||
| sed -e "s_^\(func (Implementation) \)D\(.*\)\$_$WARNINGF32\1Ds\2_" \
|
||||
-e 's_^// D_// Ds_' \
|
||||
-e 's_"gonum.org/v1/gonum/internal/asm/f64"_"gonum.org/v1/gonum/internal/asm/f32"_' \
|
||||
>> level1single_dsdot.go
|
||||
>> level1float32_dsdot.go
|
||||
|
||||
echo Generating level1single_sdsdot.go
|
||||
echo -e '// Code generated by "go generate gonum.org/v1/gonum/blas/gonum”; DO NOT EDIT.\n' > level1single_sdsdot.go
|
||||
cat level1double_ddot.go \
|
||||
echo Generating level1float32_sdsdot.go
|
||||
echo -e '// Code generated by "go generate gonum.org/v1/gonum/blas/gonum”; DO NOT EDIT.\n' > level1float32_sdsdot.go
|
||||
cat level1float64_ddot.go \
|
||||
| gofmt -r 'float64 -> float32' \
|
||||
\
|
||||
| gofmt -r 'f64.DotInc(x, y, f(n), f(incX), f(incY), f(ix), f(iy)) -> alpha + float32(f32.DdotInc(x, y, f(n), f(incX), f(incY), f(ix), f(iy)))' \
|
||||
| gofmt -r 'f64.DotUnitary(a, b) -> alpha + float32(f32.DdotUnitary(a, b))' \
|
||||
\
|
||||
| sed -e "s_^\(func (Implementation) \)D\(.*\)\$_$WARNING\1Sds\2_" \
|
||||
| sed -e "s_^\(func (Implementation) \)D\(.*\)\$_$WARNINGF32\1Sds\2_" \
|
||||
-e 's_^// D\(.*\)$_// Sds\1 plus a constant_' \
|
||||
-e 's_\\sum_alpha + \\sum_' \
|
||||
-e 's/n int/n int, alpha float32/' \
|
||||
-e 's_"gonum.org/v1/gonum/internal/asm/f64"_"gonum.org/v1/gonum/internal/asm/f32"_' \
|
||||
>> level1single_sdsdot.go
|
||||
>> level1float32_sdsdot.go
|
||||
|
||||
|
||||
# Level2 routines.
|
||||
|
||||
echo Generating level2single.go
|
||||
echo -e '// Code generated by "go generate gonum.org/v1/gonum/blas/gonum”; DO NOT EDIT.\n' > level2single.go
|
||||
cat level2double.go \
|
||||
echo Generating level2float32.go
|
||||
echo -e '// Code generated by "go generate gonum.org/v1/gonum/blas/gonum”; DO NOT EDIT.\n' > level2float32.go
|
||||
cat level2float64.go \
|
||||
| gofmt -r 'blas.Float64Level2 -> blas.Float32Level2' \
|
||||
\
|
||||
| gofmt -r 'float64 -> float32' \
|
||||
\
|
||||
| gofmt -r 'Dscal -> Sscal' \
|
||||
\
|
||||
| gofmt -r 'f64.AxpyInc -> f32.AxpyInc' \
|
||||
| gofmt -r 'f64.AxpyIncTo -> f32.AxpyIncTo' \
|
||||
| gofmt -r 'f64.AxpyUnitary -> f32.AxpyUnitary' \
|
||||
| gofmt -r 'f64.AxpyUnitaryTo -> f32.AxpyUnitaryTo' \
|
||||
| gofmt -r 'f64.DotInc -> f32.DotInc' \
|
||||
| gofmt -r 'f64.DotUnitary -> f32.DotUnitary' \
|
||||
| gofmt -r 'f64.ScalInc -> f32.ScalInc' \
|
||||
| gofmt -r 'f64.ScalUnitary -> f32.ScalUnitary' \
|
||||
| gofmt -r 'f64.Ger -> f32.Ger' \
|
||||
\
|
||||
| sed -e "s_^\(func (Implementation) \)D\(.*\)\$_$WARNING\1S\2_" \
|
||||
| sed -e "s_^\(func (Implementation) \)D\(.*\)\$_$WARNINGF32\1S\2_" \
|
||||
-e 's_^// D_// S_' \
|
||||
-e 's_"gonum.org/v1/gonum/internal/asm/f64"_"gonum.org/v1/gonum/internal/asm/f32"_' \
|
||||
>> level2single.go
|
||||
>> level2float32.go
|
||||
|
||||
echo Generating level2cmplx64.go
|
||||
echo -e '// Code generated by "go generate gonum.org/v1/gonum/blas/gonum”; DO NOT EDIT.\n' > level2cmplx64.go
|
||||
cat level2cmplx128.go \
|
||||
| gofmt -r 'blas.Complex128Level2 -> blas.Complex64Level2' \
|
||||
\
|
||||
| gofmt -r 'complex128 -> complex64' \
|
||||
| gofmt -r 'float64 -> float32' \
|
||||
\
|
||||
| gofmt -r 'c128.AxpyInc -> c64.AxpyInc' \
|
||||
| gofmt -r 'c128.AxpyUnitary -> c64.AxpyUnitary' \
|
||||
| gofmt -r 'c128.DotuInc -> c64.DotuInc' \
|
||||
| gofmt -r 'c128.DotuUnitary -> c64.DotuUnitary' \
|
||||
| gofmt -r 'c128.ScalInc -> c64.ScalInc' \
|
||||
| gofmt -r 'c128.ScalUnitary -> c64.ScalUnitary' \
|
||||
\
|
||||
| sed -e "s_^\(func (Implementation) \)Z\(.*\)\$_$WARNINGC64\1C\2_" \
|
||||
-e 's_^// Z_// C_' \
|
||||
-e 's_"gonum.org/v1/gonum/internal/asm/c128"_"gonum.org/v1/gonum/internal/asm/c64"_' \
|
||||
-e 's_"math/cmplx"_cmplx "gonum.org/v1/gonum/internal/cmplx64"_' \
|
||||
>> level2cmplx64.go
|
||||
|
||||
# Level3 routines.
|
||||
|
||||
echo Generating level3single.go
|
||||
echo -e '// Code generated by "go generate gonum.org/v1/gonum/blas/gonum”; DO NOT EDIT.\n' > level3single.go
|
||||
cat level3double.go \
|
||||
echo Generating level3float32.go
|
||||
echo -e '// Code generated by "go generate gonum.org/v1/gonum/blas/gonum”; DO NOT EDIT.\n' > level3float32.go
|
||||
cat level3float64.go \
|
||||
| gofmt -r 'blas.Float64Level3 -> blas.Float32Level3' \
|
||||
\
|
||||
| gofmt -r 'float64 -> float32' \
|
||||
\
|
||||
| gofmt -r 'f64.AxpyUnitaryTo -> f32.AxpyUnitaryTo' \
|
||||
| gofmt -r 'f64.AxpyUnitary -> f32.AxpyUnitary' \
|
||||
| gofmt -r 'f64.DotUnitary -> f32.DotUnitary' \
|
||||
| gofmt -r 'f64.ScalUnitary -> f32.ScalUnitary' \
|
||||
\
|
||||
| sed -e "s_^\(func (Implementation) \)D\(.*\)\$_$WARNING\1S\2_" \
|
||||
| sed -e "s_^\(func (Implementation) \)D\(.*\)\$_$WARNINGF32\1S\2_" \
|
||||
-e 's_^// D_// S_' \
|
||||
-e 's_"gonum.org/v1/gonum/internal/asm/f64"_"gonum.org/v1/gonum/internal/asm/f32"_' \
|
||||
>> level3single.go
|
||||
>> level3float32.go
|
||||
|
||||
echo Generating sgemm.go
|
||||
echo -e '// Code generated by "go generate gonum.org/v1/gonum/blas/gonum”; DO NOT EDIT.\n' > sgemm.go
|
||||
cat dgemm.go \
|
||||
| gofmt -r 'float64 -> float32' \
|
||||
| gofmt -r 'sliceView64 -> sliceView32' \
|
||||
| gofmt -r 'checkDMatrix -> checkSMatrix' \
|
||||
\
|
||||
| gofmt -r 'dgemmParallel -> sgemmParallel' \
|
||||
| gofmt -r 'computeNumBlocks64 -> computeNumBlocks32' \
|
||||
@@ -134,12 +188,31 @@ cat dgemm.go \
|
||||
| gofmt -r 'dgemmSerialTransTrans -> sgemmSerialTransTrans' \
|
||||
\
|
||||
| gofmt -r 'f64.AxpyInc -> f32.AxpyInc' \
|
||||
| gofmt -r 'f64.AxpyIncTo -> f32.AxpyIncTo' \
|
||||
| gofmt -r 'f64.AxpyUnitaryTo -> f32.AxpyUnitaryTo' \
|
||||
| gofmt -r 'f64.AxpyUnitary -> f32.AxpyUnitary' \
|
||||
| gofmt -r 'f64.DotUnitary -> f32.DotUnitary' \
|
||||
\
|
||||
| sed -e "s_^\(func (Implementation) \)D\(.*\)\$_$WARNING\1S\2_" \
|
||||
| sed -e "s_^\(func (Implementation) \)D\(.*\)\$_$WARNINGF32\1S\2_" \
|
||||
-e 's_^// D_// S_' \
|
||||
-e 's_^// d_// s_' \
|
||||
-e 's_"gonum.org/v1/gonum/internal/asm/f64"_"gonum.org/v1/gonum/internal/asm/f32"_' \
|
||||
>> sgemm.go
|
||||
|
||||
echo Generating level3cmplx64.go
|
||||
echo -e '// Code generated by "go generate gonum.org/v1/gonum/blas/gonum”; DO NOT EDIT.\n' > level3cmplx64.go
|
||||
cat level3cmplx128.go \
|
||||
| gofmt -r 'blas.Complex128Level3 -> blas.Complex64Level3' \
|
||||
\
|
||||
| gofmt -r 'float64 -> float32' \
|
||||
| gofmt -r 'complex128 -> complex64' \
|
||||
\
|
||||
| gofmt -r 'c128.ScalUnitary -> c64.ScalUnitary' \
|
||||
| gofmt -r 'c128.DscalUnitary -> c64.SscalUnitary' \
|
||||
| gofmt -r 'c128.DotcUnitary -> c64.DotcUnitary' \
|
||||
| gofmt -r 'c128.AxpyUnitary -> c64.AxpyUnitary' \
|
||||
| gofmt -r 'c128.DotuUnitary -> c64.DotuUnitary' \
|
||||
\
|
||||
| sed -e "s_^\(func (Implementation) \)Z\(.*\)\$_$WARNINGC64\1C\2_" \
|
||||
-e 's_^// Z_// C_' \
|
||||
-e 's_"gonum.org/v1/gonum/internal/asm/c128"_"gonum.org/v1/gonum/internal/asm/c64"_' \
|
||||
-e 's_"math/cmplx"_cmplx "gonum.org/v1/gonum/internal/cmplx64"_' \
|
||||
>> level3cmplx64.go
|
||||
|
||||
23
vendor/gonum.org/v1/gonum/floats/floats.go
generated
vendored
23
vendor/gonum.org/v1/gonum/floats/floats.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright 2013 The Gonum Authors. All rights reserved.
|
||||
// Copyright ©2013 The Gonum Authors. All rights reserved.
|
||||
// Use of this code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file
|
||||
|
||||
@@ -37,9 +37,7 @@ func AddTo(dst, s, t []float64) []float64 {
|
||||
|
||||
// AddConst adds the scalar c to all of the values in dst.
|
||||
func AddConst(c float64, dst []float64) {
|
||||
for i := range dst {
|
||||
dst[i] += c
|
||||
}
|
||||
f64.AddConst(c, dst)
|
||||
}
|
||||
|
||||
// AddScaled performs dst = dst + alpha * s.
|
||||
@@ -811,6 +809,17 @@ func Scale(c float64, dst []float64) {
|
||||
}
|
||||
}
|
||||
|
||||
// ScaleTo multiplies the elements in s by c and stores the result in dst.
|
||||
func ScaleTo(dst []float64, c float64, s []float64) []float64 {
|
||||
if len(dst) != len(s) {
|
||||
panic("floats: lengths of slices do not match")
|
||||
}
|
||||
if len(dst) > 0 {
|
||||
f64.ScalUnitaryTo(dst, c, s)
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// Span returns a set of N equally spaced points between l and u, where N
|
||||
// is equal to the length of the destination. The first element of the destination
|
||||
// is l, the final element of the destination is u.
|
||||
@@ -899,11 +908,7 @@ func SubTo(dst, s, t []float64) []float64 {
|
||||
|
||||
// Sum returns the sum of the elements of the slice.
|
||||
func Sum(s []float64) float64 {
|
||||
var sum float64
|
||||
for _, val := range s {
|
||||
sum += val
|
||||
}
|
||||
return sum
|
||||
return f64.Sum(s)
|
||||
}
|
||||
|
||||
// Within returns the first index i where s[i] <= v < s[i+1]. Within panics if:
|
||||
|
||||
2
vendor/gonum.org/v1/gonum/graph/BUILD
generated
vendored
2
vendor/gonum.org/v1/gonum/graph/BUILD
generated
vendored
@@ -6,6 +6,7 @@ go_library(
|
||||
"doc.go",
|
||||
"graph.go",
|
||||
"multigraph.go",
|
||||
"nodes_edges.go",
|
||||
"undirect.go",
|
||||
],
|
||||
importmap = "k8s.io/kubernetes/vendor/gonum.org/v1/gonum/graph",
|
||||
@@ -30,6 +31,7 @@ filegroup(
|
||||
"//vendor/gonum.org/v1/gonum/graph/internal/ordered:all-srcs",
|
||||
"//vendor/gonum.org/v1/gonum/graph/internal/set:all-srcs",
|
||||
"//vendor/gonum.org/v1/gonum/graph/internal/uid:all-srcs",
|
||||
"//vendor/gonum.org/v1/gonum/graph/iterator:all-srcs",
|
||||
"//vendor/gonum.org/v1/gonum/graph/simple:all-srcs",
|
||||
"//vendor/gonum.org/v1/gonum/graph/topo:all-srcs",
|
||||
"//vendor/gonum.org/v1/gonum/graph/traverse:all-srcs",
|
||||
|
||||
3
vendor/gonum.org/v1/gonum/graph/doc.go
generated
vendored
3
vendor/gonum.org/v1/gonum/graph/doc.go
generated
vendored
@@ -3,4 +3,7 @@
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package graph defines graph interfaces.
|
||||
//
|
||||
// Routines to test contract compliance by user implemented graph types
|
||||
// are available in gonum.org/v1/gonum/graph/testgraph.
|
||||
package graph // import "gonum.org/v1/gonum/graph"
|
||||
|
||||
1
vendor/gonum.org/v1/gonum/graph/encoding/dot/BUILD
generated
vendored
1
vendor/gonum.org/v1/gonum/graph/encoding/dot/BUILD
generated
vendored
@@ -5,7 +5,6 @@ go_library(
|
||||
srcs = [
|
||||
"decode.go",
|
||||
"doc.go",
|
||||
"dot.go",
|
||||
"encode.go",
|
||||
],
|
||||
importmap = "k8s.io/kubernetes/vendor/gonum.org/v1/gonum/graph/encoding/dot",
|
||||
|
||||
256
vendor/gonum.org/v1/gonum/graph/encoding/dot/decode.go
generated
vendored
256
vendor/gonum.org/v1/gonum/graph/encoding/dot/decode.go
generated
vendored
@@ -6,6 +6,8 @@ package dot
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"gonum.org/v1/gonum/graph"
|
||||
"gonum.org/v1/gonum/graph/encoding"
|
||||
@@ -39,15 +41,38 @@ type PortSetter interface {
|
||||
}
|
||||
|
||||
// Unmarshal parses the Graphviz DOT-encoded data and stores the result in dst.
|
||||
// If the number of graphs encoded in data is not one, an error is returned and
|
||||
// dst will hold the first graph in data.
|
||||
//
|
||||
// Attributes and IDs are unquoted during unmarshalling if appropriate.
|
||||
func Unmarshal(data []byte, dst encoding.Builder) error {
|
||||
file, err := dot.ParseBytes(data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(file.Graphs) != 1 {
|
||||
return fmt.Errorf("invalid number of graphs; expected 1, got %d", len(file.Graphs))
|
||||
err = copyGraph(dst, file.Graphs[0])
|
||||
if err == nil && len(file.Graphs) != 1 {
|
||||
err = fmt.Errorf("invalid number of graphs; expected 1, got %d", len(file.Graphs))
|
||||
}
|
||||
return copyGraph(dst, file.Graphs[0])
|
||||
return err
|
||||
}
|
||||
|
||||
// UnmarshalMulti parses the Graphviz DOT-encoded data as a multigraph and
|
||||
// stores the result in dst.
|
||||
// If the number of graphs encoded in data is not one, an error is returned and
|
||||
// dst will hold the first graph in data.
|
||||
//
|
||||
// Attributes and IDs are unquoted during unmarshalling if appropriate.
|
||||
func UnmarshalMulti(data []byte, dst encoding.MultiBuilder) error {
|
||||
file, err := dot.ParseBytes(data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = copyMultigraph(dst, file.Graphs[0])
|
||||
if err == nil && len(file.Graphs) != 1 {
|
||||
err = fmt.Errorf("invalid number of graphs; expected 1, got %d", len(file.Graphs))
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// copyGraph copies the nodes and edges from the Graphviz AST source graph to
|
||||
@@ -62,12 +87,44 @@ func copyGraph(dst encoding.Builder, src *ast.Graph) (err error) {
|
||||
panic(e)
|
||||
}
|
||||
}()
|
||||
gen := &generator{
|
||||
directed: src.Directed,
|
||||
ids: make(map[string]graph.Node),
|
||||
gen := &simpleGraph{
|
||||
generator: generator{
|
||||
directed: src.Directed,
|
||||
ids: make(map[string]graph.Node),
|
||||
},
|
||||
}
|
||||
if dst, ok := dst.(DOTIDSetter); ok {
|
||||
dst.SetDOTID(src.ID)
|
||||
dst.SetDOTID(unquoteID(src.ID))
|
||||
}
|
||||
if a, ok := dst.(AttributeSetters); ok {
|
||||
gen.graphAttr, gen.nodeAttr, gen.edgeAttr = a.DOTAttributeSetters()
|
||||
}
|
||||
for _, stmt := range src.Stmts {
|
||||
gen.addStmt(dst, stmt)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// copyMultigraph copies the nodes and edges from the Graphviz AST source graph to
|
||||
// the destination graph. Edge direction is maintained if present.
|
||||
func copyMultigraph(dst encoding.MultiBuilder, src *ast.Graph) (err error) {
|
||||
defer func() {
|
||||
switch e := recover().(type) {
|
||||
case nil:
|
||||
case error:
|
||||
err = e
|
||||
default:
|
||||
panic(e)
|
||||
}
|
||||
}()
|
||||
gen := &multiGraph{
|
||||
generator: generator{
|
||||
directed: src.Directed,
|
||||
ids: make(map[string]graph.Node),
|
||||
},
|
||||
}
|
||||
if dst, ok := dst.(DOTIDSetter); ok {
|
||||
dst.SetDOTID(unquoteID(src.ID))
|
||||
}
|
||||
if a, ok := dst.(AttributeSetters); ok {
|
||||
gen.graphAttr, gen.nodeAttr, gen.edgeAttr = a.DOTAttributeSetters()
|
||||
@@ -97,15 +154,15 @@ type generator struct {
|
||||
|
||||
// node returns the gonum node corresponding to the given dot AST node ID,
|
||||
// generating a new such node if none exist.
|
||||
func (gen *generator) node(dst encoding.Builder, id string) graph.Node {
|
||||
func (gen *generator) node(dst graph.NodeAdder, id string) graph.Node {
|
||||
if n, ok := gen.ids[id]; ok {
|
||||
return n
|
||||
}
|
||||
n := dst.NewNode()
|
||||
dst.AddNode(n)
|
||||
if n, ok := n.(DOTIDSetter); ok {
|
||||
n.SetDOTID(id)
|
||||
n.SetDOTID(unquoteID(id))
|
||||
}
|
||||
dst.AddNode(n)
|
||||
gen.ids[id] = n
|
||||
// Check if within the context of a subgraph, that is to be used as a vertex
|
||||
// of an edge.
|
||||
@@ -117,8 +174,10 @@ func (gen *generator) node(dst encoding.Builder, id string) graph.Node {
|
||||
return n
|
||||
}
|
||||
|
||||
type simpleGraph struct{ generator }
|
||||
|
||||
// addStmt adds the given statement to the graph.
|
||||
func (gen *generator) addStmt(dst encoding.Builder, stmt ast.Stmt) {
|
||||
func (gen *simpleGraph) addStmt(dst encoding.Builder, stmt ast.Stmt) {
|
||||
switch stmt := stmt.(type) {
|
||||
case *ast.NodeStmt:
|
||||
n, ok := gen.node(dst, stmt.Node.ID).(encoding.AttributeSetter)
|
||||
@@ -127,11 +186,11 @@ func (gen *generator) addStmt(dst encoding.Builder, stmt ast.Stmt) {
|
||||
}
|
||||
for _, attr := range stmt.Attrs {
|
||||
a := encoding.Attribute{
|
||||
Key: attr.Key,
|
||||
Value: attr.Val,
|
||||
Key: unquoteID(attr.Key),
|
||||
Value: unquoteID(attr.Val),
|
||||
}
|
||||
if err := n.SetAttribute(a); err != nil {
|
||||
panic(fmt.Errorf("unable to unmarshal node DOT attribute (%s=%s)", a.Key, a.Value))
|
||||
panic(fmt.Errorf("unable to unmarshal node DOT attribute (%s=%s): %v", a.Key, a.Value, err))
|
||||
}
|
||||
}
|
||||
case *ast.EdgeStmt:
|
||||
@@ -163,11 +222,11 @@ func (gen *generator) addStmt(dst encoding.Builder, stmt ast.Stmt) {
|
||||
}
|
||||
for _, attr := range stmt.Attrs {
|
||||
a := encoding.Attribute{
|
||||
Key: attr.Key,
|
||||
Value: attr.Val,
|
||||
Key: unquoteID(attr.Key),
|
||||
Value: unquoteID(attr.Val),
|
||||
}
|
||||
if err := n.SetAttribute(a); err != nil {
|
||||
panic(fmt.Errorf("unable to unmarshal global %s DOT attribute (%s=%s)", dst, a.Key, a.Value))
|
||||
panic(fmt.Errorf("unable to unmarshal global %s DOT attribute (%s=%s): %v", dst, a.Key, a.Value, err))
|
||||
}
|
||||
}
|
||||
case *ast.Attr:
|
||||
@@ -181,13 +240,20 @@ func (gen *generator) addStmt(dst encoding.Builder, stmt ast.Stmt) {
|
||||
}
|
||||
}
|
||||
|
||||
// basicEdge is an edge without the Reverse method to
|
||||
// allow satisfaction by both graph.Edge and graph.Line.
|
||||
type basicEdge interface {
|
||||
From() graph.Node
|
||||
To() graph.Node
|
||||
}
|
||||
|
||||
// applyPortsToEdge applies the available port metadata from an ast.Edge
|
||||
// to a graph.Edge
|
||||
func applyPortsToEdge(from ast.Vertex, to *ast.Edge, edge graph.Edge) {
|
||||
func applyPortsToEdge(from ast.Vertex, to *ast.Edge, edge basicEdge) {
|
||||
if ps, isPortSetter := edge.(PortSetter); isPortSetter {
|
||||
if n, vertexIsNode := from.(*ast.Node); vertexIsNode {
|
||||
if n.Port != nil {
|
||||
err := ps.SetFromPort(n.Port.ID, n.Port.CompassPoint.String())
|
||||
err := ps.SetFromPort(unquoteID(n.Port.ID), n.Port.CompassPoint.String())
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("unable to unmarshal edge port (:%s:%s)", n.Port.ID, n.Port.CompassPoint.String()))
|
||||
}
|
||||
@@ -196,7 +262,7 @@ func applyPortsToEdge(from ast.Vertex, to *ast.Edge, edge graph.Edge) {
|
||||
|
||||
if n, vertexIsNode := to.Vertex.(*ast.Node); vertexIsNode {
|
||||
if n.Port != nil {
|
||||
err := ps.SetToPort(n.Port.ID, n.Port.CompassPoint.String())
|
||||
err := ps.SetToPort(unquoteID(n.Port.ID), n.Port.CompassPoint.String())
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("unable to unmarshal edge DOT port (:%s:%s)", n.Port.ID, n.Port.CompassPoint.String()))
|
||||
}
|
||||
@@ -206,7 +272,7 @@ func applyPortsToEdge(from ast.Vertex, to *ast.Edge, edge graph.Edge) {
|
||||
}
|
||||
|
||||
// addEdgeStmt adds the given edge statement to the graph.
|
||||
func (gen *generator) addEdgeStmt(dst encoding.Builder, stmt *ast.EdgeStmt) {
|
||||
func (gen *simpleGraph) addEdgeStmt(dst encoding.Builder, stmt *ast.EdgeStmt) {
|
||||
fs := gen.addVertex(dst, stmt.From)
|
||||
ts := gen.addEdge(dst, stmt.To, stmt.Attrs)
|
||||
for _, f := range fs {
|
||||
@@ -220,7 +286,7 @@ func (gen *generator) addEdgeStmt(dst encoding.Builder, stmt *ast.EdgeStmt) {
|
||||
}
|
||||
|
||||
// addVertex adds the given vertex to the graph, and returns its set of nodes.
|
||||
func (gen *generator) addVertex(dst encoding.Builder, v ast.Vertex) []graph.Node {
|
||||
func (gen *simpleGraph) addVertex(dst encoding.Builder, v ast.Vertex) []graph.Node {
|
||||
switch v := v.(type) {
|
||||
case *ast.Node:
|
||||
n := gen.node(dst, v.ID)
|
||||
@@ -237,7 +303,7 @@ func (gen *generator) addVertex(dst encoding.Builder, v ast.Vertex) []graph.Node
|
||||
}
|
||||
|
||||
// addEdge adds the given edge to the graph, and returns its set of nodes.
|
||||
func (gen *generator) addEdge(dst encoding.Builder, to *ast.Edge, attrs []*ast.Attr) []graph.Node {
|
||||
func (gen *simpleGraph) addEdge(dst encoding.Builder, to *ast.Edge, attrs []*ast.Attr) []graph.Node {
|
||||
if !gen.directed && to.Directed {
|
||||
panic(fmt.Errorf("directed edge to %v in undirected graph", to.Vertex))
|
||||
}
|
||||
@@ -307,19 +373,155 @@ func (gen *generator) appendSubgraphNode(n graph.Node) {
|
||||
gen.subNodes = append(gen.subNodes, n)
|
||||
}
|
||||
|
||||
type multiGraph struct{ generator }
|
||||
|
||||
// addStmt adds the given statement to the multigraph.
|
||||
func (gen *multiGraph) addStmt(dst encoding.MultiBuilder, stmt ast.Stmt) {
|
||||
switch stmt := stmt.(type) {
|
||||
case *ast.NodeStmt:
|
||||
n, ok := gen.node(dst, stmt.Node.ID).(encoding.AttributeSetter)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
for _, attr := range stmt.Attrs {
|
||||
a := encoding.Attribute{
|
||||
Key: unquoteID(attr.Key),
|
||||
Value: unquoteID(attr.Val),
|
||||
}
|
||||
if err := n.SetAttribute(a); err != nil {
|
||||
panic(fmt.Errorf("unable to unmarshal node DOT attribute (%s=%s): %v", a.Key, a.Value, err))
|
||||
}
|
||||
}
|
||||
case *ast.EdgeStmt:
|
||||
gen.addEdgeStmt(dst, stmt)
|
||||
case *ast.AttrStmt:
|
||||
var n encoding.AttributeSetter
|
||||
var dst string
|
||||
switch stmt.Kind {
|
||||
case ast.GraphKind:
|
||||
if gen.graphAttr == nil {
|
||||
return
|
||||
}
|
||||
n = gen.graphAttr
|
||||
dst = "graph"
|
||||
case ast.NodeKind:
|
||||
if gen.nodeAttr == nil {
|
||||
return
|
||||
}
|
||||
n = gen.nodeAttr
|
||||
dst = "node"
|
||||
case ast.EdgeKind:
|
||||
if gen.edgeAttr == nil {
|
||||
return
|
||||
}
|
||||
n = gen.edgeAttr
|
||||
dst = "edge"
|
||||
default:
|
||||
panic("unreachable")
|
||||
}
|
||||
for _, attr := range stmt.Attrs {
|
||||
a := encoding.Attribute{
|
||||
Key: unquoteID(attr.Key),
|
||||
Value: unquoteID(attr.Val),
|
||||
}
|
||||
if err := n.SetAttribute(a); err != nil {
|
||||
panic(fmt.Errorf("unable to unmarshal global %s DOT attribute (%s=%s): %v", dst, a.Key, a.Value, err))
|
||||
}
|
||||
}
|
||||
case *ast.Attr:
|
||||
// ignore.
|
||||
case *ast.Subgraph:
|
||||
for _, stmt := range stmt.Stmts {
|
||||
gen.addStmt(dst, stmt)
|
||||
}
|
||||
default:
|
||||
panic(fmt.Sprintf("unknown statement type %T", stmt))
|
||||
}
|
||||
}
|
||||
|
||||
// addEdgeStmt adds the given edge statement to the multigraph.
|
||||
func (gen *multiGraph) addEdgeStmt(dst encoding.MultiBuilder, stmt *ast.EdgeStmt) {
|
||||
fs := gen.addVertex(dst, stmt.From)
|
||||
ts := gen.addLine(dst, stmt.To, stmt.Attrs)
|
||||
for _, f := range fs {
|
||||
for _, t := range ts {
|
||||
edge := dst.NewLine(f, t)
|
||||
dst.SetLine(edge)
|
||||
applyPortsToEdge(stmt.From, stmt.To, edge)
|
||||
addEdgeAttrs(edge, stmt.Attrs)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// addVertex adds the given vertex to the multigraph, and returns its set of nodes.
|
||||
func (gen *multiGraph) addVertex(dst encoding.MultiBuilder, v ast.Vertex) []graph.Node {
|
||||
switch v := v.(type) {
|
||||
case *ast.Node:
|
||||
n := gen.node(dst, v.ID)
|
||||
return []graph.Node{n}
|
||||
case *ast.Subgraph:
|
||||
gen.pushSubgraph()
|
||||
for _, stmt := range v.Stmts {
|
||||
gen.addStmt(dst, stmt)
|
||||
}
|
||||
return gen.popSubgraph()
|
||||
default:
|
||||
panic(fmt.Sprintf("unknown vertex type %T", v))
|
||||
}
|
||||
}
|
||||
|
||||
// addLine adds the given edge to the multigraph, and returns its set of nodes.
|
||||
func (gen *multiGraph) addLine(dst encoding.MultiBuilder, to *ast.Edge, attrs []*ast.Attr) []graph.Node {
|
||||
if !gen.directed && to.Directed {
|
||||
panic(fmt.Errorf("directed edge to %v in undirected graph", to.Vertex))
|
||||
}
|
||||
fs := gen.addVertex(dst, to.Vertex)
|
||||
if to.To != nil {
|
||||
ts := gen.addLine(dst, to.To, attrs)
|
||||
for _, f := range fs {
|
||||
for _, t := range ts {
|
||||
edge := dst.NewLine(f, t)
|
||||
dst.SetLine(edge)
|
||||
applyPortsToEdge(to.Vertex, to.To, edge)
|
||||
addEdgeAttrs(edge, attrs)
|
||||
}
|
||||
}
|
||||
}
|
||||
return fs
|
||||
}
|
||||
|
||||
// addEdgeAttrs adds the attributes to the given edge.
|
||||
func addEdgeAttrs(edge graph.Edge, attrs []*ast.Attr) {
|
||||
func addEdgeAttrs(edge basicEdge, attrs []*ast.Attr) {
|
||||
e, ok := edge.(encoding.AttributeSetter)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
for _, attr := range attrs {
|
||||
a := encoding.Attribute{
|
||||
Key: attr.Key,
|
||||
Value: attr.Val,
|
||||
Key: unquoteID(attr.Key),
|
||||
Value: unquoteID(attr.Val),
|
||||
}
|
||||
if err := e.SetAttribute(a); err != nil {
|
||||
panic(fmt.Errorf("unable to unmarshal edge DOT attribute (%s=%s)", a.Key, a.Value))
|
||||
panic(fmt.Errorf("unable to unmarshal edge DOT attribute (%s=%s): %v", a.Key, a.Value, err))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// unquoteID unquotes the given string if needed in the context of an ID. If s
|
||||
// is not already quoted the original string is returned.
|
||||
func unquoteID(s string) string {
|
||||
// To make round-trips idempotent, don't unquote quoted HTML-like strings
|
||||
//
|
||||
// /^"<.*>"$/
|
||||
if len(s) >= 4 && strings.HasPrefix(s, `"<`) && strings.HasSuffix(s, `>"`) {
|
||||
return s
|
||||
}
|
||||
// Unquote quoted string if possible.
|
||||
if t, err := strconv.Unquote(s); err == nil {
|
||||
return t
|
||||
}
|
||||
// On error, either s is not quoted or s is quoted but contains invalid
|
||||
// characters, in both cases we return the original string rather than
|
||||
// panicking.
|
||||
return s
|
||||
}
|
||||
|
||||
9
vendor/gonum.org/v1/gonum/graph/encoding/dot/doc.go
generated
vendored
9
vendor/gonum.org/v1/gonum/graph/encoding/dot/doc.go
generated
vendored
@@ -7,8 +7,15 @@
|
||||
// See the GraphViz DOT Guide and the DOT grammar for more information
|
||||
// on using specific aspects of the DOT language:
|
||||
//
|
||||
// DOT Guide: http://www.graphviz.org/Documentation/dotguide.pdf
|
||||
// DOT Guide: https://www.graphviz.org/pdf/dotguide.pdf
|
||||
//
|
||||
// DOT grammar: http://www.graphviz.org/doc/info/lang.html
|
||||
//
|
||||
// Attribute quoting
|
||||
//
|
||||
// Attributes and IDs are quoted if needed during marshalling, to conform with
|
||||
// valid DOT syntax. Quoted IDs and attributes are unquoted during unmarshaling,
|
||||
// so the data is kept in raw form. As an exception, quoted text with a leading
|
||||
// `"<` and a trailing `>"` is not unquoted to ensure preservation of the string
|
||||
// during a round-trip.
|
||||
package dot // import "gonum.org/v1/gonum/graph/encoding/dot"
|
||||
|
||||
382
vendor/gonum.org/v1/gonum/graph/encoding/dot/encode.go
generated
vendored
382
vendor/gonum.org/v1/gonum/graph/encoding/dot/encode.go
generated
vendored
@@ -8,7 +8,9 @@ import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"gonum.org/v1/gonum/graph"
|
||||
@@ -38,15 +40,15 @@ type Attributers interface {
|
||||
|
||||
// Porter defines the behavior of graph.Edge values that can specify
|
||||
// connection ports for their end points. The returned port corresponds
|
||||
// to the the DOT node port to be used by the edge, compass corresponds
|
||||
// to the DOT node port to be used by the edge, compass corresponds
|
||||
// to DOT compass point to which the edge will be aimed.
|
||||
type Porter interface {
|
||||
// FromPort returns the port and compass for the
|
||||
// From node of a graph.Edge.
|
||||
// FromPort returns the port and compass for
|
||||
// the From node of a graph.Edge.
|
||||
FromPort() (port, compass string)
|
||||
|
||||
// ToPort returns the port and compass for the
|
||||
// To node of a graph.Edge.
|
||||
// ToPort returns the port and compass for
|
||||
// the To node of a graph.Edge.
|
||||
ToPort() (port, compass string)
|
||||
}
|
||||
|
||||
@@ -55,35 +57,71 @@ type Structurer interface {
|
||||
Structure() []Graph
|
||||
}
|
||||
|
||||
// MultiStructurer represents a graph.Multigraph that can define subgraphs.
|
||||
type MultiStructurer interface {
|
||||
Structure() []Multigraph
|
||||
}
|
||||
|
||||
// Graph wraps named graph.Graph values.
|
||||
type Graph interface {
|
||||
graph.Graph
|
||||
DOTID() string
|
||||
}
|
||||
|
||||
// Multigraph wraps named graph.Multigraph values.
|
||||
type Multigraph interface {
|
||||
graph.Multigraph
|
||||
DOTID() string
|
||||
}
|
||||
|
||||
// Subgrapher wraps graph.Node values that represent subgraphs.
|
||||
type Subgrapher interface {
|
||||
Subgraph() graph.Graph
|
||||
}
|
||||
|
||||
// Marshal returns the DOT encoding for the graph g, applying the prefix
|
||||
// and indent to the encoding. Name is used to specify the graph name. If
|
||||
// name is empty and g implements Graph, the returned string from DOTID
|
||||
// will be used. If strict is true the output bytes will be prefixed with
|
||||
// the DOT "strict" keyword.
|
||||
// MultiSubgrapher wraps graph.Node values that represent subgraphs.
|
||||
type MultiSubgrapher interface {
|
||||
Subgraph() graph.Multigraph
|
||||
}
|
||||
|
||||
// Marshal returns the DOT encoding for the graph g, applying the prefix and
|
||||
// indent to the encoding. Name is used to specify the graph name. If name is
|
||||
// empty and g implements Graph, the returned string from DOTID will be used.
|
||||
//
|
||||
// Graph serialization will work for a graph.Graph without modification,
|
||||
// however, advanced GraphViz DOT features provided by Marshal depend on
|
||||
// implementation of the Node, Attributer, Porter, Attributers, Structurer,
|
||||
// Subgrapher and Graph interfaces.
|
||||
func Marshal(g graph.Graph, name, prefix, indent string, strict bool) ([]byte, error) {
|
||||
var p printer
|
||||
//
|
||||
// Attributes and IDs are quoted if needed during marshalling.
|
||||
func Marshal(g graph.Graph, name, prefix, indent string) ([]byte, error) {
|
||||
var p simpleGraphPrinter
|
||||
p.indent = indent
|
||||
p.prefix = prefix
|
||||
p.visited = make(map[edge]bool)
|
||||
if strict {
|
||||
p.buf.WriteString("strict ")
|
||||
err := p.print(g, name, false, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return p.buf.Bytes(), nil
|
||||
}
|
||||
|
||||
// MarshalMulti returns the DOT encoding for the multigraph g, applying the
|
||||
// prefix and indent to the encoding. Name is used to specify the graph name. If
|
||||
// name is empty and g implements Graph, the returned string from DOTID will be
|
||||
// used.
|
||||
//
|
||||
// Graph serialization will work for a graph.Multigraph without modification,
|
||||
// however, advanced GraphViz DOT features provided by Marshal depend on
|
||||
// implementation of the Node, Attributer, Porter, Attributers, Structurer,
|
||||
// MultiSubgrapher and Multigraph interfaces.
|
||||
//
|
||||
// Attributes and IDs are quoted if needed during marshalling.
|
||||
func MarshalMulti(g graph.Multigraph, name, prefix, indent string) ([]byte, error) {
|
||||
var p multiGraphPrinter
|
||||
p.indent = indent
|
||||
p.prefix = prefix
|
||||
p.visited = make(map[line]bool)
|
||||
err := p.print(g, name, false, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -98,8 +136,6 @@ type printer struct {
|
||||
indent string
|
||||
depth int
|
||||
|
||||
visited map[edge]bool
|
||||
|
||||
err error
|
||||
}
|
||||
|
||||
@@ -108,35 +144,16 @@ type edge struct {
|
||||
from, to int64
|
||||
}
|
||||
|
||||
func (p *printer) print(g graph.Graph, name string, needsIndent, isSubgraph bool) error {
|
||||
nodes := g.Nodes()
|
||||
sort.Sort(ordered.ByID(nodes))
|
||||
|
||||
p.buf.WriteString(p.prefix)
|
||||
if needsIndent {
|
||||
for i := 0; i < p.depth; i++ {
|
||||
p.buf.WriteString(p.indent)
|
||||
}
|
||||
}
|
||||
_, isDirected := g.(graph.Directed)
|
||||
if isSubgraph {
|
||||
p.buf.WriteString("sub")
|
||||
} else if isDirected {
|
||||
p.buf.WriteString("di")
|
||||
}
|
||||
p.buf.WriteString("graph")
|
||||
|
||||
func (p *simpleGraphPrinter) print(g graph.Graph, name string, needsIndent, isSubgraph bool) error {
|
||||
if name == "" {
|
||||
if g, ok := g.(Graph); ok {
|
||||
name = g.DOTID()
|
||||
}
|
||||
}
|
||||
if name != "" {
|
||||
p.buf.WriteByte(' ')
|
||||
p.buf.WriteString(name)
|
||||
}
|
||||
|
||||
p.openBlock(" {")
|
||||
_, isDirected := g.(graph.Directed)
|
||||
p.printFrontMatter(name, needsIndent, isSubgraph, isDirected, true)
|
||||
|
||||
if a, ok := g.(Attributers); ok {
|
||||
p.writeAttributeComplex(a)
|
||||
}
|
||||
@@ -151,12 +168,15 @@ func (p *printer) print(g graph.Graph, name string, needsIndent, isSubgraph bool
|
||||
}
|
||||
}
|
||||
|
||||
nodes := graph.NodesOf(g.Nodes())
|
||||
sort.Sort(ordered.ByID(nodes))
|
||||
|
||||
havePrintedNodeHeader := false
|
||||
for _, n := range nodes {
|
||||
if s, ok := n.(Subgrapher); ok {
|
||||
// If the node is not linked to any other node
|
||||
// the graph needs to be written now.
|
||||
if len(g.From(n.ID())) == 0 {
|
||||
if g.From(n.ID()).Len() == 0 {
|
||||
g := s.Subgraph()
|
||||
_, subIsDirected := g.(graph.Directed)
|
||||
if subIsDirected != isDirected {
|
||||
@@ -188,7 +208,7 @@ func (p *printer) print(g graph.Graph, name string, needsIndent, isSubgraph bool
|
||||
havePrintedEdgeHeader := false
|
||||
for _, n := range nodes {
|
||||
nid := n.ID()
|
||||
to := g.From(nid)
|
||||
to := graph.NodesOf(g.From(nid))
|
||||
sort.Sort(ordered.ByID(to))
|
||||
for _, t := range to {
|
||||
tid := t.ID()
|
||||
@@ -265,19 +285,48 @@ func (p *printer) print(g graph.Graph, name string, needsIndent, isSubgraph bool
|
||||
p.buf.WriteByte(';')
|
||||
}
|
||||
}
|
||||
|
||||
p.closeBlock("}")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *printer) printFrontMatter(name string, needsIndent, isSubgraph, isDirected, isStrict bool) error {
|
||||
p.buf.WriteString(p.prefix)
|
||||
if needsIndent {
|
||||
for i := 0; i < p.depth; i++ {
|
||||
p.buf.WriteString(p.indent)
|
||||
}
|
||||
}
|
||||
|
||||
if !isSubgraph && isStrict {
|
||||
p.buf.WriteString("strict ")
|
||||
}
|
||||
|
||||
if isSubgraph {
|
||||
p.buf.WriteString("sub")
|
||||
} else if isDirected {
|
||||
p.buf.WriteString("di")
|
||||
}
|
||||
p.buf.WriteString("graph")
|
||||
|
||||
if name != "" {
|
||||
p.buf.WriteByte(' ')
|
||||
p.buf.WriteString(quoteID(name))
|
||||
}
|
||||
|
||||
p.openBlock(" {")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *printer) writeNode(n graph.Node) {
|
||||
p.buf.WriteString(nodeID(n))
|
||||
p.buf.WriteString(quoteID(nodeID(n)))
|
||||
}
|
||||
|
||||
func (p *printer) writePorts(port, cp string) {
|
||||
if port != "" {
|
||||
p.buf.WriteByte(':')
|
||||
p.buf.WriteString(port)
|
||||
p.buf.WriteString(quoteID(port))
|
||||
}
|
||||
if cp != "" {
|
||||
p.buf.WriteByte(':')
|
||||
@@ -294,7 +343,7 @@ func nodeID(n graph.Node) string {
|
||||
}
|
||||
}
|
||||
|
||||
func graphID(g graph.Graph, n graph.Node) string {
|
||||
func graphID(g interface{}, n graph.Node) string {
|
||||
switch g := g.(type) {
|
||||
case Node:
|
||||
return g.DOTID()
|
||||
@@ -309,17 +358,17 @@ func (p *printer) writeAttributeList(a encoding.Attributer) {
|
||||
case 0:
|
||||
case 1:
|
||||
p.buf.WriteString(" [")
|
||||
p.buf.WriteString(attributes[0].Key)
|
||||
p.buf.WriteString(quoteID(attributes[0].Key))
|
||||
p.buf.WriteByte('=')
|
||||
p.buf.WriteString(attributes[0].Value)
|
||||
p.buf.WriteString(quoteID(attributes[0].Value))
|
||||
p.buf.WriteString("]")
|
||||
default:
|
||||
p.openBlock(" [")
|
||||
for _, att := range attributes {
|
||||
p.newline()
|
||||
p.buf.WriteString(att.Key)
|
||||
p.buf.WriteString(quoteID(att.Key))
|
||||
p.buf.WriteByte('=')
|
||||
p.buf.WriteString(att.Value)
|
||||
p.buf.WriteString(quoteID(att.Value))
|
||||
}
|
||||
p.closeBlock("]")
|
||||
}
|
||||
@@ -343,9 +392,9 @@ func (p *printer) writeAttributeComplex(ca Attributers) {
|
||||
p.openBlock(" [")
|
||||
for _, att := range attributes {
|
||||
p.newline()
|
||||
p.buf.WriteString(att.Key)
|
||||
p.buf.WriteString(quoteID(att.Key))
|
||||
p.buf.WriteByte('=')
|
||||
p.buf.WriteString(att.Value)
|
||||
p.buf.WriteString(quoteID(att.Value))
|
||||
}
|
||||
p.closeBlock("]")
|
||||
haveWrittenBlock = true
|
||||
@@ -373,3 +422,236 @@ func (p *printer) closeBlock(b string) {
|
||||
p.newline()
|
||||
p.buf.WriteString(b)
|
||||
}
|
||||
|
||||
type simpleGraphPrinter struct {
|
||||
printer
|
||||
visited map[edge]bool
|
||||
}
|
||||
|
||||
type multiGraphPrinter struct {
|
||||
printer
|
||||
visited map[line]bool
|
||||
}
|
||||
|
||||
type line struct {
|
||||
inGraph string
|
||||
id int64
|
||||
}
|
||||
|
||||
func (p *multiGraphPrinter) print(g graph.Multigraph, name string, needsIndent, isSubgraph bool) error {
|
||||
if name == "" {
|
||||
if g, ok := g.(Multigraph); ok {
|
||||
name = g.DOTID()
|
||||
}
|
||||
}
|
||||
|
||||
_, isDirected := g.(graph.Directed)
|
||||
p.printFrontMatter(name, needsIndent, isSubgraph, isDirected, false)
|
||||
|
||||
if a, ok := g.(Attributers); ok {
|
||||
p.writeAttributeComplex(a)
|
||||
}
|
||||
if s, ok := g.(MultiStructurer); ok {
|
||||
for _, g := range s.Structure() {
|
||||
_, subIsDirected := g.(graph.Directed)
|
||||
if subIsDirected != isDirected {
|
||||
return errors.New("dot: mismatched graph type")
|
||||
}
|
||||
p.buf.WriteByte('\n')
|
||||
p.print(g, g.DOTID(), true, true)
|
||||
}
|
||||
}
|
||||
|
||||
nodes := graph.NodesOf(g.Nodes())
|
||||
sort.Sort(ordered.ByID(nodes))
|
||||
|
||||
havePrintedNodeHeader := false
|
||||
for _, n := range nodes {
|
||||
if s, ok := n.(MultiSubgrapher); ok {
|
||||
// If the node is not linked to any other node
|
||||
// the graph needs to be written now.
|
||||
if g.From(n.ID()).Len() == 0 {
|
||||
g := s.Subgraph()
|
||||
_, subIsDirected := g.(graph.Directed)
|
||||
if subIsDirected != isDirected {
|
||||
return errors.New("dot: mismatched graph type")
|
||||
}
|
||||
if !havePrintedNodeHeader {
|
||||
p.newline()
|
||||
p.buf.WriteString("// Node definitions.")
|
||||
havePrintedNodeHeader = true
|
||||
}
|
||||
p.newline()
|
||||
p.print(g, graphID(g, n), false, true)
|
||||
}
|
||||
continue
|
||||
}
|
||||
if !havePrintedNodeHeader {
|
||||
p.newline()
|
||||
p.buf.WriteString("// Node definitions.")
|
||||
havePrintedNodeHeader = true
|
||||
}
|
||||
p.newline()
|
||||
p.writeNode(n)
|
||||
if a, ok := n.(encoding.Attributer); ok {
|
||||
p.writeAttributeList(a)
|
||||
}
|
||||
p.buf.WriteByte(';')
|
||||
}
|
||||
|
||||
havePrintedEdgeHeader := false
|
||||
for _, n := range nodes {
|
||||
nid := n.ID()
|
||||
to := graph.NodesOf(g.From(nid))
|
||||
sort.Sort(ordered.ByID(to))
|
||||
|
||||
for _, t := range to {
|
||||
tid := t.ID()
|
||||
|
||||
lines := graph.LinesOf(g.Lines(nid, tid))
|
||||
sort.Sort(ordered.LinesByIDs(lines))
|
||||
|
||||
for _, l := range lines {
|
||||
lid := l.ID()
|
||||
if p.visited[line{inGraph: name, id: lid}] {
|
||||
continue
|
||||
}
|
||||
p.visited[line{inGraph: name, id: lid}] = true
|
||||
|
||||
if !havePrintedEdgeHeader {
|
||||
p.buf.WriteByte('\n')
|
||||
p.buf.WriteString(strings.TrimRight(p.prefix, " \t\n")) // Trim whitespace suffix.
|
||||
p.newline()
|
||||
p.buf.WriteString("// Edge definitions.")
|
||||
havePrintedEdgeHeader = true
|
||||
}
|
||||
p.newline()
|
||||
|
||||
if s, ok := n.(MultiSubgrapher); ok {
|
||||
g := s.Subgraph()
|
||||
_, subIsDirected := g.(graph.Directed)
|
||||
if subIsDirected != isDirected {
|
||||
return errors.New("dot: mismatched graph type")
|
||||
}
|
||||
p.print(g, graphID(g, n), false, true)
|
||||
} else {
|
||||
p.writeNode(n)
|
||||
}
|
||||
|
||||
porter, edgeIsPorter := l.(Porter)
|
||||
if edgeIsPorter {
|
||||
if l.From().ID() == nid {
|
||||
p.writePorts(porter.FromPort())
|
||||
} else {
|
||||
p.writePorts(porter.ToPort())
|
||||
}
|
||||
}
|
||||
|
||||
if isDirected {
|
||||
p.buf.WriteString(" -> ")
|
||||
} else {
|
||||
p.buf.WriteString(" -- ")
|
||||
}
|
||||
|
||||
if s, ok := t.(MultiSubgrapher); ok {
|
||||
g := s.Subgraph()
|
||||
_, subIsDirected := g.(graph.Directed)
|
||||
if subIsDirected != isDirected {
|
||||
return errors.New("dot: mismatched graph type")
|
||||
}
|
||||
p.print(g, graphID(g, t), false, true)
|
||||
} else {
|
||||
p.writeNode(t)
|
||||
}
|
||||
if edgeIsPorter {
|
||||
if l.From().ID() == nid {
|
||||
p.writePorts(porter.ToPort())
|
||||
} else {
|
||||
p.writePorts(porter.FromPort())
|
||||
}
|
||||
}
|
||||
|
||||
if a, ok := l.(encoding.Attributer); ok {
|
||||
p.writeAttributeList(a)
|
||||
}
|
||||
|
||||
p.buf.WriteByte(';')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
p.closeBlock("}")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// quoteID quotes the given string if needed in the context of an ID. If s is
|
||||
// already quoted, or if s does not contain any spaces or special characters
|
||||
// that need escaping, the original string is returned.
|
||||
func quoteID(s string) string {
|
||||
// To use a keyword as an ID, it must be quoted.
|
||||
if isKeyword(s) {
|
||||
return strconv.Quote(s)
|
||||
}
|
||||
// Quote if s is not an ID. This includes strings containing spaces, except
|
||||
// if those spaces are used within HTML string IDs (e.g. <foo >).
|
||||
if !isID(s) {
|
||||
return strconv.Quote(s)
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// isKeyword reports whether the given string is a keyword in the DOT language.
|
||||
func isKeyword(s string) bool {
|
||||
// ref: https://www.graphviz.org/doc/info/lang.html
|
||||
keywords := []string{"node", "edge", "graph", "digraph", "subgraph", "strict"}
|
||||
for _, keyword := range keywords {
|
||||
if strings.EqualFold(s, keyword) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// FIXME: see if we rewrite this in another way to remove our regexp dependency.
|
||||
|
||||
// Regular expression to match identifier and numeral IDs.
|
||||
var (
|
||||
reIdent = regexp.MustCompile(`^[a-zA-Z\200-\377_][0-9a-zA-Z\200-\377_]*$`)
|
||||
reNumeral = regexp.MustCompile(`^[-]?(\.[0-9]+|[0-9]+(\.[0-9]*)?)$`)
|
||||
)
|
||||
|
||||
// isID reports whether the given string is an ID.
|
||||
//
|
||||
// An ID is one of the following:
|
||||
//
|
||||
// 1. Any string of alphabetic ([a-zA-Z\200-\377]) characters, underscores ('_')
|
||||
// or digits ([0-9]), not beginning with a digit;
|
||||
// 2. a numeral [-]?(.[0-9]+ | [0-9]+(.[0-9]*)? );
|
||||
// 3. any double-quoted string ("...") possibly containing escaped quotes (\");
|
||||
// 4. an HTML string (<...>).
|
||||
func isID(s string) bool {
|
||||
// 1. an identifier.
|
||||
if reIdent.MatchString(s) {
|
||||
return true
|
||||
}
|
||||
// 2. a numeral.
|
||||
if reNumeral.MatchString(s) {
|
||||
return true
|
||||
}
|
||||
// 3. double-quote string ID.
|
||||
if len(s) >= 2 && strings.HasPrefix(s, `"`) && strings.HasSuffix(s, `"`) {
|
||||
// Check that escape sequences within the double-quotes are valid.
|
||||
if _, err := strconv.Unquote(s); err == nil {
|
||||
return true
|
||||
}
|
||||
}
|
||||
// 4. HTML ID.
|
||||
return isHTMLID(s)
|
||||
}
|
||||
|
||||
// isHTMLID reports whether the given string an HTML ID.
|
||||
func isHTMLID(s string) bool {
|
||||
// HTML IDs have the format /^<.*>$/
|
||||
return len(s) >= 2 && strings.HasPrefix(s, "<") && strings.HasSuffix(s, ">")
|
||||
}
|
||||
|
||||
6
vendor/gonum.org/v1/gonum/graph/encoding/encoding.go
generated
vendored
6
vendor/gonum.org/v1/gonum/graph/encoding/encoding.go
generated
vendored
@@ -12,6 +12,12 @@ type Builder interface {
|
||||
graph.Builder
|
||||
}
|
||||
|
||||
// MultiBuilder is a graph that can have user-defined nodes and edges added.
|
||||
type MultiBuilder interface {
|
||||
graph.Multigraph
|
||||
graph.MultigraphBuilder
|
||||
}
|
||||
|
||||
// AttributeSetter is implemented by types that can set an encoded graph
|
||||
// attribute.
|
||||
type AttributeSetter interface {
|
||||
|
||||
6
vendor/gonum.org/v1/gonum/graph/formats/dot/internal/errors/errors.go
generated
vendored
6
vendor/gonum.org/v1/gonum/graph/formats/dot/internal/errors/errors.go
generated
vendored
@@ -13,8 +13,8 @@
|
||||
package errors
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"gonum.org/v1/gonum/graph/formats/dot/internal/token"
|
||||
)
|
||||
@@ -31,7 +31,7 @@ type Error struct {
|
||||
}
|
||||
|
||||
func (e *Error) String() string {
|
||||
w := new(bytes.Buffer)
|
||||
w := new(strings.Builder)
|
||||
fmt.Fprintf(w, "Error")
|
||||
if e.Err != nil {
|
||||
fmt.Fprintf(w, " %s\n", e.Err)
|
||||
@@ -52,7 +52,7 @@ func (e *Error) String() string {
|
||||
}
|
||||
|
||||
func (e *Error) Error() string {
|
||||
w := new(bytes.Buffer)
|
||||
w := new(strings.Builder)
|
||||
fmt.Fprintf(w, "Error in S%d: %s, %s", e.StackTop, token.TokMap.TokenString(e.ErrorToken), e.ErrorToken.Pos.String())
|
||||
if e.Err != nil {
|
||||
fmt.Fprintf(w, ": %+v", e.Err)
|
||||
|
||||
4
vendor/gonum.org/v1/gonum/graph/formats/dot/internal/parser/parser.go
generated
vendored
4
vendor/gonum.org/v1/gonum/graph/formats/dot/internal/parser/parser.go
generated
vendored
@@ -13,8 +13,8 @@
|
||||
package parser
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
parseError "gonum.org/v1/gonum/graph/formats/dot/internal/errors"
|
||||
"gonum.org/v1/gonum/graph/formats/dot/internal/token"
|
||||
@@ -76,7 +76,7 @@ func (s *stack) popN(items int) []Attrib {
|
||||
}
|
||||
|
||||
func (s *stack) String() string {
|
||||
w := new(bytes.Buffer)
|
||||
w := new(strings.Builder)
|
||||
fmt.Fprintf(w, "stack:\n")
|
||||
for i, st := range s.state {
|
||||
fmt.Fprintf(w, "\t%d: %d , ", i, st)
|
||||
|
||||
69
vendor/gonum.org/v1/gonum/graph/graph.go
generated
vendored
69
vendor/gonum.org/v1/gonum/graph/graph.go
generated
vendored
@@ -13,8 +13,15 @@ type Node interface {
|
||||
// edge is given from -> to, otherwise the edge is semantically
|
||||
// unordered.
|
||||
type Edge interface {
|
||||
// From returns the from node of the edge.
|
||||
From() Node
|
||||
|
||||
// To returns the to node of the edge.
|
||||
To() Node
|
||||
|
||||
// ReversedEdge returns an edge that has
|
||||
// the end points of the receiver swapped.
|
||||
ReversedEdge() Edge
|
||||
}
|
||||
|
||||
// WeightedEdge is a weighted graph edge. In directed graphs, the direction
|
||||
@@ -27,16 +34,20 @@ type WeightedEdge interface {
|
||||
|
||||
// Graph is a generalized graph.
|
||||
type Graph interface {
|
||||
// Has returns whether a node with the given ID exists
|
||||
// within the graph.
|
||||
Has(id int64) bool
|
||||
// Node returns the node with the given ID if it exists
|
||||
// in the graph, and nil otherwise.
|
||||
Node(id int64) Node
|
||||
|
||||
// Nodes returns all the nodes in the graph.
|
||||
Nodes() []Node
|
||||
//
|
||||
// Nodes must not return nil.
|
||||
Nodes() Nodes
|
||||
|
||||
// From returns all nodes that can be reached directly
|
||||
// from the node with the given ID.
|
||||
From(id int64) []Node
|
||||
//
|
||||
// From must not return nil.
|
||||
From(id int64) Nodes
|
||||
|
||||
// HasEdgeBetween returns whether an edge exists between
|
||||
// nodes with IDs xid and yid without considering direction.
|
||||
@@ -99,7 +110,9 @@ type Directed interface {
|
||||
|
||||
// To returns all nodes that can reach directly
|
||||
// to the node with the given ID.
|
||||
To(id int64) []Node
|
||||
//
|
||||
// To must not return nil.
|
||||
To(id int64) Nodes
|
||||
}
|
||||
|
||||
// WeightedDirected is a weighted directed graph.
|
||||
@@ -113,7 +126,9 @@ type WeightedDirected interface {
|
||||
|
||||
// To returns all nodes that can reach directly
|
||||
// to the node with the given ID.
|
||||
To(id int64) []Node
|
||||
//
|
||||
// To must not return nil.
|
||||
To(id int64) Nodes
|
||||
}
|
||||
|
||||
// NodeAdder is an interface for adding arbitrary nodes to a graph.
|
||||
@@ -122,7 +137,7 @@ type NodeAdder interface {
|
||||
// arbitrary ID.
|
||||
NewNode() Node
|
||||
|
||||
// Adds a node to the graph. AddNode panics if
|
||||
// AddNode adds a node to the graph. AddNode panics if
|
||||
// the added node ID matches an existing node ID.
|
||||
AddNode(Node)
|
||||
}
|
||||
@@ -146,8 +161,10 @@ type EdgeAdder interface {
|
||||
// will be added if they do not exist, otherwise
|
||||
// SetEdge will panic.
|
||||
// The behavior of an EdgeAdder when the IDs
|
||||
// returned by e.From and e.To are equal is
|
||||
// returned by e.From() and e.To() are equal is
|
||||
// implementation-dependent.
|
||||
// Whether e, e.From() and e.To() are stored
|
||||
// within the graph is implementation dependent.
|
||||
SetEdge(e Edge)
|
||||
}
|
||||
|
||||
@@ -162,8 +179,10 @@ type WeightedEdgeAdder interface {
|
||||
// the nodes will be added if they do not exist,
|
||||
// otherwise SetWeightedEdge will panic.
|
||||
// The behavior of a WeightedEdgeAdder when the IDs
|
||||
// returned by e.From and e.To are equal is
|
||||
// returned by e.From() and e.To() are equal is
|
||||
// implementation-dependent.
|
||||
// Whether e, e.From() and e.To() are stored
|
||||
// within the graph is implementation dependent.
|
||||
SetWeightedEdge(e WeightedEdge)
|
||||
}
|
||||
|
||||
@@ -219,12 +238,17 @@ type DirectedWeightedBuilder interface {
|
||||
// be present in the destination after the copy is complete.
|
||||
func Copy(dst Builder, src Graph) {
|
||||
nodes := src.Nodes()
|
||||
for _, n := range nodes {
|
||||
dst.AddNode(n)
|
||||
for nodes.Next() {
|
||||
dst.AddNode(nodes.Node())
|
||||
}
|
||||
for _, u := range nodes {
|
||||
for _, v := range src.From(u.ID()) {
|
||||
dst.SetEdge(dst.NewEdge(u, v))
|
||||
nodes.Reset()
|
||||
for nodes.Next() {
|
||||
u := nodes.Node()
|
||||
uid := u.ID()
|
||||
to := src.From(uid)
|
||||
for to.Next() {
|
||||
v := to.Node()
|
||||
dst.SetEdge(src.Edge(uid, v.ID()))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -242,12 +266,17 @@ func Copy(dst Builder, src Graph) {
|
||||
// to resolve such conflicts, an UndirectWeighted may be used to do this.
|
||||
func CopyWeighted(dst WeightedBuilder, src Weighted) {
|
||||
nodes := src.Nodes()
|
||||
for _, n := range nodes {
|
||||
dst.AddNode(n)
|
||||
for nodes.Next() {
|
||||
dst.AddNode(nodes.Node())
|
||||
}
|
||||
for _, u := range nodes {
|
||||
for _, v := range src.From(u.ID()) {
|
||||
dst.SetWeightedEdge(dst.NewWeightedEdge(u, v, src.WeightedEdge(u.ID(), v.ID()).Weight()))
|
||||
nodes.Reset()
|
||||
for nodes.Next() {
|
||||
u := nodes.Node()
|
||||
uid := u.ID()
|
||||
to := src.From(uid)
|
||||
for to.Next() {
|
||||
v := to.Node()
|
||||
dst.SetWeightedEdge(src.WeightedEdge(uid, v.ID()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
17
vendor/gonum.org/v1/gonum/graph/internal/ordered/sort.go
generated
vendored
17
vendor/gonum.org/v1/gonum/graph/internal/ordered/sort.go
generated
vendored
@@ -74,3 +74,20 @@ func Reverse(nodes []graph.Node) {
|
||||
nodes[i], nodes[j] = nodes[j], nodes[i]
|
||||
}
|
||||
}
|
||||
|
||||
// LinesByIDs implements the sort.Interface sorting a slice of graph.LinesByIDs
|
||||
// lexically by the From IDs, then by the To IDs, finally by the Line IDs.
|
||||
type LinesByIDs []graph.Line
|
||||
|
||||
func (n LinesByIDs) Len() int { return len(n) }
|
||||
func (n LinesByIDs) Less(i, j int) bool {
|
||||
a, b := n[i], n[j]
|
||||
if a.From().ID() != b.From().ID() {
|
||||
return a.From().ID() < b.From().ID()
|
||||
}
|
||||
if a.To().ID() != b.To().ID() {
|
||||
return a.To().ID() < b.To().ID()
|
||||
}
|
||||
return n[i].ID() < n[j].ID()
|
||||
}
|
||||
func (n LinesByIDs) Swap(i, j int) { n[i], n[j] = n[j], n[i] }
|
||||
|
||||
100
vendor/gonum.org/v1/gonum/graph/internal/set/set.go
generated
vendored
100
vendor/gonum.org/v1/gonum/graph/internal/set/set.go
generated
vendored
@@ -103,6 +103,16 @@ func Int64sEqual(a, b Int64s) bool {
|
||||
// Nodes is a set of nodes keyed in their integer identifiers.
|
||||
type Nodes map[int64]graph.Node
|
||||
|
||||
// NewNodes returns a new Nodes.
|
||||
func NewNodes() Nodes {
|
||||
return make(Nodes)
|
||||
}
|
||||
|
||||
// NewNodes returns a new Nodes with the given size hint, n.
|
||||
func NewNodesSize(n int) Nodes {
|
||||
return make(Nodes, n)
|
||||
}
|
||||
|
||||
// The simple accessor methods for Nodes are provided to allow ease of
|
||||
// implementation change should the need arise.
|
||||
|
||||
@@ -116,34 +126,23 @@ func (s Nodes) Remove(e graph.Node) {
|
||||
delete(s, e.ID())
|
||||
}
|
||||
|
||||
// Has reports the existence of the element in the set.
|
||||
// Count returns the number of element in the set.
|
||||
func (s Nodes) Count() int {
|
||||
return len(s)
|
||||
}
|
||||
|
||||
// Has reports the existence of the elements in the set.
|
||||
func (s Nodes) Has(n graph.Node) bool {
|
||||
_, ok := s[n.ID()]
|
||||
return ok
|
||||
}
|
||||
|
||||
// clear clears the set, possibly using the same backing store.
|
||||
func (s *Nodes) clear() {
|
||||
if len(*s) != 0 {
|
||||
*s = make(Nodes)
|
||||
}
|
||||
}
|
||||
|
||||
// Copy performs a perfect copy from src to dst (meaning the sets will
|
||||
// be equal).
|
||||
func (dst Nodes) Copy(src Nodes) Nodes {
|
||||
if same(src, dst) {
|
||||
return dst
|
||||
}
|
||||
|
||||
if len(dst) > 0 {
|
||||
dst = make(Nodes, len(src))
|
||||
}
|
||||
|
||||
// CloneNodes returns a clone of src.
|
||||
func CloneNodes(src Nodes) Nodes {
|
||||
dst := make(Nodes, len(src))
|
||||
for e, n := range src {
|
||||
dst[e] = n
|
||||
}
|
||||
|
||||
return dst
|
||||
}
|
||||
|
||||
@@ -167,7 +166,7 @@ func Equal(a, b Nodes) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// Union takes the union of a and b, and stores it in dst.
|
||||
// UnionOfNodes returns the union of a and b.
|
||||
//
|
||||
// The union of two sets, a and b, is the set containing all the
|
||||
// elements of each, for instance:
|
||||
@@ -179,31 +178,23 @@ func Equal(a, b Nodes) bool {
|
||||
//
|
||||
// {a,b,c} UNION {b,c,d} = {a,b,c,d}
|
||||
//
|
||||
func (dst Nodes) Union(a, b Nodes) Nodes {
|
||||
func UnionOfNodes(a, b Nodes) Nodes {
|
||||
if same(a, b) {
|
||||
return dst.Copy(a)
|
||||
return CloneNodes(a)
|
||||
}
|
||||
|
||||
if !same(a, dst) && !same(b, dst) {
|
||||
dst.clear()
|
||||
dst := make(Nodes)
|
||||
for e, n := range a {
|
||||
dst[e] = n
|
||||
}
|
||||
|
||||
if !same(dst, a) {
|
||||
for e, n := range a {
|
||||
dst[e] = n
|
||||
}
|
||||
}
|
||||
|
||||
if !same(dst, b) {
|
||||
for e, n := range b {
|
||||
dst[e] = n
|
||||
}
|
||||
for e, n := range b {
|
||||
dst[e] = n
|
||||
}
|
||||
|
||||
return dst
|
||||
}
|
||||
|
||||
// Intersect takes the intersection of a and b, and stores it in dst.
|
||||
// IntersectionOfNodes returns the intersection of a and b.
|
||||
//
|
||||
// The intersection of two sets, a and b, is the set containing all
|
||||
// the elements shared between the two sets, for instance:
|
||||
@@ -220,37 +211,18 @@ func (dst Nodes) Union(a, b Nodes) Nodes {
|
||||
//
|
||||
// {a,b,c} INTERSECT {d,e,f} = {}
|
||||
//
|
||||
func (dst Nodes) Intersect(a, b Nodes) Nodes {
|
||||
var swap Nodes
|
||||
|
||||
func IntersectionOfNodes(a, b Nodes) Nodes {
|
||||
if same(a, b) {
|
||||
return dst.Copy(a)
|
||||
return CloneNodes(a)
|
||||
}
|
||||
if same(a, dst) {
|
||||
swap = b
|
||||
} else if same(b, dst) {
|
||||
swap = a
|
||||
} else {
|
||||
dst.clear()
|
||||
|
||||
if len(a) > len(b) {
|
||||
a, b = b, a
|
||||
}
|
||||
|
||||
for e, n := range a {
|
||||
if _, ok := b[e]; ok {
|
||||
dst[e] = n
|
||||
}
|
||||
}
|
||||
|
||||
return dst
|
||||
dst := make(Nodes)
|
||||
if len(a) > len(b) {
|
||||
a, b = b, a
|
||||
}
|
||||
|
||||
for e := range dst {
|
||||
if _, ok := swap[e]; !ok {
|
||||
delete(dst, e)
|
||||
for e, n := range a {
|
||||
if _, ok := b[e]; ok {
|
||||
dst[e] = n
|
||||
}
|
||||
}
|
||||
|
||||
return dst
|
||||
}
|
||||
|
||||
29
vendor/gonum.org/v1/gonum/graph/iterator/BUILD
generated
vendored
Normal file
29
vendor/gonum.org/v1/gonum/graph/iterator/BUILD
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"doc.go",
|
||||
"edges.go",
|
||||
"lines.go",
|
||||
"nodes.go",
|
||||
],
|
||||
importmap = "k8s.io/kubernetes/vendor/gonum.org/v1/gonum/graph/iterator",
|
||||
importpath = "gonum.org/v1/gonum/graph/iterator",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = ["//vendor/gonum.org/v1/gonum/graph:go_default_library"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
9
vendor/gonum.org/v1/gonum/graph/iterator/doc.go
generated
vendored
Normal file
9
vendor/gonum.org/v1/gonum/graph/iterator/doc.go
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
// Copyright ©2018 The Gonum Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package iterator provides node, edge and line iterators.
|
||||
//
|
||||
// The iterators provided satisfy the graph.Nodes, graph.Edges and
|
||||
// graph.Lines interfaces.
|
||||
package iterator
|
||||
131
vendor/gonum.org/v1/gonum/graph/iterator/edges.go
generated
vendored
Normal file
131
vendor/gonum.org/v1/gonum/graph/iterator/edges.go
generated
vendored
Normal file
@@ -0,0 +1,131 @@
|
||||
// Copyright ©2018 The Gonum Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package iterator
|
||||
|
||||
import "gonum.org/v1/gonum/graph"
|
||||
|
||||
// OrderedEdges implements the graph.Edges and graph.EdgeSlicer interfaces.
|
||||
// The iteration order of OrderedEdges is the order of edges passed to
|
||||
// NewEdgeIterator.
|
||||
type OrderedEdges struct {
|
||||
idx int
|
||||
edges []graph.Edge
|
||||
}
|
||||
|
||||
// NewOrderedEdges returns an OrderedEdges initialized with the provided edges.
|
||||
func NewOrderedEdges(edges []graph.Edge) *OrderedEdges {
|
||||
return &OrderedEdges{idx: -1, edges: edges}
|
||||
}
|
||||
|
||||
// Len returns the remaining number of edges to be iterated over.
|
||||
func (e *OrderedEdges) Len() int {
|
||||
if e.idx >= len(e.edges) {
|
||||
return 0
|
||||
}
|
||||
if e.idx <= 0 {
|
||||
return len(e.edges)
|
||||
}
|
||||
return len(e.edges[e.idx:])
|
||||
}
|
||||
|
||||
// Next returns whether the next call of Edge will return a valid edge.
|
||||
func (e *OrderedEdges) Next() bool {
|
||||
if uint(e.idx)+1 < uint(len(e.edges)) {
|
||||
e.idx++
|
||||
return true
|
||||
}
|
||||
e.idx = len(e.edges)
|
||||
return false
|
||||
}
|
||||
|
||||
// Edge returns the current edge of the iterator. Next must have been
|
||||
// called prior to a call to Edge.
|
||||
func (e *OrderedEdges) Edge() graph.Edge {
|
||||
if e.idx >= len(e.edges) || e.idx < 0 {
|
||||
return nil
|
||||
}
|
||||
return e.edges[e.idx]
|
||||
}
|
||||
|
||||
// EdgeSlice returns all the remaining edges in the iterator and advances
|
||||
// the iterator.
|
||||
func (e *OrderedEdges) EdgeSlice() []graph.Edge {
|
||||
if e.idx >= len(e.edges) {
|
||||
return nil
|
||||
}
|
||||
idx := e.idx
|
||||
if idx == -1 {
|
||||
idx = 0
|
||||
}
|
||||
e.idx = len(e.edges)
|
||||
return e.edges[idx:]
|
||||
}
|
||||
|
||||
// Reset returns the iterator to its initial state.
|
||||
func (e *OrderedEdges) Reset() {
|
||||
e.idx = -1
|
||||
}
|
||||
|
||||
// OrderedWeightedEdges implements the graph.Edges and graph.EdgeSlicer interfaces.
|
||||
// The iteration order of OrderedWeightedEdges is the order of edges passed to
|
||||
// NewEdgeIterator.
|
||||
type OrderedWeightedEdges struct {
|
||||
idx int
|
||||
edges []graph.WeightedEdge
|
||||
}
|
||||
|
||||
// NewOrderedWeightedEdges returns an OrderedWeightedEdges initialized with the provided edges.
|
||||
func NewOrderedWeightedEdges(edges []graph.WeightedEdge) *OrderedWeightedEdges {
|
||||
return &OrderedWeightedEdges{idx: -1, edges: edges}
|
||||
}
|
||||
|
||||
// Len returns the remaining number of edges to be iterated over.
|
||||
func (e *OrderedWeightedEdges) Len() int {
|
||||
if e.idx >= len(e.edges) {
|
||||
return 0
|
||||
}
|
||||
if e.idx <= 0 {
|
||||
return len(e.edges)
|
||||
}
|
||||
return len(e.edges[e.idx:])
|
||||
}
|
||||
|
||||
// Next returns whether the next call of WeightedEdge will return a valid edge.
|
||||
func (e *OrderedWeightedEdges) Next() bool {
|
||||
if uint(e.idx)+1 < uint(len(e.edges)) {
|
||||
e.idx++
|
||||
return true
|
||||
}
|
||||
e.idx = len(e.edges)
|
||||
return false
|
||||
}
|
||||
|
||||
// WeightedEdge returns the current edge of the iterator. Next must have been
|
||||
// called prior to a call to WeightedEdge.
|
||||
func (e *OrderedWeightedEdges) WeightedEdge() graph.WeightedEdge {
|
||||
if e.idx >= len(e.edges) || e.idx < 0 {
|
||||
return nil
|
||||
}
|
||||
return e.edges[e.idx]
|
||||
}
|
||||
|
||||
// WeightedEdgeSlice returns all the remaining edges in the iterator and advances
|
||||
// the iterator.
|
||||
func (e *OrderedWeightedEdges) WeightedEdgeSlice() []graph.WeightedEdge {
|
||||
if e.idx >= len(e.edges) {
|
||||
return nil
|
||||
}
|
||||
idx := e.idx
|
||||
if idx == -1 {
|
||||
idx = 0
|
||||
}
|
||||
e.idx = len(e.edges)
|
||||
return e.edges[idx:]
|
||||
}
|
||||
|
||||
// Reset returns the iterator to its initial state.
|
||||
func (e *OrderedWeightedEdges) Reset() {
|
||||
e.idx = -1
|
||||
}
|
||||
131
vendor/gonum.org/v1/gonum/graph/iterator/lines.go
generated
vendored
Normal file
131
vendor/gonum.org/v1/gonum/graph/iterator/lines.go
generated
vendored
Normal file
@@ -0,0 +1,131 @@
|
||||
// Copyright ©2018 The Gonum Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package iterator
|
||||
|
||||
import "gonum.org/v1/gonum/graph"
|
||||
|
||||
// OrderedLines implements the graph.Lines and graph.LineSlicer interfaces.
|
||||
// The iteration order of OrderedLines is the order of lines passed to
|
||||
// NewLineIterator.
|
||||
type OrderedLines struct {
|
||||
idx int
|
||||
lines []graph.Line
|
||||
}
|
||||
|
||||
// NewOrderedLines returns an OrderedLines initialized with the provided lines.
|
||||
func NewOrderedLines(lines []graph.Line) *OrderedLines {
|
||||
return &OrderedLines{idx: -1, lines: lines}
|
||||
}
|
||||
|
||||
// Len returns the remaining number of lines to be iterated over.
|
||||
func (e *OrderedLines) Len() int {
|
||||
if e.idx >= len(e.lines) {
|
||||
return 0
|
||||
}
|
||||
if e.idx <= 0 {
|
||||
return len(e.lines)
|
||||
}
|
||||
return len(e.lines[e.idx:])
|
||||
}
|
||||
|
||||
// Next returns whether the next call of Line will return a valid line.
|
||||
func (e *OrderedLines) Next() bool {
|
||||
if uint(e.idx)+1 < uint(len(e.lines)) {
|
||||
e.idx++
|
||||
return true
|
||||
}
|
||||
e.idx = len(e.lines)
|
||||
return false
|
||||
}
|
||||
|
||||
// Line returns the current line of the iterator. Next must have been
|
||||
// called prior to a call to Line.
|
||||
func (e *OrderedLines) Line() graph.Line {
|
||||
if e.idx >= len(e.lines) || e.idx < 0 {
|
||||
return nil
|
||||
}
|
||||
return e.lines[e.idx]
|
||||
}
|
||||
|
||||
// LineSlice returns all the remaining lines in the iterator and advances
|
||||
// the iterator.
|
||||
func (e *OrderedLines) LineSlice() []graph.Line {
|
||||
if e.idx >= len(e.lines) {
|
||||
return nil
|
||||
}
|
||||
idx := e.idx
|
||||
if idx == -1 {
|
||||
idx = 0
|
||||
}
|
||||
e.idx = len(e.lines)
|
||||
return e.lines[idx:]
|
||||
}
|
||||
|
||||
// Reset returns the iterator to its initial state.
|
||||
func (e *OrderedLines) Reset() {
|
||||
e.idx = -1
|
||||
}
|
||||
|
||||
// OrderedWeightedLines implements the graph.Lines and graph.LineSlicer interfaces.
|
||||
// The iteration order of OrderedWeightedLines is the order of lines passed to
|
||||
// NewLineIterator.
|
||||
type OrderedWeightedLines struct {
|
||||
idx int
|
||||
lines []graph.WeightedLine
|
||||
}
|
||||
|
||||
// NewWeightedLineIterator returns an OrderedWeightedLines initialized with the provided lines.
|
||||
func NewOrderedWeightedLines(lines []graph.WeightedLine) *OrderedWeightedLines {
|
||||
return &OrderedWeightedLines{idx: -1, lines: lines}
|
||||
}
|
||||
|
||||
// Len returns the remaining number of lines to be iterated over.
|
||||
func (e *OrderedWeightedLines) Len() int {
|
||||
if e.idx >= len(e.lines) {
|
||||
return 0
|
||||
}
|
||||
if e.idx <= 0 {
|
||||
return len(e.lines)
|
||||
}
|
||||
return len(e.lines[e.idx:])
|
||||
}
|
||||
|
||||
// Next returns whether the next call of WeightedLine will return a valid line.
|
||||
func (e *OrderedWeightedLines) Next() bool {
|
||||
if uint(e.idx)+1 < uint(len(e.lines)) {
|
||||
e.idx++
|
||||
return true
|
||||
}
|
||||
e.idx = len(e.lines)
|
||||
return false
|
||||
}
|
||||
|
||||
// WeightedLine returns the current line of the iterator. Next must have been
|
||||
// called prior to a call to WeightedLine.
|
||||
func (e *OrderedWeightedLines) WeightedLine() graph.WeightedLine {
|
||||
if e.idx >= len(e.lines) || e.idx < 0 {
|
||||
return nil
|
||||
}
|
||||
return e.lines[e.idx]
|
||||
}
|
||||
|
||||
// WeightedLineSlice returns all the remaining lines in the iterator and advances
|
||||
// the iterator.
|
||||
func (e *OrderedWeightedLines) WeightedLineSlice() []graph.WeightedLine {
|
||||
if e.idx >= len(e.lines) {
|
||||
return nil
|
||||
}
|
||||
idx := e.idx
|
||||
if idx == -1 {
|
||||
idx = 0
|
||||
}
|
||||
e.idx = len(e.lines)
|
||||
return e.lines[idx:]
|
||||
}
|
||||
|
||||
// Reset returns the iterator to its initial state.
|
||||
func (e *OrderedWeightedLines) Reset() {
|
||||
e.idx = -1
|
||||
}
|
||||
125
vendor/gonum.org/v1/gonum/graph/iterator/nodes.go
generated
vendored
Normal file
125
vendor/gonum.org/v1/gonum/graph/iterator/nodes.go
generated
vendored
Normal file
@@ -0,0 +1,125 @@
|
||||
// Copyright ©2018 The Gonum Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package iterator
|
||||
|
||||
import "gonum.org/v1/gonum/graph"
|
||||
|
||||
// OrderedNodes implements the graph.Nodes and graph.NodeSlicer interfaces.
|
||||
// The iteration order of OrderedNodes is the order of nodes passed to
|
||||
// NewNodeIterator.
|
||||
type OrderedNodes struct {
|
||||
idx int
|
||||
nodes []graph.Node
|
||||
}
|
||||
|
||||
// NewOrderedNodes returns a OrderedNodes initialized with the provided nodes.
|
||||
func NewOrderedNodes(nodes []graph.Node) *OrderedNodes {
|
||||
return &OrderedNodes{idx: -1, nodes: nodes}
|
||||
}
|
||||
|
||||
// Len returns the remaining number of nodes to be iterated over.
|
||||
func (n *OrderedNodes) Len() int {
|
||||
if n.idx >= len(n.nodes) {
|
||||
return 0
|
||||
}
|
||||
if n.idx <= 0 {
|
||||
return len(n.nodes)
|
||||
}
|
||||
return len(n.nodes[n.idx:])
|
||||
}
|
||||
|
||||
// Next returns whether the next call of Node will return a valid node.
|
||||
func (n *OrderedNodes) Next() bool {
|
||||
if uint(n.idx)+1 < uint(len(n.nodes)) {
|
||||
n.idx++
|
||||
return true
|
||||
}
|
||||
n.idx = len(n.nodes)
|
||||
return false
|
||||
}
|
||||
|
||||
// Node returns the current node of the iterator. Next must have been
|
||||
// called prior to a call to Node.
|
||||
func (n *OrderedNodes) Node() graph.Node {
|
||||
if n.idx >= len(n.nodes) || n.idx < 0 {
|
||||
return nil
|
||||
}
|
||||
return n.nodes[n.idx]
|
||||
}
|
||||
|
||||
// NodeSlice returns all the remaining nodes in the iterator and advances
|
||||
// the iterator.
|
||||
func (n *OrderedNodes) NodeSlice() []graph.Node {
|
||||
if n.idx >= len(n.nodes) {
|
||||
return nil
|
||||
}
|
||||
idx := n.idx
|
||||
if idx == -1 {
|
||||
idx = 0
|
||||
}
|
||||
n.idx = len(n.nodes)
|
||||
return n.nodes[idx:]
|
||||
}
|
||||
|
||||
// Reset returns the iterator to its initial state.
|
||||
func (n *OrderedNodes) Reset() {
|
||||
n.idx = -1
|
||||
}
|
||||
|
||||
// ImplicitNodes implements the graph.Nodes interface for a set of nodes over
|
||||
// a contiguous ID range.
|
||||
type ImplicitNodes struct {
|
||||
beg, end int
|
||||
curr int
|
||||
newNode func(id int) graph.Node
|
||||
}
|
||||
|
||||
// NewImplicitNodes returns a new implicit node iterator spanning nodes in [beg,end).
|
||||
// The provided new func maps the id to a graph.Node. NewImplicitNodes will panic
|
||||
// if beg is greater than end.
|
||||
func NewImplicitNodes(beg, end int, new func(id int) graph.Node) *ImplicitNodes {
|
||||
if beg > end {
|
||||
panic("iterator: invalid range")
|
||||
}
|
||||
return &ImplicitNodes{beg: beg, end: end, curr: beg - 1, newNode: new}
|
||||
}
|
||||
|
||||
// Len returns the remaining number of nodes to be iterated over.
|
||||
func (n *ImplicitNodes) Len() int {
|
||||
return n.end - n.curr - 1
|
||||
}
|
||||
|
||||
// Next returns whether the next call of Node will return a valid node.
|
||||
func (n *ImplicitNodes) Next() bool {
|
||||
if n.curr == n.end {
|
||||
return false
|
||||
}
|
||||
n.curr++
|
||||
return n.curr < n.end
|
||||
}
|
||||
|
||||
// Node returns the current node of the iterator. Next must have been
|
||||
// called prior to a call to Node.
|
||||
func (n *ImplicitNodes) Node() graph.Node {
|
||||
if n.Len() == -1 || n.curr < n.beg {
|
||||
return nil
|
||||
}
|
||||
return n.newNode(n.curr)
|
||||
}
|
||||
|
||||
// Reset returns the iterator to its initial state.
|
||||
func (n *ImplicitNodes) Reset() {
|
||||
n.curr = n.beg - 1
|
||||
}
|
||||
|
||||
// NodeSlice returns all the remaining nodes in the iterator and advances
|
||||
// the iterator.
|
||||
func (n *ImplicitNodes) NodeSlice() []graph.Node {
|
||||
nodes := make([]graph.Node, 0, n.Len())
|
||||
for n.curr++; n.curr < n.end; n.curr++ {
|
||||
nodes = append(nodes, n.newNode(n.curr))
|
||||
}
|
||||
return nodes
|
||||
}
|
||||
56
vendor/gonum.org/v1/gonum/graph/multigraph.go
generated
vendored
56
vendor/gonum.org/v1/gonum/graph/multigraph.go
generated
vendored
@@ -7,7 +7,17 @@ package graph
|
||||
// Line is an edge in a multigraph. A Line returns an ID that must
|
||||
// distinguish Lines sharing Node end points.
|
||||
type Line interface {
|
||||
Edge
|
||||
// From returns the from node of the edge.
|
||||
From() Node
|
||||
|
||||
// To returns the to node of the edge.
|
||||
To() Node
|
||||
|
||||
// ReversedLine returns a line that has the
|
||||
// end points of the receiver swapped.
|
||||
ReversedLine() Line
|
||||
|
||||
// ID returns the unique ID for the Line.
|
||||
ID() int64
|
||||
}
|
||||
|
||||
@@ -19,16 +29,20 @@ type WeightedLine interface {
|
||||
|
||||
// Multigraph is a generalized multigraph.
|
||||
type Multigraph interface {
|
||||
// Has returns whether the node with the given ID exists
|
||||
// within the multigraph.
|
||||
Has(id int64) bool
|
||||
// Node returns the node with the given ID if it exists
|
||||
// in the multigraph, and nil otherwise.
|
||||
Node(id int64) Node
|
||||
|
||||
// Nodes returns all the nodes in the multigraph.
|
||||
Nodes() []Node
|
||||
//
|
||||
// Nodes must not return nil.
|
||||
Nodes() Nodes
|
||||
|
||||
// From returns all nodes that can be reached directly
|
||||
// from the node with the given ID.
|
||||
From(id int64) []Node
|
||||
//
|
||||
// From must not return nil.
|
||||
From(id int64) Nodes
|
||||
|
||||
// HasEdgeBetween returns whether an edge exists between
|
||||
// nodes with IDs xid and yid without considering direction.
|
||||
@@ -38,7 +52,9 @@ type Multigraph interface {
|
||||
// vid, if any such lines exist and nil otherwise. The
|
||||
// node v must be directly reachable from u as defined by
|
||||
// the From method.
|
||||
Lines(uid, vid int64) []Line
|
||||
//
|
||||
// Lines must not return nil.
|
||||
Lines(uid, vid int64) Lines
|
||||
}
|
||||
|
||||
// WeightedMultigraph is a weighted multigraph.
|
||||
@@ -49,7 +65,9 @@ type WeightedMultigraph interface {
|
||||
// with IDs uid and vid if any such lines exist and nil
|
||||
// otherwise. The node v must be directly reachable
|
||||
// from u as defined by the From method.
|
||||
WeightedLines(uid, vid int64) []WeightedLine
|
||||
//
|
||||
// WeightedLines must not return nil.
|
||||
WeightedLines(uid, vid int64) WeightedLines
|
||||
}
|
||||
|
||||
// UndirectedMultigraph is an undirected multigraph.
|
||||
@@ -58,7 +76,9 @@ type UndirectedMultigraph interface {
|
||||
|
||||
// LinesBetween returns the lines between nodes x and y
|
||||
// with IDs xid and yid.
|
||||
LinesBetween(xid, yid int64) []Line
|
||||
//
|
||||
// LinesBetween must not return nil.
|
||||
LinesBetween(xid, yid int64) Lines
|
||||
}
|
||||
|
||||
// WeightedUndirectedMultigraph is a weighted undirected multigraph.
|
||||
@@ -67,7 +87,9 @@ type WeightedUndirectedMultigraph interface {
|
||||
|
||||
// WeightedLinesBetween returns the lines between nodes
|
||||
// x and y with IDs xid and yid.
|
||||
WeightedLinesBetween(xid, yid int64) []WeightedLine
|
||||
//
|
||||
// WeightedLinesBetween must not return nil.
|
||||
WeightedLinesBetween(xid, yid int64) WeightedLines
|
||||
}
|
||||
|
||||
// DirectedMultigraph is a directed multigraph.
|
||||
@@ -81,7 +103,9 @@ type DirectedMultigraph interface {
|
||||
|
||||
// To returns all nodes that can reach directly
|
||||
// to the node with the given ID.
|
||||
To(id int64) []Node
|
||||
//
|
||||
// To must not return nil.
|
||||
To(id int64) Nodes
|
||||
}
|
||||
|
||||
// WeightedDirectedMultigraph is a weighted directed multigraph.
|
||||
@@ -95,7 +119,9 @@ type WeightedDirectedMultigraph interface {
|
||||
|
||||
// To returns all nodes that can reach directly
|
||||
// to the node with the given ID.
|
||||
To(id int64) []Node
|
||||
//
|
||||
// To must not return nil.
|
||||
To(id int64) Nodes
|
||||
}
|
||||
|
||||
// LineAdder is an interface for adding lines to a multigraph.
|
||||
@@ -107,6 +133,8 @@ type LineAdder interface {
|
||||
// If the multigraph supports node addition the nodes
|
||||
// will be added if they do not exist, otherwise
|
||||
// SetLine will panic.
|
||||
// Whether l, l.From() and l.To() are stored
|
||||
// within the graph is implementation dependent.
|
||||
SetLine(l Line)
|
||||
}
|
||||
|
||||
@@ -120,7 +148,9 @@ type WeightedLineAdder interface {
|
||||
// to another. If the multigraph supports node addition
|
||||
// the nodes will be added if they do not exist,
|
||||
// otherwise SetWeightedLine will panic.
|
||||
SetWeightedLine(e WeightedLine)
|
||||
// Whether l, l.From() and l.To() are stored
|
||||
// within the graph is implementation dependent.
|
||||
SetWeightedLine(l WeightedLine)
|
||||
}
|
||||
|
||||
// LineRemover is an interface for removing lines from a multigraph.
|
||||
|
||||
300
vendor/gonum.org/v1/gonum/graph/nodes_edges.go
generated
vendored
Normal file
300
vendor/gonum.org/v1/gonum/graph/nodes_edges.go
generated
vendored
Normal file
@@ -0,0 +1,300 @@
|
||||
// Copyright ©2018 The Gonum Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package graph
|
||||
|
||||
// Iterator is an item iterator.
|
||||
type Iterator interface {
|
||||
// Next advances the iterator and returns whether
|
||||
// the next call to the item method will return a
|
||||
// non-nil item.
|
||||
//
|
||||
// Next should be called prior to any call to the
|
||||
// iterator's item retrieval method after the
|
||||
// iterator has been obtained or reset.
|
||||
//
|
||||
// The order of iteration is implementation
|
||||
// dependent.
|
||||
Next() bool
|
||||
|
||||
// Len returns the number of items remaining in the
|
||||
// iterator.
|
||||
//
|
||||
// If the number of items in the iterator is unknown,
|
||||
// too large to materialize or too costly to calculate
|
||||
// then Len may return a negative value.
|
||||
// In this case the consuming function must be able
|
||||
// to operate on the items of the iterator directly
|
||||
// without materializing the items into a slice.
|
||||
// The magnitude of a negative length has
|
||||
// implementation-dependent semantics.
|
||||
Len() int
|
||||
|
||||
// Reset returns the iterator to its start position.
|
||||
Reset()
|
||||
}
|
||||
|
||||
// Nodes is a Node iterator.
|
||||
type Nodes interface {
|
||||
Iterator
|
||||
|
||||
// Node returns the current Node from the iterator.
|
||||
Node() Node
|
||||
}
|
||||
|
||||
// NodeSlicer wraps the NodeSlice method.
|
||||
type NodeSlicer interface {
|
||||
// NodeSlice returns the set of nodes remaining
|
||||
// to be iterated by a Nodes iterator.
|
||||
// The holder of the iterator may arbitrarily
|
||||
// change elements in the returned slice, but
|
||||
// those changes may be reflected to other
|
||||
// iterators.
|
||||
NodeSlice() []Node
|
||||
}
|
||||
|
||||
// NodesOf returns it.Len() nodes from it. If it is a NodeSlicer, the NodeSlice method
|
||||
// is used to obtain the nodes. It is safe to pass a nil Nodes to NodesOf.
|
||||
//
|
||||
// If the Nodes has an indeterminate length, NodesOf will panic.
|
||||
func NodesOf(it Nodes) []Node {
|
||||
if it == nil {
|
||||
return nil
|
||||
}
|
||||
len := it.Len()
|
||||
switch {
|
||||
case len == 0:
|
||||
return nil
|
||||
case len < 0:
|
||||
panic("graph: called NodesOf on indeterminate iterator")
|
||||
}
|
||||
switch it := it.(type) {
|
||||
case NodeSlicer:
|
||||
return it.NodeSlice()
|
||||
}
|
||||
n := make([]Node, 0, len)
|
||||
for it.Next() {
|
||||
n = append(n, it.Node())
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
// Edges is an Edge iterator.
|
||||
type Edges interface {
|
||||
Iterator
|
||||
|
||||
// Edge returns the current Edge from the iterator.
|
||||
Edge() Edge
|
||||
}
|
||||
|
||||
// EdgeSlicer wraps the EdgeSlice method.
|
||||
type EdgeSlicer interface {
|
||||
// EdgeSlice returns the set of edges remaining
|
||||
// to be iterated by an Edges iterator.
|
||||
// The holder of the iterator may arbitrarily
|
||||
// change elements in the returned slice, but
|
||||
// those changes may be reflected to other
|
||||
// iterators.
|
||||
EdgeSlice() []Edge
|
||||
}
|
||||
|
||||
// EdgesOf returns it.Len() nodes from it. If it is an EdgeSlicer, the EdgeSlice method is used
|
||||
// to obtain the edges. It is safe to pass a nil Edges to EdgesOf.
|
||||
//
|
||||
// If the Edges has an indeterminate length, EdgesOf will panic.
|
||||
func EdgesOf(it Edges) []Edge {
|
||||
if it == nil {
|
||||
return nil
|
||||
}
|
||||
len := it.Len()
|
||||
switch {
|
||||
case len == 0:
|
||||
return nil
|
||||
case len < 0:
|
||||
panic("graph: called EdgesOf on indeterminate iterator")
|
||||
}
|
||||
switch it := it.(type) {
|
||||
case EdgeSlicer:
|
||||
return it.EdgeSlice()
|
||||
}
|
||||
e := make([]Edge, 0, len)
|
||||
for it.Next() {
|
||||
e = append(e, it.Edge())
|
||||
}
|
||||
return e
|
||||
}
|
||||
|
||||
// WeightedEdges is a WeightedEdge iterator.
|
||||
type WeightedEdges interface {
|
||||
Iterator
|
||||
|
||||
// Edge returns the current Edge from the iterator.
|
||||
WeightedEdge() WeightedEdge
|
||||
}
|
||||
|
||||
// WeightedEdgeSlicer wraps the WeightedEdgeSlice method.
|
||||
type WeightedEdgeSlicer interface {
|
||||
// EdgeSlice returns the set of edges remaining
|
||||
// to be iterated by an Edges iterator.
|
||||
// The holder of the iterator may arbitrarily
|
||||
// change elements in the returned slice, but
|
||||
// those changes may be reflected to other
|
||||
// iterators.
|
||||
WeightedEdgeSlice() []WeightedEdge
|
||||
}
|
||||
|
||||
// WeightedEdgesOf returns it.Len() weighted edge from it. If it is a WeightedEdgeSlicer, the
|
||||
// WeightedEdgeSlice method is used to obtain the edges. It is safe to pass a nil WeightedEdges
|
||||
// to WeightedEdgesOf.
|
||||
//
|
||||
// If the WeightedEdges has an indeterminate length, WeightedEdgesOf will panic.
|
||||
func WeightedEdgesOf(it WeightedEdges) []WeightedEdge {
|
||||
if it == nil {
|
||||
return nil
|
||||
}
|
||||
len := it.Len()
|
||||
switch {
|
||||
case len == 0:
|
||||
return nil
|
||||
case len < 0:
|
||||
panic("graph: called WeightedEdgesOf on indeterminate iterator")
|
||||
}
|
||||
switch it := it.(type) {
|
||||
case WeightedEdgeSlicer:
|
||||
return it.WeightedEdgeSlice()
|
||||
}
|
||||
e := make([]WeightedEdge, 0, len)
|
||||
for it.Next() {
|
||||
e = append(e, it.WeightedEdge())
|
||||
}
|
||||
return e
|
||||
}
|
||||
|
||||
// Lines is a Line iterator.
|
||||
type Lines interface {
|
||||
Iterator
|
||||
|
||||
// Line returns the current Line from the iterator.
|
||||
Line() Line
|
||||
}
|
||||
|
||||
// LineSlicer wraps the LineSlice method.
|
||||
type LineSlicer interface {
|
||||
// LineSlice returns the set of lines remaining
|
||||
// to be iterated by an Lines iterator.
|
||||
// The holder of the iterator may arbitrarily
|
||||
// change elements in the returned slice, but
|
||||
// those changes may be reflected to other
|
||||
// iterators.
|
||||
LineSlice() []Line
|
||||
}
|
||||
|
||||
// LinesOf returns it.Len() nodes from it. If it is a LineSlicer, the LineSlice method is used
|
||||
// to obtain the lines. It is safe to pass a nil Lines to LinesOf.
|
||||
//
|
||||
// If the Lines has an indeterminate length, LinesOf will panic.
|
||||
func LinesOf(it Lines) []Line {
|
||||
if it == nil {
|
||||
return nil
|
||||
}
|
||||
len := it.Len()
|
||||
switch {
|
||||
case len == 0:
|
||||
return nil
|
||||
case len < 0:
|
||||
panic("graph: called LinesOf on indeterminate iterator")
|
||||
}
|
||||
switch it := it.(type) {
|
||||
case LineSlicer:
|
||||
return it.LineSlice()
|
||||
}
|
||||
l := make([]Line, 0, len)
|
||||
for it.Next() {
|
||||
l = append(l, it.Line())
|
||||
}
|
||||
return l
|
||||
}
|
||||
|
||||
// WeightedLines is a WeightedLine iterator.
|
||||
type WeightedLines interface {
|
||||
Iterator
|
||||
|
||||
// Line returns the current Line from the iterator.
|
||||
WeightedLine() WeightedLine
|
||||
}
|
||||
|
||||
// WeightedLineSlicer wraps the WeightedLineSlice method.
|
||||
type WeightedLineSlicer interface {
|
||||
// LineSlice returns the set of lines remaining
|
||||
// to be iterated by an Lines iterator.
|
||||
// The holder of the iterator may arbitrarily
|
||||
// change elements in the returned slice, but
|
||||
// those changes may be reflected to other
|
||||
// iterators.
|
||||
WeightedLineSlice() []WeightedLine
|
||||
}
|
||||
|
||||
// WeightedLinesOf returns it.Len() weighted line from it. If it is a WeightedLineSlicer, the
|
||||
// WeightedLineSlice method is used to obtain the lines. It is safe to pass a nil WeightedLines
|
||||
// to WeightedLinesOf.
|
||||
//
|
||||
// If the WeightedLines has an indeterminate length, WeightedLinesOf will panic.
|
||||
func WeightedLinesOf(it WeightedLines) []WeightedLine {
|
||||
if it == nil {
|
||||
return nil
|
||||
}
|
||||
len := it.Len()
|
||||
switch {
|
||||
case len == 0:
|
||||
return nil
|
||||
case len < 0:
|
||||
panic("graph: called WeightedLinesOf on indeterminate iterator")
|
||||
}
|
||||
switch it := it.(type) {
|
||||
case WeightedLineSlicer:
|
||||
return it.WeightedLineSlice()
|
||||
}
|
||||
l := make([]WeightedLine, 0, len)
|
||||
for it.Next() {
|
||||
l = append(l, it.WeightedLine())
|
||||
}
|
||||
return l
|
||||
}
|
||||
|
||||
// Empty is an empty set of nodes, edges or lines. It should be used when
|
||||
// a graph returns a zero-length Iterator. Empty implements the slicer
|
||||
// interfaces for nodes, edges and lines, returning nil for each of these.
|
||||
const Empty = nothing
|
||||
|
||||
var (
|
||||
_ Iterator = Empty
|
||||
_ Nodes = Empty
|
||||
_ NodeSlicer = Empty
|
||||
_ Edges = Empty
|
||||
_ EdgeSlicer = Empty
|
||||
_ WeightedEdges = Empty
|
||||
_ WeightedEdgeSlicer = Empty
|
||||
_ Lines = Empty
|
||||
_ LineSlicer = Empty
|
||||
_ WeightedLines = Empty
|
||||
_ WeightedLineSlicer = Empty
|
||||
)
|
||||
|
||||
const nothing = empty(true)
|
||||
|
||||
type empty bool
|
||||
|
||||
func (empty) Next() bool { return false }
|
||||
func (empty) Len() int { return 0 }
|
||||
func (empty) Reset() {}
|
||||
func (empty) Node() Node { return nil }
|
||||
func (empty) NodeSlice() []Node { return nil }
|
||||
func (empty) Edge() Edge { return nil }
|
||||
func (empty) EdgeSlice() []Edge { return nil }
|
||||
func (empty) WeightedEdge() WeightedEdge { return nil }
|
||||
func (empty) WeightedEdgeSlice() []WeightedEdge { return nil }
|
||||
func (empty) Line() Line { return nil }
|
||||
func (empty) LineSlice() []Line { return nil }
|
||||
func (empty) WeightedLine() WeightedLine { return nil }
|
||||
func (empty) WeightedLineSlice() []WeightedLine { return nil }
|
||||
1
vendor/gonum.org/v1/gonum/graph/simple/BUILD
generated
vendored
1
vendor/gonum.org/v1/gonum/graph/simple/BUILD
generated
vendored
@@ -19,6 +19,7 @@ go_library(
|
||||
"//vendor/gonum.org/v1/gonum/graph:go_default_library",
|
||||
"//vendor/gonum.org/v1/gonum/graph/internal/ordered:go_default_library",
|
||||
"//vendor/gonum.org/v1/gonum/graph/internal/uid:go_default_library",
|
||||
"//vendor/gonum.org/v1/gonum/graph/iterator:go_default_library",
|
||||
"//vendor/gonum.org/v1/gonum/mat:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
282
vendor/gonum.org/v1/gonum/graph/simple/dense_directed_matrix.go
generated
vendored
282
vendor/gonum.org/v1/gonum/graph/simple/dense_directed_matrix.go
generated
vendored
@@ -9,9 +9,19 @@ import (
|
||||
|
||||
"gonum.org/v1/gonum/graph"
|
||||
"gonum.org/v1/gonum/graph/internal/ordered"
|
||||
"gonum.org/v1/gonum/graph/iterator"
|
||||
"gonum.org/v1/gonum/mat"
|
||||
)
|
||||
|
||||
var (
|
||||
dm *DirectedMatrix
|
||||
|
||||
_ graph.Graph = dm
|
||||
_ graph.Directed = dm
|
||||
_ edgeSetter = dm
|
||||
_ weightedEdgeSetter = dm
|
||||
)
|
||||
|
||||
// DirectedMatrix represents a directed graph using an adjacency
|
||||
// matrix such that all IDs are in a contiguous block from 0 to n-1.
|
||||
// Edges are stored implicitly as an edge weight, so edges stored in
|
||||
@@ -63,44 +73,14 @@ func NewDirectedMatrixFrom(nodes []graph.Node, init, self, absent float64) *Dire
|
||||
return g
|
||||
}
|
||||
|
||||
// Node returns the node in the graph with the given ID.
|
||||
func (g *DirectedMatrix) Node(id int64) graph.Node {
|
||||
if !g.has(id) {
|
||||
return nil
|
||||
}
|
||||
if g.nodes == nil {
|
||||
return Node(id)
|
||||
}
|
||||
return g.nodes[id]
|
||||
}
|
||||
|
||||
// Has returns whether the node exists within the graph.
|
||||
func (g *DirectedMatrix) Has(id int64) bool {
|
||||
return g.has(id)
|
||||
}
|
||||
|
||||
func (g *DirectedMatrix) has(id int64) bool {
|
||||
r, _ := g.mat.Dims()
|
||||
return 0 <= id && id < int64(r)
|
||||
}
|
||||
|
||||
// Nodes returns all the nodes in the graph.
|
||||
func (g *DirectedMatrix) Nodes() []graph.Node {
|
||||
if g.nodes != nil {
|
||||
nodes := make([]graph.Node, len(g.nodes))
|
||||
copy(nodes, g.nodes)
|
||||
return nodes
|
||||
}
|
||||
r, _ := g.mat.Dims()
|
||||
nodes := make([]graph.Node, r)
|
||||
for i := 0; i < r; i++ {
|
||||
nodes[i] = Node(i)
|
||||
}
|
||||
return nodes
|
||||
// Edge returns the edge from u to v if such an edge exists and nil otherwise.
|
||||
// The node v must be directly reachable from u as defined by the From method.
|
||||
func (g *DirectedMatrix) Edge(uid, vid int64) graph.Edge {
|
||||
return g.WeightedEdge(uid, vid)
|
||||
}
|
||||
|
||||
// Edges returns all the edges in the graph.
|
||||
func (g *DirectedMatrix) Edges() []graph.Edge {
|
||||
func (g *DirectedMatrix) Edges() graph.Edges {
|
||||
var edges []graph.Edge
|
||||
r, _ := g.mat.Dims()
|
||||
for i := 0; i < r; i++ {
|
||||
@@ -113,15 +93,18 @@ func (g *DirectedMatrix) Edges() []graph.Edge {
|
||||
}
|
||||
}
|
||||
}
|
||||
return edges
|
||||
if len(edges) == 0 {
|
||||
return graph.Empty
|
||||
}
|
||||
return iterator.NewOrderedEdges(edges)
|
||||
}
|
||||
|
||||
// From returns all nodes in g that can be reached directly from n.
|
||||
func (g *DirectedMatrix) From(id int64) []graph.Node {
|
||||
func (g *DirectedMatrix) From(id int64) graph.Nodes {
|
||||
if !g.has(id) {
|
||||
return nil
|
||||
return graph.Empty
|
||||
}
|
||||
var neighbors []graph.Node
|
||||
var nodes []graph.Node
|
||||
_, c := g.mat.Dims()
|
||||
for j := 0; j < c; j++ {
|
||||
if int64(j) == id {
|
||||
@@ -129,29 +112,13 @@ func (g *DirectedMatrix) From(id int64) []graph.Node {
|
||||
}
|
||||
// id is not greater than maximum int by this point.
|
||||
if !isSame(g.mat.At(int(id), j), g.absent) {
|
||||
neighbors = append(neighbors, g.Node(int64(j)))
|
||||
nodes = append(nodes, g.Node(int64(j)))
|
||||
}
|
||||
}
|
||||
return neighbors
|
||||
}
|
||||
|
||||
// To returns all nodes in g that can reach directly to n.
|
||||
func (g *DirectedMatrix) To(id int64) []graph.Node {
|
||||
if !g.has(id) {
|
||||
return nil
|
||||
if len(nodes) == 0 {
|
||||
return graph.Empty
|
||||
}
|
||||
var neighbors []graph.Node
|
||||
r, _ := g.mat.Dims()
|
||||
for i := 0; i < r; i++ {
|
||||
if int64(i) == id {
|
||||
continue
|
||||
}
|
||||
// id is not greater than maximum int by this point.
|
||||
if !isSame(g.mat.At(i, int(id)), g.absent) {
|
||||
neighbors = append(neighbors, g.Node(int64(i)))
|
||||
}
|
||||
}
|
||||
return neighbors
|
||||
return iterator.NewOrderedNodes(nodes)
|
||||
}
|
||||
|
||||
// HasEdgeBetween returns whether an edge exists between nodes x and y without
|
||||
@@ -167,22 +134,6 @@ func (g *DirectedMatrix) HasEdgeBetween(xid, yid int64) bool {
|
||||
return xid != yid && (!isSame(g.mat.At(int(xid), int(yid)), g.absent) || !isSame(g.mat.At(int(yid), int(xid)), g.absent))
|
||||
}
|
||||
|
||||
// Edge returns the edge from u to v if such an edge exists and nil otherwise.
|
||||
// The node v must be directly reachable from u as defined by the From method.
|
||||
func (g *DirectedMatrix) Edge(uid, vid int64) graph.Edge {
|
||||
return g.WeightedEdge(uid, vid)
|
||||
}
|
||||
|
||||
// WeightedEdge returns the weighted edge from u to v if such an edge exists and nil otherwise.
|
||||
// The node v must be directly reachable from u as defined by the From method.
|
||||
func (g *DirectedMatrix) WeightedEdge(uid, vid int64) graph.WeightedEdge {
|
||||
if g.HasEdgeFromTo(uid, vid) {
|
||||
// xid and yid are not greater than maximum int by this point.
|
||||
return WeightedEdge{F: g.Node(uid), T: g.Node(vid), W: g.mat.At(int(uid), int(vid))}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// HasEdgeFromTo returns whether an edge exists in the graph from u to v.
|
||||
func (g *DirectedMatrix) HasEdgeFromTo(uid, vid int64) bool {
|
||||
if !g.has(uid) {
|
||||
@@ -195,47 +146,37 @@ func (g *DirectedMatrix) HasEdgeFromTo(uid, vid int64) bool {
|
||||
return uid != vid && !isSame(g.mat.At(int(uid), int(vid)), g.absent)
|
||||
}
|
||||
|
||||
// Weight returns the weight for the edge between x and y if Edge(x, y) returns a non-nil Edge.
|
||||
// If x and y are the same node or there is no joining edge between the two nodes the weight
|
||||
// value returned is either the graph's absent or self value. Weight returns true if an edge
|
||||
// exists between x and y or if x and y have the same ID, false otherwise.
|
||||
func (g *DirectedMatrix) Weight(xid, yid int64) (w float64, ok bool) {
|
||||
if xid == yid {
|
||||
return g.self, true
|
||||
}
|
||||
if g.has(xid) && g.has(yid) {
|
||||
// xid and yid are not greater than maximum int by this point.
|
||||
return g.mat.At(int(xid), int(yid)), true
|
||||
}
|
||||
return g.absent, false
|
||||
// Matrix returns the mat.Matrix representation of the graph. The orientation
|
||||
// of the matrix is such that the matrix entry at G_{ij} is the weight of the edge
|
||||
// from node i to node j.
|
||||
func (g *DirectedMatrix) Matrix() mat.Matrix {
|
||||
// Prevent alteration of dimensions of the returned matrix.
|
||||
m := *g.mat
|
||||
return &m
|
||||
}
|
||||
|
||||
// SetEdge sets e, an edge from one node to another with unit weight. If the ends of the edge
|
||||
// are not in g or the edge is a self loop, SetEdge panics.
|
||||
func (g *DirectedMatrix) SetEdge(e graph.Edge) {
|
||||
g.setWeightedEdge(e, 1)
|
||||
// Node returns the node with the given ID if it exists in the graph,
|
||||
// and nil otherwise.
|
||||
func (g *DirectedMatrix) Node(id int64) graph.Node {
|
||||
if !g.has(id) {
|
||||
return nil
|
||||
}
|
||||
if g.nodes == nil {
|
||||
return Node(id)
|
||||
}
|
||||
return g.nodes[id]
|
||||
}
|
||||
|
||||
// SetWeightedEdge sets e, an edge from one node to another. If the ends of the edge are not in g
|
||||
// or the edge is a self loop, SetWeightedEdge panics.
|
||||
func (g *DirectedMatrix) SetWeightedEdge(e graph.WeightedEdge) {
|
||||
g.setWeightedEdge(e, e.Weight())
|
||||
}
|
||||
|
||||
func (g *DirectedMatrix) setWeightedEdge(e graph.Edge, weight float64) {
|
||||
fid := e.From().ID()
|
||||
tid := e.To().ID()
|
||||
if fid == tid {
|
||||
panic("simple: set illegal edge")
|
||||
// Nodes returns all the nodes in the graph.
|
||||
func (g *DirectedMatrix) Nodes() graph.Nodes {
|
||||
if g.nodes != nil {
|
||||
nodes := make([]graph.Node, len(g.nodes))
|
||||
copy(nodes, g.nodes)
|
||||
return iterator.NewOrderedNodes(nodes)
|
||||
}
|
||||
if int64(int(fid)) != fid {
|
||||
panic("simple: unavailable from node ID for dense graph")
|
||||
}
|
||||
if int64(int(tid)) != tid {
|
||||
panic("simple: unavailable to node ID for dense graph")
|
||||
}
|
||||
// fid and tid are not greater than maximum int by this point.
|
||||
g.mat.Set(int(fid), int(tid), weight)
|
||||
r, _ := g.mat.Dims()
|
||||
// Matrix graphs must have at least one node.
|
||||
return iterator.NewImplicitNodes(0, r, newSimpleNode)
|
||||
}
|
||||
|
||||
// RemoveEdge removes the edge with the given end point nodes from the graph, leaving the terminal
|
||||
@@ -251,39 +192,110 @@ func (g *DirectedMatrix) RemoveEdge(fid, tid int64) {
|
||||
g.mat.Set(int(fid), int(tid), g.absent)
|
||||
}
|
||||
|
||||
// Degree returns the in+out degree of n in g.
|
||||
func (g *DirectedMatrix) Degree(id int64) int {
|
||||
if !g.has(id) {
|
||||
return 0
|
||||
// SetEdge sets e, an edge from one node to another with unit weight. If the ends of the edge
|
||||
// are not in g or the edge is a self loop, SetEdge panics. SetEdge will store the nodes of
|
||||
// e in the graph if it was initialized with NewDirectedMatrixFrom.
|
||||
func (g *DirectedMatrix) SetEdge(e graph.Edge) {
|
||||
g.setWeightedEdge(e, 1)
|
||||
}
|
||||
|
||||
// SetWeightedEdge sets e, an edge from one node to another. If the ends of the edge are not in g
|
||||
// or the edge is a self loop, SetWeightedEdge panics. SetWeightedEdge will store the nodes of
|
||||
// e in the graph if it was initialized with NewDirectedMatrixFrom.
|
||||
func (g *DirectedMatrix) SetWeightedEdge(e graph.WeightedEdge) {
|
||||
g.setWeightedEdge(e, e.Weight())
|
||||
}
|
||||
|
||||
func (g *DirectedMatrix) setWeightedEdge(e graph.Edge, weight float64) {
|
||||
from := e.From()
|
||||
fid := from.ID()
|
||||
to := e.To()
|
||||
tid := to.ID()
|
||||
if fid == tid {
|
||||
panic("simple: set illegal edge")
|
||||
}
|
||||
var deg int
|
||||
r, c := g.mat.Dims()
|
||||
if int64(int(fid)) != fid {
|
||||
panic("simple: unavailable from node ID for dense graph")
|
||||
}
|
||||
if int64(int(tid)) != tid {
|
||||
panic("simple: unavailable to node ID for dense graph")
|
||||
}
|
||||
if g.nodes != nil {
|
||||
g.nodes[fid] = from
|
||||
g.nodes[tid] = to
|
||||
}
|
||||
// fid and tid are not greater than maximum int by this point.
|
||||
g.mat.Set(int(fid), int(tid), weight)
|
||||
}
|
||||
|
||||
// To returns all nodes in g that can reach directly to n.
|
||||
func (g *DirectedMatrix) To(id int64) graph.Nodes {
|
||||
if !g.has(id) {
|
||||
return graph.Empty
|
||||
}
|
||||
var nodes []graph.Node
|
||||
r, _ := g.mat.Dims()
|
||||
for i := 0; i < r; i++ {
|
||||
if int64(i) == id {
|
||||
continue
|
||||
}
|
||||
// id is not greater than maximum int by this point.
|
||||
if !isSame(g.mat.At(int(id), i), g.absent) {
|
||||
deg++
|
||||
}
|
||||
}
|
||||
for i := 0; i < c; i++ {
|
||||
if int64(i) == id {
|
||||
continue
|
||||
}
|
||||
// id is not greater than maximum int by this point.
|
||||
if !isSame(g.mat.At(i, int(id)), g.absent) {
|
||||
deg++
|
||||
nodes = append(nodes, g.Node(int64(i)))
|
||||
}
|
||||
}
|
||||
return deg
|
||||
if len(nodes) == 0 {
|
||||
return graph.Empty
|
||||
}
|
||||
return iterator.NewOrderedNodes(nodes)
|
||||
}
|
||||
|
||||
// Matrix returns the mat.Matrix representation of the graph. The orientation
|
||||
// of the matrix is such that the matrix entry at G_{ij} is the weight of the edge
|
||||
// from node i to node j.
|
||||
func (g *DirectedMatrix) Matrix() mat.Matrix {
|
||||
// Prevent alteration of dimensions of the returned matrix.
|
||||
m := *g.mat
|
||||
return &m
|
||||
// Weight returns the weight for the edge between x and y if Edge(x, y) returns a non-nil Edge.
|
||||
// If x and y are the same node or there is no joining edge between the two nodes the weight
|
||||
// value returned is either the graph's absent or self value. Weight returns true if an edge
|
||||
// exists between x and y or if x and y have the same ID, false otherwise.
|
||||
func (g *DirectedMatrix) Weight(xid, yid int64) (w float64, ok bool) {
|
||||
if xid == yid {
|
||||
return g.self, true
|
||||
}
|
||||
if g.HasEdgeFromTo(xid, yid) {
|
||||
// xid and yid are not greater than maximum int by this point.
|
||||
return g.mat.At(int(xid), int(yid)), true
|
||||
}
|
||||
return g.absent, false
|
||||
}
|
||||
|
||||
// WeightedEdge returns the weighted edge from u to v if such an edge exists and nil otherwise.
|
||||
// The node v must be directly reachable from u as defined by the From method.
|
||||
func (g *DirectedMatrix) WeightedEdge(uid, vid int64) graph.WeightedEdge {
|
||||
if g.HasEdgeFromTo(uid, vid) {
|
||||
// xid and yid are not greater than maximum int by this point.
|
||||
return WeightedEdge{F: g.Node(uid), T: g.Node(vid), W: g.mat.At(int(uid), int(vid))}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// WeightedEdges returns all the edges in the graph.
|
||||
func (g *DirectedMatrix) WeightedEdges() graph.WeightedEdges {
|
||||
var edges []graph.WeightedEdge
|
||||
r, _ := g.mat.Dims()
|
||||
for i := 0; i < r; i++ {
|
||||
for j := 0; j < r; j++ {
|
||||
if i == j {
|
||||
continue
|
||||
}
|
||||
if w := g.mat.At(i, j); !isSame(w, g.absent) {
|
||||
edges = append(edges, WeightedEdge{F: g.Node(int64(i)), T: g.Node(int64(j)), W: w})
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(edges) == 0 {
|
||||
return graph.Empty
|
||||
}
|
||||
return iterator.NewOrderedWeightedEdges(edges)
|
||||
}
|
||||
|
||||
func (g *DirectedMatrix) has(id int64) bool {
|
||||
r, _ := g.mat.Dims()
|
||||
return 0 <= id && id < int64(r)
|
||||
}
|
||||
|
||||
259
vendor/gonum.org/v1/gonum/graph/simple/dense_undirected_matrix.go
generated
vendored
259
vendor/gonum.org/v1/gonum/graph/simple/dense_undirected_matrix.go
generated
vendored
@@ -9,9 +9,19 @@ import (
|
||||
|
||||
"gonum.org/v1/gonum/graph"
|
||||
"gonum.org/v1/gonum/graph/internal/ordered"
|
||||
"gonum.org/v1/gonum/graph/iterator"
|
||||
"gonum.org/v1/gonum/mat"
|
||||
)
|
||||
|
||||
var (
|
||||
um *UndirectedMatrix
|
||||
|
||||
_ graph.Graph = um
|
||||
_ graph.Undirected = um
|
||||
_ edgeSetter = um
|
||||
_ weightedEdgeSetter = um
|
||||
)
|
||||
|
||||
// UndirectedMatrix represents an undirected graph using an adjacency
|
||||
// matrix such that all IDs are in a contiguous block from 0 to n-1.
|
||||
// Edges are stored implicitly as an edge weight, so edges stored in
|
||||
@@ -63,44 +73,19 @@ func NewUndirectedMatrixFrom(nodes []graph.Node, init, self, absent float64) *Un
|
||||
return g
|
||||
}
|
||||
|
||||
// Node returns the node in the graph with the given ID.
|
||||
func (g *UndirectedMatrix) Node(id int64) graph.Node {
|
||||
if !g.has(id) {
|
||||
return nil
|
||||
}
|
||||
if g.nodes == nil {
|
||||
return Node(id)
|
||||
}
|
||||
return g.nodes[id]
|
||||
// Edge returns the edge from u to v if such an edge exists and nil otherwise.
|
||||
// The node v must be directly reachable from u as defined by the From method.
|
||||
func (g *UndirectedMatrix) Edge(uid, vid int64) graph.Edge {
|
||||
return g.WeightedEdgeBetween(uid, vid)
|
||||
}
|
||||
|
||||
// Has returns whether the node exists within the graph.
|
||||
func (g *UndirectedMatrix) Has(id int64) bool {
|
||||
return g.has(id)
|
||||
}
|
||||
|
||||
func (g *UndirectedMatrix) has(id int64) bool {
|
||||
r := g.mat.Symmetric()
|
||||
return 0 <= id && id < int64(r)
|
||||
}
|
||||
|
||||
// Nodes returns all the nodes in the graph.
|
||||
func (g *UndirectedMatrix) Nodes() []graph.Node {
|
||||
if g.nodes != nil {
|
||||
nodes := make([]graph.Node, len(g.nodes))
|
||||
copy(nodes, g.nodes)
|
||||
return nodes
|
||||
}
|
||||
r := g.mat.Symmetric()
|
||||
nodes := make([]graph.Node, r)
|
||||
for i := 0; i < r; i++ {
|
||||
nodes[i] = Node(i)
|
||||
}
|
||||
return nodes
|
||||
// EdgeBetween returns the edge between nodes x and y.
|
||||
func (g *UndirectedMatrix) EdgeBetween(uid, vid int64) graph.Edge {
|
||||
return g.WeightedEdgeBetween(uid, vid)
|
||||
}
|
||||
|
||||
// Edges returns all the edges in the graph.
|
||||
func (g *UndirectedMatrix) Edges() []graph.Edge {
|
||||
func (g *UndirectedMatrix) Edges() graph.Edges {
|
||||
var edges []graph.Edge
|
||||
r, _ := g.mat.Dims()
|
||||
for i := 0; i < r; i++ {
|
||||
@@ -110,15 +95,18 @@ func (g *UndirectedMatrix) Edges() []graph.Edge {
|
||||
}
|
||||
}
|
||||
}
|
||||
return edges
|
||||
if len(edges) == 0 {
|
||||
return graph.Empty
|
||||
}
|
||||
return iterator.NewOrderedEdges(edges)
|
||||
}
|
||||
|
||||
// From returns all nodes in g that can be reached directly from n.
|
||||
func (g *UndirectedMatrix) From(id int64) []graph.Node {
|
||||
func (g *UndirectedMatrix) From(id int64) graph.Nodes {
|
||||
if !g.has(id) {
|
||||
return nil
|
||||
return graph.Empty
|
||||
}
|
||||
var neighbors []graph.Node
|
||||
var nodes []graph.Node
|
||||
r := g.mat.Symmetric()
|
||||
for i := 0; i < r; i++ {
|
||||
if int64(i) == id {
|
||||
@@ -126,10 +114,13 @@ func (g *UndirectedMatrix) From(id int64) []graph.Node {
|
||||
}
|
||||
// id is not greater than maximum int by this point.
|
||||
if !isSame(g.mat.At(int(id), i), g.absent) {
|
||||
neighbors = append(neighbors, g.Node(int64(i)))
|
||||
nodes = append(nodes, g.Node(int64(i)))
|
||||
}
|
||||
}
|
||||
return neighbors
|
||||
if len(nodes) == 0 {
|
||||
return graph.Empty
|
||||
}
|
||||
return iterator.NewOrderedNodes(nodes)
|
||||
}
|
||||
|
||||
// HasEdgeBetween returns whether an edge exists between nodes x and y.
|
||||
@@ -144,73 +135,35 @@ func (g *UndirectedMatrix) HasEdgeBetween(uid, vid int64) bool {
|
||||
return uid != vid && !isSame(g.mat.At(int(uid), int(vid)), g.absent)
|
||||
}
|
||||
|
||||
// Edge returns the edge from u to v if such an edge exists and nil otherwise.
|
||||
// The node v must be directly reachable from u as defined by the From method.
|
||||
func (g *UndirectedMatrix) Edge(uid, vid int64) graph.Edge {
|
||||
return g.WeightedEdgeBetween(uid, vid)
|
||||
// Matrix returns the mat.Matrix representation of the graph.
|
||||
func (g *UndirectedMatrix) Matrix() mat.Matrix {
|
||||
// Prevent alteration of dimensions of the returned matrix.
|
||||
m := *g.mat
|
||||
return &m
|
||||
}
|
||||
|
||||
// WeightedEdge returns the weighted edge from u to v if such an edge exists and nil otherwise.
|
||||
// The node v must be directly reachable from u as defined by the From method.
|
||||
func (g *UndirectedMatrix) WeightedEdge(uid, vid int64) graph.WeightedEdge {
|
||||
return g.WeightedEdgeBetween(uid, vid)
|
||||
}
|
||||
|
||||
// EdgeBetween returns the edge between nodes x and y.
|
||||
func (g *UndirectedMatrix) EdgeBetween(uid, vid int64) graph.Edge {
|
||||
return g.WeightedEdgeBetween(uid, vid)
|
||||
}
|
||||
|
||||
// WeightedEdgeBetween returns the weighted edge between nodes x and y.
|
||||
func (g *UndirectedMatrix) WeightedEdgeBetween(uid, vid int64) graph.WeightedEdge {
|
||||
if g.HasEdgeBetween(uid, vid) {
|
||||
// uid and vid are not greater than maximum int by this point.
|
||||
return WeightedEdge{F: g.Node(uid), T: g.Node(vid), W: g.mat.At(int(uid), int(vid))}
|
||||
// Node returns the node with the given ID if it exists in the graph,
|
||||
// and nil otherwise.
|
||||
func (g *UndirectedMatrix) Node(id int64) graph.Node {
|
||||
if !g.has(id) {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
if g.nodes == nil {
|
||||
return Node(id)
|
||||
}
|
||||
return g.nodes[id]
|
||||
}
|
||||
|
||||
// Weight returns the weight for the edge between x and y if Edge(x, y) returns a non-nil Edge.
|
||||
// If x and y are the same node or there is no joining edge between the two nodes the weight
|
||||
// value returned is either the graph's absent or self value. Weight returns true if an edge
|
||||
// exists between x and y or if x and y have the same ID, false otherwise.
|
||||
func (g *UndirectedMatrix) Weight(xid, yid int64) (w float64, ok bool) {
|
||||
if xid == yid {
|
||||
return g.self, true
|
||||
// Nodes returns all the nodes in the graph.
|
||||
func (g *UndirectedMatrix) Nodes() graph.Nodes {
|
||||
if g.nodes != nil {
|
||||
nodes := make([]graph.Node, len(g.nodes))
|
||||
copy(nodes, g.nodes)
|
||||
return iterator.NewOrderedNodes(nodes)
|
||||
}
|
||||
if g.has(xid) && g.has(yid) {
|
||||
// xid and yid are not greater than maximum int by this point.
|
||||
return g.mat.At(int(xid), int(yid)), true
|
||||
}
|
||||
return g.absent, false
|
||||
}
|
||||
|
||||
// SetEdge sets e, an edge from one node to another with unit weight. If the ends of the edge are
|
||||
// not in g or the edge is a self loop, SetEdge panics.
|
||||
func (g *UndirectedMatrix) SetEdge(e graph.Edge) {
|
||||
g.setWeightedEdge(e, 1)
|
||||
}
|
||||
|
||||
// SetWeightedEdge sets e, an edge from one node to another. If the ends of the edge are not in g
|
||||
// or the edge is a self loop, SetWeightedEdge panics.
|
||||
func (g *UndirectedMatrix) SetWeightedEdge(e graph.WeightedEdge) {
|
||||
g.setWeightedEdge(e, e.Weight())
|
||||
}
|
||||
|
||||
func (g *UndirectedMatrix) setWeightedEdge(e graph.Edge, weight float64) {
|
||||
fid := e.From().ID()
|
||||
tid := e.To().ID()
|
||||
if fid == tid {
|
||||
panic("simple: set illegal edge")
|
||||
}
|
||||
if int64(int(fid)) != fid {
|
||||
panic("simple: unavailable from node ID for dense graph")
|
||||
}
|
||||
if int64(int(tid)) != tid {
|
||||
panic("simple: unavailable to node ID for dense graph")
|
||||
}
|
||||
// fid and tid are not greater than maximum int by this point.
|
||||
g.mat.SetSym(int(fid), int(tid), weight)
|
||||
r := g.mat.Symmetric()
|
||||
// Matrix graphs must have at least one node.
|
||||
return iterator.NewImplicitNodes(0, r, newSimpleNode)
|
||||
}
|
||||
|
||||
// RemoveEdge removes the edge with the given end point IDs from the graph, leaving the terminal
|
||||
@@ -226,28 +179,90 @@ func (g *UndirectedMatrix) RemoveEdge(fid, tid int64) {
|
||||
g.mat.SetSym(int(fid), int(tid), g.absent)
|
||||
}
|
||||
|
||||
// Degree returns the degree of n in g.
|
||||
func (g *UndirectedMatrix) Degree(id int64) int {
|
||||
if !g.has(id) {
|
||||
return 0
|
||||
}
|
||||
var deg int
|
||||
r := g.mat.Symmetric()
|
||||
for i := 0; i < r; i++ {
|
||||
if int64(i) == id {
|
||||
continue
|
||||
}
|
||||
// id is not greater than maximum int by this point.
|
||||
if !isSame(g.mat.At(int(id), i), g.absent) {
|
||||
deg++
|
||||
}
|
||||
}
|
||||
return deg
|
||||
// SetEdge sets e, an edge from one node to another with unit weight. If the ends of the edge are
|
||||
// not in g or the edge is a self loop, SetEdge panics. SetEdge will store the nodes of
|
||||
// e in the graph if it was initialized with NewUndirectedMatrixFrom.
|
||||
func (g *UndirectedMatrix) SetEdge(e graph.Edge) {
|
||||
g.setWeightedEdge(e, 1)
|
||||
}
|
||||
|
||||
// Matrix returns the mat.Matrix representation of the graph.
|
||||
func (g *UndirectedMatrix) Matrix() mat.Matrix {
|
||||
// Prevent alteration of dimensions of the returned matrix.
|
||||
m := *g.mat
|
||||
return &m
|
||||
// SetWeightedEdge sets e, an edge from one node to another. If the ends of the edge are not in g
|
||||
// or the edge is a self loop, SetWeightedEdge panics. SetWeightedEdge will store the nodes of
|
||||
// e in the graph if it was initialized with NewUndirectedMatrixFrom.
|
||||
func (g *UndirectedMatrix) SetWeightedEdge(e graph.WeightedEdge) {
|
||||
g.setWeightedEdge(e, e.Weight())
|
||||
}
|
||||
|
||||
func (g *UndirectedMatrix) setWeightedEdge(e graph.Edge, weight float64) {
|
||||
from := e.From()
|
||||
fid := from.ID()
|
||||
to := e.To()
|
||||
tid := to.ID()
|
||||
if fid == tid {
|
||||
panic("simple: set illegal edge")
|
||||
}
|
||||
if int64(int(fid)) != fid {
|
||||
panic("simple: unavailable from node ID for dense graph")
|
||||
}
|
||||
if int64(int(tid)) != tid {
|
||||
panic("simple: unavailable to node ID for dense graph")
|
||||
}
|
||||
if g.nodes != nil {
|
||||
g.nodes[fid] = from
|
||||
g.nodes[tid] = to
|
||||
}
|
||||
// fid and tid are not greater than maximum int by this point.
|
||||
g.mat.SetSym(int(fid), int(tid), weight)
|
||||
}
|
||||
|
||||
// Weight returns the weight for the edge between x and y if Edge(x, y) returns a non-nil Edge.
|
||||
// If x and y are the same node or there is no joining edge between the two nodes the weight
|
||||
// value returned is either the graph's absent or self value. Weight returns true if an edge
|
||||
// exists between x and y or if x and y have the same ID, false otherwise.
|
||||
func (g *UndirectedMatrix) Weight(xid, yid int64) (w float64, ok bool) {
|
||||
if xid == yid {
|
||||
return g.self, true
|
||||
}
|
||||
if g.HasEdgeBetween(xid, yid) {
|
||||
// xid and yid are not greater than maximum int by this point.
|
||||
return g.mat.At(int(xid), int(yid)), true
|
||||
}
|
||||
return g.absent, false
|
||||
}
|
||||
|
||||
// WeightedEdge returns the weighted edge from u to v if such an edge exists and nil otherwise.
|
||||
// The node v must be directly reachable from u as defined by the From method.
|
||||
func (g *UndirectedMatrix) WeightedEdge(uid, vid int64) graph.WeightedEdge {
|
||||
return g.WeightedEdgeBetween(uid, vid)
|
||||
}
|
||||
|
||||
// WeightedEdgeBetween returns the weighted edge between nodes x and y.
|
||||
func (g *UndirectedMatrix) WeightedEdgeBetween(uid, vid int64) graph.WeightedEdge {
|
||||
if g.HasEdgeBetween(uid, vid) {
|
||||
// uid and vid are not greater than maximum int by this point.
|
||||
return WeightedEdge{F: g.Node(uid), T: g.Node(vid), W: g.mat.At(int(uid), int(vid))}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// WeightedEdges returns all the edges in the graph.
|
||||
func (g *UndirectedMatrix) WeightedEdges() graph.WeightedEdges {
|
||||
var edges []graph.WeightedEdge
|
||||
r, _ := g.mat.Dims()
|
||||
for i := 0; i < r; i++ {
|
||||
for j := i + 1; j < r; j++ {
|
||||
if w := g.mat.At(i, j); !isSame(w, g.absent) {
|
||||
edges = append(edges, WeightedEdge{F: g.Node(int64(i)), T: g.Node(int64(j)), W: w})
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(edges) == 0 {
|
||||
return graph.Empty
|
||||
}
|
||||
return iterator.NewOrderedWeightedEdges(edges)
|
||||
}
|
||||
|
||||
func (g *UndirectedMatrix) has(id int64) bool {
|
||||
r := g.mat.Symmetric()
|
||||
return 0 <= id && id < int64(r)
|
||||
}
|
||||
|
||||
251
vendor/gonum.org/v1/gonum/graph/simple/directed.go
generated
vendored
251
vendor/gonum.org/v1/gonum/graph/simple/directed.go
generated
vendored
@@ -9,6 +9,18 @@ import (
|
||||
|
||||
"gonum.org/v1/gonum/graph"
|
||||
"gonum.org/v1/gonum/graph/internal/uid"
|
||||
"gonum.org/v1/gonum/graph/iterator"
|
||||
)
|
||||
|
||||
var (
|
||||
dg *DirectedGraph
|
||||
|
||||
_ graph.Graph = dg
|
||||
_ graph.Directed = dg
|
||||
_ graph.NodeAdder = dg
|
||||
_ graph.NodeRemover = dg
|
||||
_ graph.EdgeAdder = dg
|
||||
_ graph.EdgeRemover = dg
|
||||
)
|
||||
|
||||
// DirectedGraph implements a generalized directed graph.
|
||||
@@ -31,6 +43,82 @@ func NewDirectedGraph() *DirectedGraph {
|
||||
}
|
||||
}
|
||||
|
||||
// AddNode adds n to the graph. It panics if the added node ID matches an existing node ID.
|
||||
func (g *DirectedGraph) AddNode(n graph.Node) {
|
||||
if _, exists := g.nodes[n.ID()]; exists {
|
||||
panic(fmt.Sprintf("simple: node ID collision: %d", n.ID()))
|
||||
}
|
||||
g.nodes[n.ID()] = n
|
||||
g.from[n.ID()] = make(map[int64]graph.Edge)
|
||||
g.to[n.ID()] = make(map[int64]graph.Edge)
|
||||
g.nodeIDs.Use(n.ID())
|
||||
}
|
||||
|
||||
// Edge returns the edge from u to v if such an edge exists and nil otherwise.
|
||||
// The node v must be directly reachable from u as defined by the From method.
|
||||
func (g *DirectedGraph) Edge(uid, vid int64) graph.Edge {
|
||||
edge, ok := g.from[uid][vid]
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
return edge
|
||||
}
|
||||
|
||||
// Edges returns all the edges in the graph.
|
||||
func (g *DirectedGraph) Edges() graph.Edges {
|
||||
var edges []graph.Edge
|
||||
for _, u := range g.nodes {
|
||||
for _, e := range g.from[u.ID()] {
|
||||
edges = append(edges, e)
|
||||
}
|
||||
}
|
||||
if len(edges) == 0 {
|
||||
return graph.Empty
|
||||
}
|
||||
return iterator.NewOrderedEdges(edges)
|
||||
}
|
||||
|
||||
// From returns all nodes in g that can be reached directly from n.
|
||||
func (g *DirectedGraph) From(id int64) graph.Nodes {
|
||||
if _, ok := g.from[id]; !ok {
|
||||
return graph.Empty
|
||||
}
|
||||
|
||||
from := make([]graph.Node, len(g.from[id]))
|
||||
i := 0
|
||||
for vid := range g.from[id] {
|
||||
from[i] = g.nodes[vid]
|
||||
i++
|
||||
}
|
||||
if len(from) == 0 {
|
||||
return graph.Empty
|
||||
}
|
||||
return iterator.NewOrderedNodes(from)
|
||||
}
|
||||
|
||||
// HasEdgeBetween returns whether an edge exists between nodes x and y without
|
||||
// considering direction.
|
||||
func (g *DirectedGraph) HasEdgeBetween(xid, yid int64) bool {
|
||||
if _, ok := g.from[xid][yid]; ok {
|
||||
return true
|
||||
}
|
||||
_, ok := g.from[yid][xid]
|
||||
return ok
|
||||
}
|
||||
|
||||
// HasEdgeFromTo returns whether an edge exists in the graph from u to v.
|
||||
func (g *DirectedGraph) HasEdgeFromTo(uid, vid int64) bool {
|
||||
if _, ok := g.from[uid][vid]; !ok {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// NewEdge returns a new Edge from the source to the destination node.
|
||||
func (g *DirectedGraph) NewEdge(from, to graph.Node) graph.Edge {
|
||||
return &Edge{F: from, T: to}
|
||||
}
|
||||
|
||||
// NewNode returns a new unique Node to be added to g. The Node's ID does
|
||||
// not become valid in g until the Node is added to g.
|
||||
func (g *DirectedGraph) NewNode() graph.Node {
|
||||
@@ -43,15 +131,38 @@ func (g *DirectedGraph) NewNode() graph.Node {
|
||||
return Node(g.nodeIDs.NewID())
|
||||
}
|
||||
|
||||
// AddNode adds n to the graph. It panics if the added node ID matches an existing node ID.
|
||||
func (g *DirectedGraph) AddNode(n graph.Node) {
|
||||
if _, exists := g.nodes[n.ID()]; exists {
|
||||
panic(fmt.Sprintf("simple: node ID collision: %d", n.ID()))
|
||||
// Node returns the node with the given ID if it exists in the graph,
|
||||
// and nil otherwise.
|
||||
func (g *DirectedGraph) Node(id int64) graph.Node {
|
||||
return g.nodes[id]
|
||||
}
|
||||
|
||||
// Nodes returns all the nodes in the graph.
|
||||
func (g *DirectedGraph) Nodes() graph.Nodes {
|
||||
if len(g.nodes) == 0 {
|
||||
return graph.Empty
|
||||
}
|
||||
g.nodes[n.ID()] = n
|
||||
g.from[n.ID()] = make(map[int64]graph.Edge)
|
||||
g.to[n.ID()] = make(map[int64]graph.Edge)
|
||||
g.nodeIDs.Use(n.ID())
|
||||
nodes := make([]graph.Node, len(g.nodes))
|
||||
i := 0
|
||||
for _, n := range g.nodes {
|
||||
nodes[i] = n
|
||||
i++
|
||||
}
|
||||
return iterator.NewOrderedNodes(nodes)
|
||||
}
|
||||
|
||||
// RemoveEdge removes the edge with the given end point IDs from the graph, leaving the terminal
|
||||
// nodes. If the edge does not exist it is a no-op.
|
||||
func (g *DirectedGraph) RemoveEdge(fid, tid int64) {
|
||||
if _, ok := g.nodes[fid]; !ok {
|
||||
return
|
||||
}
|
||||
if _, ok := g.nodes[tid]; !ok {
|
||||
return
|
||||
}
|
||||
|
||||
delete(g.from[fid], tid)
|
||||
delete(g.to[tid], fid)
|
||||
}
|
||||
|
||||
// RemoveNode removes the node with the given ID from the graph, as well as any edges attached
|
||||
@@ -75,12 +186,8 @@ func (g *DirectedGraph) RemoveNode(id int64) {
|
||||
g.nodeIDs.Release(id)
|
||||
}
|
||||
|
||||
// NewEdge returns a new Edge from the source to the destination node.
|
||||
func (g *DirectedGraph) NewEdge(from, to graph.Node) graph.Edge {
|
||||
return &Edge{F: from, T: to}
|
||||
}
|
||||
|
||||
// SetEdge adds e, an edge from one node to another. If the nodes do not exist, they are added.
|
||||
// SetEdge adds e, an edge from one node to another. If the nodes do not exist, they are added
|
||||
// and are set to the nodes of the edge otherwise.
|
||||
// It will panic if the IDs of the e.From and e.To are equal.
|
||||
func (g *DirectedGraph) SetEdge(e graph.Edge) {
|
||||
var (
|
||||
@@ -94,86 +201,25 @@ func (g *DirectedGraph) SetEdge(e graph.Edge) {
|
||||
panic("simple: adding self edge")
|
||||
}
|
||||
|
||||
if !g.Has(fid) {
|
||||
if _, ok := g.nodes[fid]; !ok {
|
||||
g.AddNode(from)
|
||||
} else {
|
||||
g.nodes[fid] = from
|
||||
}
|
||||
if !g.Has(tid) {
|
||||
if _, ok := g.nodes[tid]; !ok {
|
||||
g.AddNode(to)
|
||||
} else {
|
||||
g.nodes[tid] = to
|
||||
}
|
||||
|
||||
g.from[fid][tid] = e
|
||||
g.to[tid][fid] = e
|
||||
}
|
||||
|
||||
// RemoveEdge removes the edge with the given end point IDs from the graph, leaving the terminal
|
||||
// nodes. If the edge does not exist it is a no-op.
|
||||
func (g *DirectedGraph) RemoveEdge(fid, tid int64) {
|
||||
if _, ok := g.nodes[fid]; !ok {
|
||||
return
|
||||
}
|
||||
if _, ok := g.nodes[tid]; !ok {
|
||||
return
|
||||
}
|
||||
|
||||
delete(g.from[fid], tid)
|
||||
delete(g.to[tid], fid)
|
||||
}
|
||||
|
||||
// Node returns the node in the graph with the given ID.
|
||||
func (g *DirectedGraph) Node(id int64) graph.Node {
|
||||
return g.nodes[id]
|
||||
}
|
||||
|
||||
// Has returns whether the node exists within the graph.
|
||||
func (g *DirectedGraph) Has(id int64) bool {
|
||||
_, ok := g.nodes[id]
|
||||
return ok
|
||||
}
|
||||
|
||||
// Nodes returns all the nodes in the graph.
|
||||
func (g *DirectedGraph) Nodes() []graph.Node {
|
||||
if len(g.nodes) == 0 {
|
||||
return nil
|
||||
}
|
||||
nodes := make([]graph.Node, len(g.nodes))
|
||||
i := 0
|
||||
for _, n := range g.nodes {
|
||||
nodes[i] = n
|
||||
i++
|
||||
}
|
||||
return nodes
|
||||
}
|
||||
|
||||
// Edges returns all the edges in the graph.
|
||||
func (g *DirectedGraph) Edges() []graph.Edge {
|
||||
var edges []graph.Edge
|
||||
for _, u := range g.nodes {
|
||||
for _, e := range g.from[u.ID()] {
|
||||
edges = append(edges, e)
|
||||
}
|
||||
}
|
||||
return edges
|
||||
}
|
||||
|
||||
// From returns all nodes in g that can be reached directly from n.
|
||||
func (g *DirectedGraph) From(id int64) []graph.Node {
|
||||
if _, ok := g.from[id]; !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
from := make([]graph.Node, len(g.from[id]))
|
||||
i := 0
|
||||
for vid := range g.from[id] {
|
||||
from[i] = g.nodes[vid]
|
||||
i++
|
||||
}
|
||||
return from
|
||||
}
|
||||
|
||||
// To returns all nodes in g that can reach directly to n.
|
||||
func (g *DirectedGraph) To(id int64) []graph.Node {
|
||||
func (g *DirectedGraph) To(id int64) graph.Nodes {
|
||||
if _, ok := g.from[id]; !ok {
|
||||
return nil
|
||||
return graph.Empty
|
||||
}
|
||||
|
||||
to := make([]graph.Node, len(g.to[id]))
|
||||
@@ -182,41 +228,8 @@ func (g *DirectedGraph) To(id int64) []graph.Node {
|
||||
to[i] = g.nodes[uid]
|
||||
i++
|
||||
}
|
||||
return to
|
||||
}
|
||||
|
||||
// HasEdgeBetween returns whether an edge exists between nodes x and y without
|
||||
// considering direction.
|
||||
func (g *DirectedGraph) HasEdgeBetween(xid, yid int64) bool {
|
||||
if _, ok := g.from[xid][yid]; ok {
|
||||
return true
|
||||
if len(to) == 0 {
|
||||
return graph.Empty
|
||||
}
|
||||
_, ok := g.from[yid][xid]
|
||||
return ok
|
||||
}
|
||||
|
||||
// Edge returns the edge from u to v if such an edge exists and nil otherwise.
|
||||
// The node v must be directly reachable from u as defined by the From method.
|
||||
func (g *DirectedGraph) Edge(uid, vid int64) graph.Edge {
|
||||
edge, ok := g.from[uid][vid]
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
return edge
|
||||
}
|
||||
|
||||
// HasEdgeFromTo returns whether an edge exists in the graph from u to v.
|
||||
func (g *DirectedGraph) HasEdgeFromTo(uid, vid int64) bool {
|
||||
if _, ok := g.from[uid][vid]; !ok {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Degree returns the in+out degree of n in g.
|
||||
func (g *DirectedGraph) Degree(id int64) int {
|
||||
if _, ok := g.nodes[id]; !ok {
|
||||
return 0
|
||||
}
|
||||
return len(g.from[id]) + len(g.to[id])
|
||||
return iterator.NewOrderedNodes(to)
|
||||
}
|
||||
|
||||
2
vendor/gonum.org/v1/gonum/graph/simple/doc.go
generated
vendored
2
vendor/gonum.org/v1/gonum/graph/simple/doc.go
generated
vendored
@@ -4,4 +4,6 @@
|
||||
|
||||
// Package simple provides a suite of simple graph implementations satisfying
|
||||
// the gonum/graph interfaces.
|
||||
//
|
||||
// All types in simple return the graph.Empty value for empty iterators.
|
||||
package simple // import "gonum.org/v1/gonum/graph/simple"
|
||||
|
||||
21
vendor/gonum.org/v1/gonum/graph/simple/simple.go
generated
vendored
21
vendor/gonum.org/v1/gonum/graph/simple/simple.go
generated
vendored
@@ -18,6 +18,10 @@ func (n Node) ID() int64 {
|
||||
return int64(n)
|
||||
}
|
||||
|
||||
func newSimpleNode(id int) graph.Node {
|
||||
return Node(id)
|
||||
}
|
||||
|
||||
// Edge is a simple graph edge.
|
||||
type Edge struct {
|
||||
F, T graph.Node
|
||||
@@ -29,6 +33,10 @@ func (e Edge) From() graph.Node { return e.F }
|
||||
// To returns the to-node of the edge.
|
||||
func (e Edge) To() graph.Node { return e.T }
|
||||
|
||||
// ReversedLine returns a new Edge with the F and T fields
|
||||
// swapped.
|
||||
func (e Edge) ReversedEdge() graph.Edge { return Edge{F: e.T, T: e.F} }
|
||||
|
||||
// WeightedEdge is a simple weighted graph edge.
|
||||
type WeightedEdge struct {
|
||||
F, T graph.Node
|
||||
@@ -41,6 +49,11 @@ func (e WeightedEdge) From() graph.Node { return e.F }
|
||||
// To returns the to-node of the edge.
|
||||
func (e WeightedEdge) To() graph.Node { return e.T }
|
||||
|
||||
// ReversedLine returns a new Edge with the F and T fields
|
||||
// swapped. The weight of the new Edge is the same as
|
||||
// the weight of the receiver.
|
||||
func (e WeightedEdge) ReversedEdge() graph.Edge { return WeightedEdge{F: e.T, T: e.F, W: e.W} }
|
||||
|
||||
// Weight returns the weight of the edge.
|
||||
func (e WeightedEdge) Weight() float64 { return e.W }
|
||||
|
||||
@@ -49,3 +62,11 @@ func (e WeightedEdge) Weight() float64 { return e.W }
|
||||
func isSame(a, b float64) bool {
|
||||
return a == b || (math.IsNaN(a) && math.IsNaN(b))
|
||||
}
|
||||
|
||||
type edgeSetter interface {
|
||||
SetEdge(e graph.Edge)
|
||||
}
|
||||
|
||||
type weightedEdgeSetter interface {
|
||||
SetWeightedEdge(e graph.WeightedEdge)
|
||||
}
|
||||
|
||||
253
vendor/gonum.org/v1/gonum/graph/simple/undirected.go
generated
vendored
253
vendor/gonum.org/v1/gonum/graph/simple/undirected.go
generated
vendored
@@ -9,6 +9,18 @@ import (
|
||||
|
||||
"gonum.org/v1/gonum/graph"
|
||||
"gonum.org/v1/gonum/graph/internal/uid"
|
||||
"gonum.org/v1/gonum/graph/iterator"
|
||||
)
|
||||
|
||||
var (
|
||||
ug *UndirectedGraph
|
||||
|
||||
_ graph.Graph = ug
|
||||
_ graph.Undirected = ug
|
||||
_ graph.NodeAdder = ug
|
||||
_ graph.NodeRemover = ug
|
||||
_ graph.EdgeAdder = ug
|
||||
_ graph.EdgeRemover = ug
|
||||
)
|
||||
|
||||
// UndirectedGraph implements a generalized undirected graph.
|
||||
@@ -29,6 +41,88 @@ func NewUndirectedGraph() *UndirectedGraph {
|
||||
}
|
||||
}
|
||||
|
||||
// AddNode adds n to the graph. It panics if the added node ID matches an existing node ID.
|
||||
func (g *UndirectedGraph) AddNode(n graph.Node) {
|
||||
if _, exists := g.nodes[n.ID()]; exists {
|
||||
panic(fmt.Sprintf("simple: node ID collision: %d", n.ID()))
|
||||
}
|
||||
g.nodes[n.ID()] = n
|
||||
g.edges[n.ID()] = make(map[int64]graph.Edge)
|
||||
g.nodeIDs.Use(n.ID())
|
||||
}
|
||||
|
||||
// Edge returns the edge from u to v if such an edge exists and nil otherwise.
|
||||
// The node v must be directly reachable from u as defined by the From method.
|
||||
func (g *UndirectedGraph) Edge(uid, vid int64) graph.Edge {
|
||||
return g.EdgeBetween(uid, vid)
|
||||
}
|
||||
|
||||
// EdgeBetween returns the edge between nodes x and y.
|
||||
func (g *UndirectedGraph) EdgeBetween(xid, yid int64) graph.Edge {
|
||||
edge, ok := g.edges[xid][yid]
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
if edge.From().ID() == xid {
|
||||
return edge
|
||||
}
|
||||
return edge.ReversedEdge()
|
||||
}
|
||||
|
||||
// Edges returns all the edges in the graph.
|
||||
func (g *UndirectedGraph) Edges() graph.Edges {
|
||||
if len(g.edges) == 0 {
|
||||
return graph.Empty
|
||||
}
|
||||
var edges []graph.Edge
|
||||
seen := make(map[[2]int64]struct{})
|
||||
for _, u := range g.edges {
|
||||
for _, e := range u {
|
||||
uid := e.From().ID()
|
||||
vid := e.To().ID()
|
||||
if _, ok := seen[[2]int64{uid, vid}]; ok {
|
||||
continue
|
||||
}
|
||||
seen[[2]int64{uid, vid}] = struct{}{}
|
||||
seen[[2]int64{vid, uid}] = struct{}{}
|
||||
edges = append(edges, e)
|
||||
}
|
||||
}
|
||||
if len(edges) == 0 {
|
||||
return graph.Empty
|
||||
}
|
||||
return iterator.NewOrderedEdges(edges)
|
||||
}
|
||||
|
||||
// From returns all nodes in g that can be reached directly from n.
|
||||
func (g *UndirectedGraph) From(id int64) graph.Nodes {
|
||||
if _, ok := g.nodes[id]; !ok {
|
||||
return graph.Empty
|
||||
}
|
||||
|
||||
nodes := make([]graph.Node, len(g.edges[id]))
|
||||
i := 0
|
||||
for from := range g.edges[id] {
|
||||
nodes[i] = g.nodes[from]
|
||||
i++
|
||||
}
|
||||
if len(nodes) == 0 {
|
||||
return graph.Empty
|
||||
}
|
||||
return iterator.NewOrderedNodes(nodes)
|
||||
}
|
||||
|
||||
// HasEdgeBetween returns whether an edge exists between nodes x and y.
|
||||
func (g *UndirectedGraph) HasEdgeBetween(xid, yid int64) bool {
|
||||
_, ok := g.edges[xid][yid]
|
||||
return ok
|
||||
}
|
||||
|
||||
// NewEdge returns a new Edge from the source to the destination node.
|
||||
func (g *UndirectedGraph) NewEdge(from, to graph.Node) graph.Edge {
|
||||
return &Edge{F: from, T: to}
|
||||
}
|
||||
|
||||
// NewNode returns a new unique Node to be added to g. The Node's ID does
|
||||
// not become valid in g until the Node is added to g.
|
||||
func (g *UndirectedGraph) NewNode() graph.Node {
|
||||
@@ -41,14 +135,38 @@ func (g *UndirectedGraph) NewNode() graph.Node {
|
||||
return Node(g.nodeIDs.NewID())
|
||||
}
|
||||
|
||||
// AddNode adds n to the graph. It panics if the added node ID matches an existing node ID.
|
||||
func (g *UndirectedGraph) AddNode(n graph.Node) {
|
||||
if _, exists := g.nodes[n.ID()]; exists {
|
||||
panic(fmt.Sprintf("simple: node ID collision: %d", n.ID()))
|
||||
// Node returns the node with the given ID if it exists in the graph,
|
||||
// and nil otherwise.
|
||||
func (g *UndirectedGraph) Node(id int64) graph.Node {
|
||||
return g.nodes[id]
|
||||
}
|
||||
|
||||
// Nodes returns all the nodes in the graph.
|
||||
func (g *UndirectedGraph) Nodes() graph.Nodes {
|
||||
if len(g.nodes) == 0 {
|
||||
return graph.Empty
|
||||
}
|
||||
g.nodes[n.ID()] = n
|
||||
g.edges[n.ID()] = make(map[int64]graph.Edge)
|
||||
g.nodeIDs.Use(n.ID())
|
||||
nodes := make([]graph.Node, len(g.nodes))
|
||||
i := 0
|
||||
for _, n := range g.nodes {
|
||||
nodes[i] = n
|
||||
i++
|
||||
}
|
||||
return iterator.NewOrderedNodes(nodes)
|
||||
}
|
||||
|
||||
// RemoveEdge removes the edge with the given end IDs from the graph, leaving the terminal nodes.
|
||||
// If the edge does not exist it is a no-op.
|
||||
func (g *UndirectedGraph) RemoveEdge(fid, tid int64) {
|
||||
if _, ok := g.nodes[fid]; !ok {
|
||||
return
|
||||
}
|
||||
if _, ok := g.nodes[tid]; !ok {
|
||||
return
|
||||
}
|
||||
|
||||
delete(g.edges[fid], tid)
|
||||
delete(g.edges[tid], fid)
|
||||
}
|
||||
|
||||
// RemoveNode removes the node with the given ID from the graph, as well as any edges attached
|
||||
@@ -67,12 +185,8 @@ func (g *UndirectedGraph) RemoveNode(id int64) {
|
||||
g.nodeIDs.Release(id)
|
||||
}
|
||||
|
||||
// NewEdge returns a new Edge from the source to the destination node.
|
||||
func (g *UndirectedGraph) NewEdge(from, to graph.Node) graph.Edge {
|
||||
return &Edge{F: from, T: to}
|
||||
}
|
||||
|
||||
// SetEdge adds e, an edge from one node to another. If the nodes do not exist, they are added.
|
||||
// SetEdge adds e, an edge from one node to another. If the nodes do not exist, they are added
|
||||
// and are set to the nodes of the edge otherwise.
|
||||
// It will panic if the IDs of the e.From and e.To are equal.
|
||||
func (g *UndirectedGraph) SetEdge(e graph.Edge) {
|
||||
var (
|
||||
@@ -86,118 +200,17 @@ func (g *UndirectedGraph) SetEdge(e graph.Edge) {
|
||||
panic("simple: adding self edge")
|
||||
}
|
||||
|
||||
if !g.Has(fid) {
|
||||
if _, ok := g.nodes[fid]; !ok {
|
||||
g.AddNode(from)
|
||||
} else {
|
||||
g.nodes[fid] = from
|
||||
}
|
||||
if !g.Has(tid) {
|
||||
if _, ok := g.nodes[tid]; !ok {
|
||||
g.AddNode(to)
|
||||
} else {
|
||||
g.nodes[tid] = to
|
||||
}
|
||||
|
||||
g.edges[fid][tid] = e
|
||||
g.edges[tid][fid] = e
|
||||
}
|
||||
|
||||
// RemoveEdge removes the edge with the given end IDs from the graph, leaving the terminal nodes.
|
||||
// If the edge does not exist it is a no-op.
|
||||
func (g *UndirectedGraph) RemoveEdge(fid, tid int64) {
|
||||
if _, ok := g.nodes[fid]; !ok {
|
||||
return
|
||||
}
|
||||
if _, ok := g.nodes[tid]; !ok {
|
||||
return
|
||||
}
|
||||
|
||||
delete(g.edges[fid], tid)
|
||||
delete(g.edges[tid], fid)
|
||||
}
|
||||
|
||||
// Node returns the node in the graph with the given ID.
|
||||
func (g *UndirectedGraph) Node(id int64) graph.Node {
|
||||
return g.nodes[id]
|
||||
}
|
||||
|
||||
// Has returns whether the node exists within the graph.
|
||||
func (g *UndirectedGraph) Has(id int64) bool {
|
||||
_, ok := g.nodes[id]
|
||||
return ok
|
||||
}
|
||||
|
||||
// Nodes returns all the nodes in the graph.
|
||||
func (g *UndirectedGraph) Nodes() []graph.Node {
|
||||
if len(g.nodes) == 0 {
|
||||
return nil
|
||||
}
|
||||
nodes := make([]graph.Node, len(g.nodes))
|
||||
i := 0
|
||||
for _, n := range g.nodes {
|
||||
nodes[i] = n
|
||||
i++
|
||||
}
|
||||
return nodes
|
||||
}
|
||||
|
||||
// Edges returns all the edges in the graph.
|
||||
func (g *UndirectedGraph) Edges() []graph.Edge {
|
||||
if len(g.edges) == 0 {
|
||||
return nil
|
||||
}
|
||||
var edges []graph.Edge
|
||||
seen := make(map[[2]int64]struct{})
|
||||
for _, u := range g.edges {
|
||||
for _, e := range u {
|
||||
uid := e.From().ID()
|
||||
vid := e.To().ID()
|
||||
if _, ok := seen[[2]int64{uid, vid}]; ok {
|
||||
continue
|
||||
}
|
||||
seen[[2]int64{uid, vid}] = struct{}{}
|
||||
seen[[2]int64{vid, uid}] = struct{}{}
|
||||
edges = append(edges, e)
|
||||
}
|
||||
}
|
||||
return edges
|
||||
}
|
||||
|
||||
// From returns all nodes in g that can be reached directly from n.
|
||||
func (g *UndirectedGraph) From(id int64) []graph.Node {
|
||||
if !g.Has(id) {
|
||||
return nil
|
||||
}
|
||||
|
||||
nodes := make([]graph.Node, len(g.edges[id]))
|
||||
i := 0
|
||||
for from := range g.edges[id] {
|
||||
nodes[i] = g.nodes[from]
|
||||
i++
|
||||
}
|
||||
return nodes
|
||||
}
|
||||
|
||||
// HasEdgeBetween returns whether an edge exists between nodes x and y.
|
||||
func (g *UndirectedGraph) HasEdgeBetween(xid, yid int64) bool {
|
||||
_, ok := g.edges[xid][yid]
|
||||
return ok
|
||||
}
|
||||
|
||||
// Edge returns the edge from u to v if such an edge exists and nil otherwise.
|
||||
// The node v must be directly reachable from u as defined by the From method.
|
||||
func (g *UndirectedGraph) Edge(uid, vid int64) graph.Edge {
|
||||
return g.EdgeBetween(uid, vid)
|
||||
}
|
||||
|
||||
// EdgeBetween returns the edge between nodes x and y.
|
||||
func (g *UndirectedGraph) EdgeBetween(xid, yid int64) graph.Edge {
|
||||
edge, ok := g.edges[xid][yid]
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
return edge
|
||||
}
|
||||
|
||||
// Degree returns the degree of n in g.
|
||||
func (g *UndirectedGraph) Degree(id int64) int {
|
||||
if _, ok := g.nodes[id]; !ok {
|
||||
return 0
|
||||
}
|
||||
return len(g.edges[id])
|
||||
}
|
||||
|
||||
284
vendor/gonum.org/v1/gonum/graph/simple/weighted_directed.go
generated
vendored
284
vendor/gonum.org/v1/gonum/graph/simple/weighted_directed.go
generated
vendored
@@ -9,6 +9,20 @@ import (
|
||||
|
||||
"gonum.org/v1/gonum/graph"
|
||||
"gonum.org/v1/gonum/graph/internal/uid"
|
||||
"gonum.org/v1/gonum/graph/iterator"
|
||||
)
|
||||
|
||||
var (
|
||||
wdg *WeightedDirectedGraph
|
||||
|
||||
_ graph.Graph = wdg
|
||||
_ graph.Weighted = wdg
|
||||
_ graph.Directed = wdg
|
||||
_ graph.WeightedDirected = wdg
|
||||
_ graph.NodeAdder = wdg
|
||||
_ graph.NodeRemover = wdg
|
||||
_ graph.WeightedEdgeAdder = wdg
|
||||
_ graph.EdgeRemover = wdg
|
||||
)
|
||||
|
||||
// WeightedDirectedGraph implements a generalized weighted directed graph.
|
||||
@@ -37,6 +51,73 @@ func NewWeightedDirectedGraph(self, absent float64) *WeightedDirectedGraph {
|
||||
}
|
||||
}
|
||||
|
||||
// AddNode adds n to the graph. It panics if the added node ID matches an existing node ID.
|
||||
func (g *WeightedDirectedGraph) AddNode(n graph.Node) {
|
||||
if _, exists := g.nodes[n.ID()]; exists {
|
||||
panic(fmt.Sprintf("simple: node ID collision: %d", n.ID()))
|
||||
}
|
||||
g.nodes[n.ID()] = n
|
||||
g.from[n.ID()] = make(map[int64]graph.WeightedEdge)
|
||||
g.to[n.ID()] = make(map[int64]graph.WeightedEdge)
|
||||
g.nodeIDs.Use(n.ID())
|
||||
}
|
||||
|
||||
// Edge returns the edge from u to v if such an edge exists and nil otherwise.
|
||||
// The node v must be directly reachable from u as defined by the From method.
|
||||
func (g *WeightedDirectedGraph) Edge(uid, vid int64) graph.Edge {
|
||||
return g.WeightedEdge(uid, vid)
|
||||
}
|
||||
|
||||
// Edges returns all the edges in the graph.
|
||||
func (g *WeightedDirectedGraph) Edges() graph.Edges {
|
||||
var edges []graph.Edge
|
||||
for _, u := range g.nodes {
|
||||
for _, e := range g.from[u.ID()] {
|
||||
edges = append(edges, e)
|
||||
}
|
||||
}
|
||||
if len(edges) == 0 {
|
||||
return graph.Empty
|
||||
}
|
||||
return iterator.NewOrderedEdges(edges)
|
||||
}
|
||||
|
||||
// From returns all nodes in g that can be reached directly from n.
|
||||
func (g *WeightedDirectedGraph) From(id int64) graph.Nodes {
|
||||
if _, ok := g.from[id]; !ok {
|
||||
return graph.Empty
|
||||
}
|
||||
|
||||
from := make([]graph.Node, len(g.from[id]))
|
||||
i := 0
|
||||
for vid := range g.from[id] {
|
||||
from[i] = g.nodes[vid]
|
||||
i++
|
||||
}
|
||||
if len(from) == 0 {
|
||||
return graph.Empty
|
||||
}
|
||||
return iterator.NewOrderedNodes(from)
|
||||
}
|
||||
|
||||
// HasEdgeBetween returns whether an edge exists between nodes x and y without
|
||||
// considering direction.
|
||||
func (g *WeightedDirectedGraph) HasEdgeBetween(xid, yid int64) bool {
|
||||
if _, ok := g.from[xid][yid]; ok {
|
||||
return true
|
||||
}
|
||||
_, ok := g.from[yid][xid]
|
||||
return ok
|
||||
}
|
||||
|
||||
// HasEdgeFromTo returns whether an edge exists in the graph from u to v.
|
||||
func (g *WeightedDirectedGraph) HasEdgeFromTo(uid, vid int64) bool {
|
||||
if _, ok := g.from[uid][vid]; !ok {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// NewNode returns a new unique Node to be added to g. The Node's ID does
|
||||
// not become valid in g until the Node is added to g.
|
||||
func (g *WeightedDirectedGraph) NewNode() graph.Node {
|
||||
@@ -49,15 +130,43 @@ func (g *WeightedDirectedGraph) NewNode() graph.Node {
|
||||
return Node(g.nodeIDs.NewID())
|
||||
}
|
||||
|
||||
// AddNode adds n to the graph. It panics if the added node ID matches an existing node ID.
|
||||
func (g *WeightedDirectedGraph) AddNode(n graph.Node) {
|
||||
if _, exists := g.nodes[n.ID()]; exists {
|
||||
panic(fmt.Sprintf("simple: node ID collision: %d", n.ID()))
|
||||
// NewWeightedEdge returns a new weighted edge from the source to the destination node.
|
||||
func (g *WeightedDirectedGraph) NewWeightedEdge(from, to graph.Node, weight float64) graph.WeightedEdge {
|
||||
return &WeightedEdge{F: from, T: to, W: weight}
|
||||
}
|
||||
|
||||
// Node returns the node with the given ID if it exists in the graph,
|
||||
// and nil otherwise.
|
||||
func (g *WeightedDirectedGraph) Node(id int64) graph.Node {
|
||||
return g.nodes[id]
|
||||
}
|
||||
|
||||
// Nodes returns all the nodes in the graph.
|
||||
func (g *WeightedDirectedGraph) Nodes() graph.Nodes {
|
||||
if len(g.from) == 0 {
|
||||
return graph.Empty
|
||||
}
|
||||
g.nodes[n.ID()] = n
|
||||
g.from[n.ID()] = make(map[int64]graph.WeightedEdge)
|
||||
g.to[n.ID()] = make(map[int64]graph.WeightedEdge)
|
||||
g.nodeIDs.Use(n.ID())
|
||||
nodes := make([]graph.Node, len(g.nodes))
|
||||
i := 0
|
||||
for _, n := range g.nodes {
|
||||
nodes[i] = n
|
||||
i++
|
||||
}
|
||||
return iterator.NewOrderedNodes(nodes)
|
||||
}
|
||||
|
||||
// RemoveEdge removes the edge with the given end point IDs from the graph, leaving the terminal
|
||||
// nodes. If the edge does not exist it is a no-op.
|
||||
func (g *WeightedDirectedGraph) RemoveEdge(fid, tid int64) {
|
||||
if _, ok := g.nodes[fid]; !ok {
|
||||
return
|
||||
}
|
||||
if _, ok := g.nodes[tid]; !ok {
|
||||
return
|
||||
}
|
||||
|
||||
delete(g.from[fid], tid)
|
||||
delete(g.to[tid], fid)
|
||||
}
|
||||
|
||||
// RemoveNode removes the node with the given ID from the graph, as well as any edges attached
|
||||
@@ -81,12 +190,8 @@ func (g *WeightedDirectedGraph) RemoveNode(id int64) {
|
||||
g.nodeIDs.Release(id)
|
||||
}
|
||||
|
||||
// NewWeightedEdge returns a new weighted edge from the source to the destination node.
|
||||
func (g *WeightedDirectedGraph) NewWeightedEdge(from, to graph.Node, weight float64) graph.WeightedEdge {
|
||||
return &WeightedEdge{F: from, T: to, W: weight}
|
||||
}
|
||||
|
||||
// SetWeightedEdge adds a weighted edge from one node to another. If the nodes do not exist, they are added.
|
||||
// SetWeightedEdge adds a weighted edge from one node to another. If the nodes do not exist, they are added
|
||||
// and are set to the nodes of the edge otherwise.
|
||||
// It will panic if the IDs of the e.From and e.To are equal.
|
||||
func (g *WeightedDirectedGraph) SetWeightedEdge(e graph.WeightedEdge) {
|
||||
var (
|
||||
@@ -100,97 +205,25 @@ func (g *WeightedDirectedGraph) SetWeightedEdge(e graph.WeightedEdge) {
|
||||
panic("simple: adding self edge")
|
||||
}
|
||||
|
||||
if !g.Has(fid) {
|
||||
if _, ok := g.nodes[fid]; !ok {
|
||||
g.AddNode(from)
|
||||
} else {
|
||||
g.nodes[fid] = from
|
||||
}
|
||||
if !g.Has(tid) {
|
||||
if _, ok := g.nodes[tid]; !ok {
|
||||
g.AddNode(to)
|
||||
} else {
|
||||
g.nodes[tid] = to
|
||||
}
|
||||
|
||||
g.from[fid][tid] = e
|
||||
g.to[tid][fid] = e
|
||||
}
|
||||
|
||||
// RemoveEdge removes the edge with the given end point IDs from the graph, leaving the terminal
|
||||
// nodes. If the edge does not exist it is a no-op.
|
||||
func (g *WeightedDirectedGraph) RemoveEdge(fid, tid int64) {
|
||||
if _, ok := g.nodes[fid]; !ok {
|
||||
return
|
||||
}
|
||||
if _, ok := g.nodes[tid]; !ok {
|
||||
return
|
||||
}
|
||||
|
||||
delete(g.from[fid], tid)
|
||||
delete(g.to[tid], fid)
|
||||
}
|
||||
|
||||
// Node returns the node in the graph with the given ID.
|
||||
func (g *WeightedDirectedGraph) Node(id int64) graph.Node {
|
||||
return g.nodes[id]
|
||||
}
|
||||
|
||||
// Has returns whether the node exists within the graph.
|
||||
func (g *WeightedDirectedGraph) Has(id int64) bool {
|
||||
_, ok := g.nodes[id]
|
||||
return ok
|
||||
}
|
||||
|
||||
// Nodes returns all the nodes in the graph.
|
||||
func (g *WeightedDirectedGraph) Nodes() []graph.Node {
|
||||
if len(g.from) == 0 {
|
||||
return nil
|
||||
}
|
||||
nodes := make([]graph.Node, len(g.nodes))
|
||||
i := 0
|
||||
for _, n := range g.nodes {
|
||||
nodes[i] = n
|
||||
i++
|
||||
}
|
||||
return nodes
|
||||
}
|
||||
|
||||
// Edges returns all the edges in the graph.
|
||||
func (g *WeightedDirectedGraph) Edges() []graph.Edge {
|
||||
var edges []graph.Edge
|
||||
for _, u := range g.nodes {
|
||||
for _, e := range g.from[u.ID()] {
|
||||
edges = append(edges, e)
|
||||
}
|
||||
}
|
||||
return edges
|
||||
}
|
||||
|
||||
// WeightedEdges returns all the weighted edges in the graph.
|
||||
func (g *WeightedDirectedGraph) WeightedEdges() []graph.WeightedEdge {
|
||||
var edges []graph.WeightedEdge
|
||||
for _, u := range g.nodes {
|
||||
for _, e := range g.from[u.ID()] {
|
||||
edges = append(edges, e)
|
||||
}
|
||||
}
|
||||
return edges
|
||||
}
|
||||
|
||||
// From returns all nodes in g that can be reached directly from n.
|
||||
func (g *WeightedDirectedGraph) From(id int64) []graph.Node {
|
||||
if _, ok := g.from[id]; !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
from := make([]graph.Node, len(g.from[id]))
|
||||
i := 0
|
||||
for vid := range g.from[id] {
|
||||
from[i] = g.nodes[vid]
|
||||
i++
|
||||
}
|
||||
return from
|
||||
}
|
||||
|
||||
// To returns all nodes in g that can reach directly to n.
|
||||
func (g *WeightedDirectedGraph) To(id int64) []graph.Node {
|
||||
func (g *WeightedDirectedGraph) To(id int64) graph.Nodes {
|
||||
if _, ok := g.from[id]; !ok {
|
||||
return nil
|
||||
return graph.Empty
|
||||
}
|
||||
|
||||
to := make([]graph.Node, len(g.to[id]))
|
||||
@@ -199,41 +232,10 @@ func (g *WeightedDirectedGraph) To(id int64) []graph.Node {
|
||||
to[i] = g.nodes[uid]
|
||||
i++
|
||||
}
|
||||
return to
|
||||
}
|
||||
|
||||
// HasEdgeBetween returns whether an edge exists between nodes x and y without
|
||||
// considering direction.
|
||||
func (g *WeightedDirectedGraph) HasEdgeBetween(xid, yid int64) bool {
|
||||
if _, ok := g.from[xid][yid]; ok {
|
||||
return true
|
||||
if len(to) == 0 {
|
||||
return graph.Empty
|
||||
}
|
||||
_, ok := g.from[yid][xid]
|
||||
return ok
|
||||
}
|
||||
|
||||
// Edge returns the edge from u to v if such an edge exists and nil otherwise.
|
||||
// The node v must be directly reachable from u as defined by the From method.
|
||||
func (g *WeightedDirectedGraph) Edge(uid, vid int64) graph.Edge {
|
||||
return g.WeightedEdge(uid, vid)
|
||||
}
|
||||
|
||||
// WeightedEdge returns the weighted edge from u to v if such an edge exists and nil otherwise.
|
||||
// The node v must be directly reachable from u as defined by the From method.
|
||||
func (g *WeightedDirectedGraph) WeightedEdge(uid, vid int64) graph.WeightedEdge {
|
||||
edge, ok := g.from[uid][vid]
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
return edge
|
||||
}
|
||||
|
||||
// HasEdgeFromTo returns whether an edge exists in the graph from u to v.
|
||||
func (g *WeightedDirectedGraph) HasEdgeFromTo(uid, vid int64) bool {
|
||||
if _, ok := g.from[uid][vid]; !ok {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
return iterator.NewOrderedNodes(to)
|
||||
}
|
||||
|
||||
// Weight returns the weight for the edge between x and y if Edge(x, y) returns a non-nil Edge.
|
||||
@@ -252,10 +254,26 @@ func (g *WeightedDirectedGraph) Weight(xid, yid int64) (w float64, ok bool) {
|
||||
return g.absent, false
|
||||
}
|
||||
|
||||
// Degree returns the in+out degree of n in g.
|
||||
func (g *WeightedDirectedGraph) Degree(id int64) int {
|
||||
if _, ok := g.nodes[id]; !ok {
|
||||
return 0
|
||||
// WeightedEdge returns the weighted edge from u to v if such an edge exists and nil otherwise.
|
||||
// The node v must be directly reachable from u as defined by the From method.
|
||||
func (g *WeightedDirectedGraph) WeightedEdge(uid, vid int64) graph.WeightedEdge {
|
||||
edge, ok := g.from[uid][vid]
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
return len(g.from[id]) + len(g.to[id])
|
||||
return edge
|
||||
}
|
||||
|
||||
// WeightedEdges returns all the weighted edges in the graph.
|
||||
func (g *WeightedDirectedGraph) WeightedEdges() graph.WeightedEdges {
|
||||
var edges []graph.WeightedEdge
|
||||
for _, u := range g.nodes {
|
||||
for _, e := range g.from[u.ID()] {
|
||||
edges = append(edges, e)
|
||||
}
|
||||
}
|
||||
if len(edges) == 0 {
|
||||
return graph.Empty
|
||||
}
|
||||
return iterator.NewOrderedWeightedEdges(edges)
|
||||
}
|
||||
|
||||
314
vendor/gonum.org/v1/gonum/graph/simple/weighted_undirected.go
generated
vendored
314
vendor/gonum.org/v1/gonum/graph/simple/weighted_undirected.go
generated
vendored
@@ -9,6 +9,20 @@ import (
|
||||
|
||||
"gonum.org/v1/gonum/graph"
|
||||
"gonum.org/v1/gonum/graph/internal/uid"
|
||||
"gonum.org/v1/gonum/graph/iterator"
|
||||
)
|
||||
|
||||
var (
|
||||
wug *WeightedUndirectedGraph
|
||||
|
||||
_ graph.Graph = wug
|
||||
_ graph.Weighted = wug
|
||||
_ graph.Undirected = wug
|
||||
_ graph.WeightedUndirected = wug
|
||||
_ graph.NodeAdder = wug
|
||||
_ graph.NodeRemover = wug
|
||||
_ graph.WeightedEdgeAdder = wug
|
||||
_ graph.EdgeRemover = wug
|
||||
)
|
||||
|
||||
// WeightedUndirectedGraph implements a generalized weighted undirected graph.
|
||||
@@ -35,6 +49,76 @@ func NewWeightedUndirectedGraph(self, absent float64) *WeightedUndirectedGraph {
|
||||
}
|
||||
}
|
||||
|
||||
// AddNode adds n to the graph. It panics if the added node ID matches an existing node ID.
|
||||
func (g *WeightedUndirectedGraph) AddNode(n graph.Node) {
|
||||
if _, exists := g.nodes[n.ID()]; exists {
|
||||
panic(fmt.Sprintf("simple: node ID collision: %d", n.ID()))
|
||||
}
|
||||
g.nodes[n.ID()] = n
|
||||
g.edges[n.ID()] = make(map[int64]graph.WeightedEdge)
|
||||
g.nodeIDs.Use(n.ID())
|
||||
}
|
||||
|
||||
// Edge returns the edge from u to v if such an edge exists and nil otherwise.
|
||||
// The node v must be directly reachable from u as defined by the From method.
|
||||
func (g *WeightedUndirectedGraph) Edge(uid, vid int64) graph.Edge {
|
||||
return g.WeightedEdgeBetween(uid, vid)
|
||||
}
|
||||
|
||||
// EdgeBetween returns the edge between nodes x and y.
|
||||
func (g *WeightedUndirectedGraph) EdgeBetween(xid, yid int64) graph.Edge {
|
||||
return g.WeightedEdgeBetween(xid, yid)
|
||||
}
|
||||
|
||||
// Edges returns all the edges in the graph.
|
||||
func (g *WeightedUndirectedGraph) Edges() graph.Edges {
|
||||
if len(g.edges) == 0 {
|
||||
return graph.Empty
|
||||
}
|
||||
var edges []graph.Edge
|
||||
seen := make(map[[2]int64]struct{})
|
||||
for _, u := range g.edges {
|
||||
for _, e := range u {
|
||||
uid := e.From().ID()
|
||||
vid := e.To().ID()
|
||||
if _, ok := seen[[2]int64{uid, vid}]; ok {
|
||||
continue
|
||||
}
|
||||
seen[[2]int64{uid, vid}] = struct{}{}
|
||||
seen[[2]int64{vid, uid}] = struct{}{}
|
||||
edges = append(edges, e)
|
||||
}
|
||||
}
|
||||
if len(edges) == 0 {
|
||||
return graph.Empty
|
||||
}
|
||||
return iterator.NewOrderedEdges(edges)
|
||||
}
|
||||
|
||||
// From returns all nodes in g that can be reached directly from n.
|
||||
func (g *WeightedUndirectedGraph) From(id int64) graph.Nodes {
|
||||
if _, ok := g.nodes[id]; !ok {
|
||||
return graph.Empty
|
||||
}
|
||||
|
||||
nodes := make([]graph.Node, len(g.edges[id]))
|
||||
i := 0
|
||||
for from := range g.edges[id] {
|
||||
nodes[i] = g.nodes[from]
|
||||
i++
|
||||
}
|
||||
if len(nodes) == 0 {
|
||||
return graph.Empty
|
||||
}
|
||||
return iterator.NewOrderedNodes(nodes)
|
||||
}
|
||||
|
||||
// HasEdgeBetween returns whether an edge exists between nodes x and y.
|
||||
func (g *WeightedUndirectedGraph) HasEdgeBetween(xid, yid int64) bool {
|
||||
_, ok := g.edges[xid][yid]
|
||||
return ok
|
||||
}
|
||||
|
||||
// NewNode returns a new unique Node to be added to g. The Node's ID does
|
||||
// not become valid in g until the Node is added to g.
|
||||
func (g *WeightedUndirectedGraph) NewNode() graph.Node {
|
||||
@@ -47,14 +131,43 @@ func (g *WeightedUndirectedGraph) NewNode() graph.Node {
|
||||
return Node(g.nodeIDs.NewID())
|
||||
}
|
||||
|
||||
// AddNode adds n to the graph. It panics if the added node ID matches an existing node ID.
|
||||
func (g *WeightedUndirectedGraph) AddNode(n graph.Node) {
|
||||
if _, exists := g.nodes[n.ID()]; exists {
|
||||
panic(fmt.Sprintf("simple: node ID collision: %d", n.ID()))
|
||||
// NewWeightedEdge returns a new weighted edge from the source to the destination node.
|
||||
func (g *WeightedUndirectedGraph) NewWeightedEdge(from, to graph.Node, weight float64) graph.WeightedEdge {
|
||||
return &WeightedEdge{F: from, T: to, W: weight}
|
||||
}
|
||||
|
||||
// Node returns the node with the given ID if it exists in the graph,
|
||||
// and nil otherwise.
|
||||
func (g *WeightedUndirectedGraph) Node(id int64) graph.Node {
|
||||
return g.nodes[id]
|
||||
}
|
||||
|
||||
// Nodes returns all the nodes in the graph.
|
||||
func (g *WeightedUndirectedGraph) Nodes() graph.Nodes {
|
||||
if len(g.nodes) == 0 {
|
||||
return graph.Empty
|
||||
}
|
||||
g.nodes[n.ID()] = n
|
||||
g.edges[n.ID()] = make(map[int64]graph.WeightedEdge)
|
||||
g.nodeIDs.Use(n.ID())
|
||||
nodes := make([]graph.Node, len(g.nodes))
|
||||
i := 0
|
||||
for _, n := range g.nodes {
|
||||
nodes[i] = n
|
||||
i++
|
||||
}
|
||||
return iterator.NewOrderedNodes(nodes)
|
||||
}
|
||||
|
||||
// RemoveEdge removes the edge with the given end point IDs from the graph, leaving the terminal
|
||||
// nodes. If the edge does not exist it is a no-op.
|
||||
func (g *WeightedUndirectedGraph) RemoveEdge(fid, tid int64) {
|
||||
if _, ok := g.nodes[fid]; !ok {
|
||||
return
|
||||
}
|
||||
if _, ok := g.nodes[tid]; !ok {
|
||||
return
|
||||
}
|
||||
|
||||
delete(g.edges[fid], tid)
|
||||
delete(g.edges[tid], fid)
|
||||
}
|
||||
|
||||
// RemoveNode removes the node with the given ID from the graph, as well as any edges attached
|
||||
@@ -73,12 +186,8 @@ func (g *WeightedUndirectedGraph) RemoveNode(id int64) {
|
||||
g.nodeIDs.Release(id)
|
||||
}
|
||||
|
||||
// NewWeightedEdge returns a new weighted edge from the source to the destination node.
|
||||
func (g *WeightedUndirectedGraph) NewWeightedEdge(from, to graph.Node, weight float64) graph.WeightedEdge {
|
||||
return &WeightedEdge{F: from, T: to, W: weight}
|
||||
}
|
||||
|
||||
// SetWeightedEdge adds a weighted edge from one node to another. If the nodes do not exist, they are added.
|
||||
// SetWeightedEdge adds a weighted edge from one node to another. If the nodes do not exist, they are added
|
||||
// and are set to the nodes of the edge otherwise.
|
||||
// It will panic if the IDs of the e.From and e.To are equal.
|
||||
func (g *WeightedUndirectedGraph) SetWeightedEdge(e graph.WeightedEdge) {
|
||||
var (
|
||||
@@ -92,144 +201,21 @@ func (g *WeightedUndirectedGraph) SetWeightedEdge(e graph.WeightedEdge) {
|
||||
panic("simple: adding self edge")
|
||||
}
|
||||
|
||||
if !g.Has(fid) {
|
||||
if _, ok := g.nodes[fid]; !ok {
|
||||
g.AddNode(from)
|
||||
} else {
|
||||
g.nodes[fid] = from
|
||||
}
|
||||
if !g.Has(tid) {
|
||||
if _, ok := g.nodes[tid]; !ok {
|
||||
g.AddNode(to)
|
||||
} else {
|
||||
g.nodes[tid] = to
|
||||
}
|
||||
|
||||
g.edges[fid][tid] = e
|
||||
g.edges[tid][fid] = e
|
||||
}
|
||||
|
||||
// RemoveEdge removes the edge with the given end point IDs from the graph, leaving the terminal
|
||||
// nodes. If the edge does not exist it is a no-op.
|
||||
func (g *WeightedUndirectedGraph) RemoveEdge(fid, tid int64) {
|
||||
if _, ok := g.nodes[fid]; !ok {
|
||||
return
|
||||
}
|
||||
if _, ok := g.nodes[tid]; !ok {
|
||||
return
|
||||
}
|
||||
|
||||
delete(g.edges[fid], tid)
|
||||
delete(g.edges[tid], fid)
|
||||
}
|
||||
|
||||
// Node returns the node in the graph with the given ID.
|
||||
func (g *WeightedUndirectedGraph) Node(id int64) graph.Node {
|
||||
return g.nodes[id]
|
||||
}
|
||||
|
||||
// Has returns whether the node exists within the graph.
|
||||
func (g *WeightedUndirectedGraph) Has(id int64) bool {
|
||||
_, ok := g.nodes[id]
|
||||
return ok
|
||||
}
|
||||
|
||||
// Nodes returns all the nodes in the graph.
|
||||
func (g *WeightedUndirectedGraph) Nodes() []graph.Node {
|
||||
if len(g.nodes) == 0 {
|
||||
return nil
|
||||
}
|
||||
nodes := make([]graph.Node, len(g.nodes))
|
||||
i := 0
|
||||
for _, n := range g.nodes {
|
||||
nodes[i] = n
|
||||
i++
|
||||
}
|
||||
return nodes
|
||||
}
|
||||
|
||||
// Edges returns all the edges in the graph.
|
||||
func (g *WeightedUndirectedGraph) Edges() []graph.Edge {
|
||||
if len(g.edges) == 0 {
|
||||
return nil
|
||||
}
|
||||
var edges []graph.Edge
|
||||
seen := make(map[[2]int64]struct{})
|
||||
for _, u := range g.edges {
|
||||
for _, e := range u {
|
||||
uid := e.From().ID()
|
||||
vid := e.To().ID()
|
||||
if _, ok := seen[[2]int64{uid, vid}]; ok {
|
||||
continue
|
||||
}
|
||||
seen[[2]int64{uid, vid}] = struct{}{}
|
||||
seen[[2]int64{vid, uid}] = struct{}{}
|
||||
edges = append(edges, e)
|
||||
}
|
||||
}
|
||||
return edges
|
||||
}
|
||||
|
||||
// WeightedEdges returns all the weighted edges in the graph.
|
||||
func (g *WeightedUndirectedGraph) WeightedEdges() []graph.WeightedEdge {
|
||||
var edges []graph.WeightedEdge
|
||||
seen := make(map[[2]int64]struct{})
|
||||
for _, u := range g.edges {
|
||||
for _, e := range u {
|
||||
uid := e.From().ID()
|
||||
vid := e.To().ID()
|
||||
if _, ok := seen[[2]int64{uid, vid}]; ok {
|
||||
continue
|
||||
}
|
||||
seen[[2]int64{uid, vid}] = struct{}{}
|
||||
seen[[2]int64{vid, uid}] = struct{}{}
|
||||
edges = append(edges, e)
|
||||
}
|
||||
}
|
||||
return edges
|
||||
}
|
||||
|
||||
// From returns all nodes in g that can be reached directly from n.
|
||||
func (g *WeightedUndirectedGraph) From(id int64) []graph.Node {
|
||||
if !g.Has(id) {
|
||||
return nil
|
||||
}
|
||||
|
||||
nodes := make([]graph.Node, len(g.edges[id]))
|
||||
i := 0
|
||||
for from := range g.edges[id] {
|
||||
nodes[i] = g.nodes[from]
|
||||
i++
|
||||
}
|
||||
return nodes
|
||||
}
|
||||
|
||||
// HasEdgeBetween returns whether an edge exists between nodes x and y.
|
||||
func (g *WeightedUndirectedGraph) HasEdgeBetween(xid, yid int64) bool {
|
||||
_, ok := g.edges[xid][yid]
|
||||
return ok
|
||||
}
|
||||
|
||||
// Edge returns the edge from u to v if such an edge exists and nil otherwise.
|
||||
// The node v must be directly reachable from u as defined by the From method.
|
||||
func (g *WeightedUndirectedGraph) Edge(uid, vid int64) graph.Edge {
|
||||
return g.WeightedEdgeBetween(uid, vid)
|
||||
}
|
||||
|
||||
// WeightedEdge returns the weighted edge from u to v if such an edge exists and nil otherwise.
|
||||
// The node v must be directly reachable from u as defined by the From method.
|
||||
func (g *WeightedUndirectedGraph) WeightedEdge(uid, vid int64) graph.WeightedEdge {
|
||||
return g.WeightedEdgeBetween(uid, vid)
|
||||
}
|
||||
|
||||
// EdgeBetween returns the edge between nodes x and y.
|
||||
func (g *WeightedUndirectedGraph) EdgeBetween(xid, yid int64) graph.Edge {
|
||||
return g.WeightedEdgeBetween(xid, yid)
|
||||
}
|
||||
|
||||
// WeightedEdgeBetween returns the weighted edge between nodes x and y.
|
||||
func (g *WeightedUndirectedGraph) WeightedEdgeBetween(xid, yid int64) graph.WeightedEdge {
|
||||
edge, ok := g.edges[xid][yid]
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
return edge
|
||||
}
|
||||
|
||||
// Weight returns the weight for the edge between x and y if Edge(x, y) returns a non-nil Edge.
|
||||
// If x and y are the same node or there is no joining edge between the two nodes the weight
|
||||
// value returned is either the graph's absent or self value. Weight returns true if an edge
|
||||
@@ -246,10 +232,42 @@ func (g *WeightedUndirectedGraph) Weight(xid, yid int64) (w float64, ok bool) {
|
||||
return g.absent, false
|
||||
}
|
||||
|
||||
// Degree returns the degree of n in g.
|
||||
func (g *WeightedUndirectedGraph) Degree(id int64) int {
|
||||
if _, ok := g.nodes[id]; !ok {
|
||||
return 0
|
||||
}
|
||||
return len(g.edges[id])
|
||||
// WeightedEdge returns the weighted edge from u to v if such an edge exists and nil otherwise.
|
||||
// The node v must be directly reachable from u as defined by the From method.
|
||||
func (g *WeightedUndirectedGraph) WeightedEdge(uid, vid int64) graph.WeightedEdge {
|
||||
return g.WeightedEdgeBetween(uid, vid)
|
||||
}
|
||||
|
||||
// WeightedEdgeBetween returns the weighted edge between nodes x and y.
|
||||
func (g *WeightedUndirectedGraph) WeightedEdgeBetween(xid, yid int64) graph.WeightedEdge {
|
||||
edge, ok := g.edges[xid][yid]
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
if edge.From().ID() == xid {
|
||||
return edge
|
||||
}
|
||||
return edge.ReversedEdge().(graph.WeightedEdge)
|
||||
}
|
||||
|
||||
// WeightedEdges returns all the weighted edges in the graph.
|
||||
func (g *WeightedUndirectedGraph) WeightedEdges() graph.WeightedEdges {
|
||||
var edges []graph.WeightedEdge
|
||||
seen := make(map[[2]int64]struct{})
|
||||
for _, u := range g.edges {
|
||||
for _, e := range u {
|
||||
uid := e.From().ID()
|
||||
vid := e.To().ID()
|
||||
if _, ok := seen[[2]int64{uid, vid}]; ok {
|
||||
continue
|
||||
}
|
||||
seen[[2]int64{uid, vid}] = struct{}{}
|
||||
seen[[2]int64{vid, uid}] = struct{}{}
|
||||
edges = append(edges, e)
|
||||
}
|
||||
}
|
||||
if len(edges) == 0 {
|
||||
return graph.Empty
|
||||
}
|
||||
return iterator.NewOrderedWeightedEdges(edges)
|
||||
}
|
||||
|
||||
1
vendor/gonum.org/v1/gonum/graph/topo/BUILD
generated
vendored
1
vendor/gonum.org/v1/gonum/graph/topo/BUILD
generated
vendored
@@ -20,6 +20,7 @@ go_library(
|
||||
"//vendor/gonum.org/v1/gonum/graph/internal/linear:go_default_library",
|
||||
"//vendor/gonum.org/v1/gonum/graph/internal/ordered:go_default_library",
|
||||
"//vendor/gonum.org/v1/gonum/graph/internal/set:go_default_library",
|
||||
"//vendor/gonum.org/v1/gonum/graph/iterator:go_default_library",
|
||||
"//vendor/gonum.org/v1/gonum/graph/traverse:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
30
vendor/gonum.org/v1/gonum/graph/topo/bron_kerbosch.go
generated
vendored
30
vendor/gonum.org/v1/gonum/graph/topo/bron_kerbosch.go
generated
vendored
@@ -44,7 +44,7 @@ func KCore(k int, g graph.Undirected) []graph.Node {
|
||||
// s, a set of relative offsets into l for each k-core, where k is an index
|
||||
// into s.
|
||||
func degeneracyOrdering(g graph.Undirected) (l []graph.Node, s []int) {
|
||||
nodes := g.Nodes()
|
||||
nodes := graph.NodesOf(g.Nodes())
|
||||
|
||||
// The algorithm used here is essentially as described at
|
||||
// http://en.wikipedia.org/w/index.php?title=Degeneracy_%28graph_theory%29&oldid=640308710
|
||||
@@ -61,7 +61,7 @@ func degeneracyOrdering(g graph.Undirected) (l []graph.Node, s []int) {
|
||||
)
|
||||
for _, n := range nodes {
|
||||
id := n.ID()
|
||||
adj := g.From(id)
|
||||
adj := graph.NodesOf(g.From(id))
|
||||
neighbours[id] = adj
|
||||
dv[id] = len(adj)
|
||||
if len(adj) > maxDegree {
|
||||
@@ -133,26 +133,26 @@ func degeneracyOrdering(g graph.Undirected) (l []graph.Node, s []int) {
|
||||
|
||||
// BronKerbosch returns the set of maximal cliques of the undirected graph g.
|
||||
func BronKerbosch(g graph.Undirected) [][]graph.Node {
|
||||
nodes := g.Nodes()
|
||||
nodes := graph.NodesOf(g.Nodes())
|
||||
|
||||
// The algorithm used here is essentially BronKerbosch3 as described at
|
||||
// http://en.wikipedia.org/w/index.php?title=Bron%E2%80%93Kerbosch_algorithm&oldid=656805858
|
||||
|
||||
p := make(set.Nodes, len(nodes))
|
||||
p := set.NewNodesSize(len(nodes))
|
||||
for _, n := range nodes {
|
||||
p.Add(n)
|
||||
}
|
||||
x := make(set.Nodes)
|
||||
x := set.NewNodes()
|
||||
var bk bronKerbosch
|
||||
order, _ := degeneracyOrdering(g)
|
||||
ordered.Reverse(order)
|
||||
for _, v := range order {
|
||||
neighbours := g.From(v.ID())
|
||||
nv := make(set.Nodes, len(neighbours))
|
||||
neighbours := graph.NodesOf(g.From(v.ID()))
|
||||
nv := set.NewNodesSize(len(neighbours))
|
||||
for _, n := range neighbours {
|
||||
nv.Add(n)
|
||||
}
|
||||
bk.maximalCliquePivot(g, []graph.Node{v}, make(set.Nodes).Intersect(p, nv), make(set.Nodes).Intersect(x, nv))
|
||||
bk.maximalCliquePivot(g, []graph.Node{v}, set.IntersectionOfNodes(p, nv), set.IntersectionOfNodes(x, nv))
|
||||
p.Remove(v)
|
||||
x.Add(v)
|
||||
}
|
||||
@@ -168,7 +168,7 @@ func (bk *bronKerbosch) maximalCliquePivot(g graph.Undirected, r []graph.Node, p
|
||||
}
|
||||
|
||||
neighbours := bk.choosePivotFrom(g, p, x)
|
||||
nu := make(set.Nodes, len(neighbours))
|
||||
nu := set.NewNodesSize(len(neighbours))
|
||||
for _, n := range neighbours {
|
||||
nu.Add(n)
|
||||
}
|
||||
@@ -177,8 +177,8 @@ func (bk *bronKerbosch) maximalCliquePivot(g graph.Undirected, r []graph.Node, p
|
||||
continue
|
||||
}
|
||||
vid := v.ID()
|
||||
neighbours := g.From(vid)
|
||||
nv := make(set.Nodes, len(neighbours))
|
||||
neighbours := graph.NodesOf(g.From(vid))
|
||||
nv := set.NewNodesSize(len(neighbours))
|
||||
for _, n := range neighbours {
|
||||
nv.Add(n)
|
||||
}
|
||||
@@ -195,7 +195,7 @@ func (bk *bronKerbosch) maximalCliquePivot(g graph.Undirected, r []graph.Node, p
|
||||
sr = append(r[:len(r):len(r)], v)
|
||||
}
|
||||
|
||||
bk.maximalCliquePivot(g, sr, make(set.Nodes).Intersect(p, nv), make(set.Nodes).Intersect(x, nv))
|
||||
bk.maximalCliquePivot(g, sr, set.IntersectionOfNodes(p, nv), set.IntersectionOfNodes(x, nv))
|
||||
p.Remove(v)
|
||||
x.Add(v)
|
||||
}
|
||||
@@ -207,10 +207,10 @@ func (*bronKerbosch) choosePivotFrom(g graph.Undirected, p, x set.Nodes) (neighb
|
||||
// compile time option.
|
||||
if !tomitaTanakaTakahashi {
|
||||
for _, n := range p {
|
||||
return g.From(n.ID())
|
||||
return graph.NodesOf(g.From(n.ID()))
|
||||
}
|
||||
for _, n := range x {
|
||||
return g.From(n.ID())
|
||||
return graph.NodesOf(g.From(n.ID()))
|
||||
}
|
||||
panic("bronKerbosch: empty set")
|
||||
}
|
||||
@@ -222,7 +222,7 @@ func (*bronKerbosch) choosePivotFrom(g graph.Undirected, p, x set.Nodes) (neighb
|
||||
maxNeighbors := func(s set.Nodes) {
|
||||
outer:
|
||||
for _, u := range s {
|
||||
nb := g.From(u.ID())
|
||||
nb := graph.NodesOf(g.From(u.ID()))
|
||||
c := len(nb)
|
||||
if c <= max {
|
||||
continue
|
||||
|
||||
9
vendor/gonum.org/v1/gonum/graph/topo/clique_graph.go
generated
vendored
9
vendor/gonum.org/v1/gonum/graph/topo/clique_graph.go
generated
vendored
@@ -34,7 +34,7 @@ func CliqueGraph(dst Builder, g graph.Undirected) {
|
||||
|
||||
cliqueNodes := make(cliqueNodeSets, len(cliques))
|
||||
for id, c := range cliques {
|
||||
s := make(set.Nodes, len(c))
|
||||
s := set.NewNodesSize(len(c))
|
||||
for _, n := range c {
|
||||
s.Add(n)
|
||||
}
|
||||
@@ -58,7 +58,7 @@ func CliqueGraph(dst Builder, g graph.Undirected) {
|
||||
case len(vc.Clique.nodes):
|
||||
edgeNodes = []graph.Node{vc.Clique.nodes[0]}
|
||||
default:
|
||||
for _, n := range make(set.Nodes).Intersect(uc.nodes, vc.nodes) {
|
||||
for _, n := range set.IntersectionOfNodes(uc.nodes, vc.nodes) {
|
||||
edgeNodes = append(edgeNodes, n)
|
||||
}
|
||||
sort.Sort(ordered.ByID(edgeNodes))
|
||||
@@ -101,6 +101,11 @@ func (e CliqueGraphEdge) From() graph.Node { return e.from }
|
||||
// To returns the to node of the edge.
|
||||
func (e CliqueGraphEdge) To() graph.Node { return e.to }
|
||||
|
||||
// ReversedEdge returns a new CliqueGraphEdge with
|
||||
// the edge end points swapped. The nodes of the
|
||||
// new edge are shared with the receiver.
|
||||
func (e CliqueGraphEdge) ReversedEdge() graph.Edge { e.from, e.to = e.to, e.from; return e }
|
||||
|
||||
// Nodes returns the common nodes in the cliques of the underlying graph
|
||||
// corresponding to the from and to nodes in the clique graph.
|
||||
func (e CliqueGraphEdge) Nodes() []graph.Node { return e.nodes }
|
||||
|
||||
20
vendor/gonum.org/v1/gonum/graph/topo/johnson_cycles.go
generated
vendored
20
vendor/gonum.org/v1/gonum/graph/topo/johnson_cycles.go
generated
vendored
@@ -10,6 +10,7 @@ import (
|
||||
"gonum.org/v1/gonum/graph"
|
||||
"gonum.org/v1/gonum/graph/internal/ordered"
|
||||
"gonum.org/v1/gonum/graph/internal/set"
|
||||
"gonum.org/v1/gonum/graph/iterator"
|
||||
)
|
||||
|
||||
// johnson implements Johnson's "Finding all the elementary
|
||||
@@ -132,7 +133,7 @@ type johnsonGraph struct {
|
||||
|
||||
// johnsonGraphFrom returns a deep copy of the graph g.
|
||||
func johnsonGraphFrom(g graph.Directed) johnsonGraph {
|
||||
nodes := g.Nodes()
|
||||
nodes := graph.NodesOf(g.Nodes())
|
||||
sort.Sort(ordered.ByID(nodes))
|
||||
c := johnsonGraph{
|
||||
orig: nodes,
|
||||
@@ -144,7 +145,7 @@ func johnsonGraphFrom(g graph.Directed) johnsonGraph {
|
||||
for i, u := range nodes {
|
||||
uid := u.ID()
|
||||
c.index[uid] = i
|
||||
for _, v := range g.From(uid) {
|
||||
for _, v := range graph.NodesOf(g.From(uid)) {
|
||||
if c.succ[uid] == nil {
|
||||
c.succ[uid] = make(set.Int64s)
|
||||
c.nodes.Add(uid)
|
||||
@@ -239,30 +240,33 @@ func (g johnsonGraph) sccSubGraph(sccs [][]graph.Node, min int) johnsonGraph {
|
||||
}
|
||||
|
||||
// Nodes is required to satisfy Tarjan.
|
||||
func (g johnsonGraph) Nodes() []graph.Node {
|
||||
func (g johnsonGraph) Nodes() graph.Nodes {
|
||||
n := make([]graph.Node, 0, len(g.nodes))
|
||||
for id := range g.nodes {
|
||||
n = append(n, johnsonGraphNode(id))
|
||||
}
|
||||
return n
|
||||
return iterator.NewOrderedNodes(n)
|
||||
}
|
||||
|
||||
// Successors is required to satisfy Tarjan.
|
||||
func (g johnsonGraph) From(id int64) []graph.Node {
|
||||
func (g johnsonGraph) From(id int64) graph.Nodes {
|
||||
adj := g.succ[id]
|
||||
if len(adj) == 0 {
|
||||
return nil
|
||||
return graph.Empty
|
||||
}
|
||||
succ := make([]graph.Node, 0, len(adj))
|
||||
for id := range adj {
|
||||
succ = append(succ, johnsonGraphNode(id))
|
||||
}
|
||||
return succ
|
||||
return iterator.NewOrderedNodes(succ)
|
||||
}
|
||||
|
||||
func (johnsonGraph) Has(int64) bool {
|
||||
panic("topo: unintended use of johnsonGraph")
|
||||
}
|
||||
func (johnsonGraph) Node(int64) graph.Node {
|
||||
panic("topo: unintended use of johnsonGraph")
|
||||
}
|
||||
func (johnsonGraph) HasEdgeBetween(_, _ int64) bool {
|
||||
panic("topo: unintended use of johnsonGraph")
|
||||
}
|
||||
@@ -272,7 +276,7 @@ func (johnsonGraph) Edge(_, _ int64) graph.Edge {
|
||||
func (johnsonGraph) HasEdgeFromTo(_, _ int64) bool {
|
||||
panic("topo: unintended use of johnsonGraph")
|
||||
}
|
||||
func (johnsonGraph) To(int64) []graph.Node {
|
||||
func (johnsonGraph) To(int64) graph.Nodes {
|
||||
panic("topo: unintended use of johnsonGraph")
|
||||
}
|
||||
|
||||
|
||||
6
vendor/gonum.org/v1/gonum/graph/topo/paton_cycles.go
generated
vendored
6
vendor/gonum.org/v1/gonum/graph/topo/paton_cycles.go
generated
vendored
@@ -19,7 +19,9 @@ func UndirectedCyclesIn(g graph.Undirected) [][]graph.Node {
|
||||
var cycles [][]graph.Node
|
||||
done := make(set.Int64s)
|
||||
var tree linear.NodeStack
|
||||
for _, n := range g.Nodes() {
|
||||
nodes := g.Nodes()
|
||||
for nodes.Next() {
|
||||
n := nodes.Node()
|
||||
id := n.ID()
|
||||
if done.Has(id) {
|
||||
continue
|
||||
@@ -35,7 +37,7 @@ func UndirectedCyclesIn(g graph.Undirected) [][]graph.Node {
|
||||
u := tree.Pop()
|
||||
uid := u.ID()
|
||||
adj := from[uid]
|
||||
for _, v := range g.From(uid) {
|
||||
for _, v := range graph.NodesOf(g.From(uid)) {
|
||||
vid := v.ID()
|
||||
switch {
|
||||
case uid == vid:
|
||||
|
||||
8
vendor/gonum.org/v1/gonum/graph/topo/tarjan.go
generated
vendored
8
vendor/gonum.org/v1/gonum/graph/topo/tarjan.go
generated
vendored
@@ -94,16 +94,18 @@ func TarjanSCC(g graph.Directed) [][]graph.Node {
|
||||
}
|
||||
|
||||
func tarjanSCCstabilized(g graph.Directed, order func([]graph.Node)) [][]graph.Node {
|
||||
nodes := g.Nodes()
|
||||
nodes := graph.NodesOf(g.Nodes())
|
||||
var succ func(id int64) []graph.Node
|
||||
if order == nil {
|
||||
succ = g.From
|
||||
succ = func(id int64) []graph.Node {
|
||||
return graph.NodesOf(g.From(id))
|
||||
}
|
||||
} else {
|
||||
order(nodes)
|
||||
ordered.Reverse(nodes)
|
||||
|
||||
succ = func(id int64) []graph.Node {
|
||||
to := g.From(id)
|
||||
to := graph.NodesOf(g.From(id))
|
||||
order(to)
|
||||
ordered.Reverse(to)
|
||||
return to
|
||||
|
||||
2
vendor/gonum.org/v1/gonum/graph/topo/topo.go
generated
vendored
2
vendor/gonum.org/v1/gonum/graph/topo/topo.go
generated
vendored
@@ -18,7 +18,7 @@ func IsPathIn(g graph.Graph, path []graph.Node) bool {
|
||||
case 0:
|
||||
return true
|
||||
case 1:
|
||||
return g.Has(path[0].ID())
|
||||
return g.Node(path[0].ID()) != nil
|
||||
default:
|
||||
var canReach func(uid, vid int64) bool
|
||||
switch g := g.(type) {
|
||||
|
||||
82
vendor/gonum.org/v1/gonum/graph/traverse/traverse.go
generated
vendored
82
vendor/gonum.org/v1/gonum/graph/traverse/traverse.go
generated
vendored
@@ -16,33 +16,45 @@ var _ Graph = graph.Graph(nil)
|
||||
type Graph interface {
|
||||
// From returns all nodes that can be reached directly
|
||||
// from the node with the given ID.
|
||||
From(id int64) []graph.Node
|
||||
From(id int64) graph.Nodes
|
||||
|
||||
// Edge returns the edge from u to v, with IDs uid and vid,
|
||||
// if such an edge exists and nil otherwise. The node v
|
||||
// must be directly reachable from u as defined by the
|
||||
// From method.
|
||||
// must be directly reachable from u as defined by
|
||||
// the From method.
|
||||
Edge(uid, vid int64) graph.Edge
|
||||
}
|
||||
|
||||
// BreadthFirst implements stateful breadth-first graph traversal.
|
||||
type BreadthFirst struct {
|
||||
EdgeFilter func(graph.Edge) bool
|
||||
Visit func(u, v graph.Node)
|
||||
queue linear.NodeQueue
|
||||
visited set.Int64s
|
||||
// Visit is called on all nodes on their first visit.
|
||||
Visit func(graph.Node)
|
||||
|
||||
// Traverse is called on all edges that may be traversed
|
||||
// during the walk. This includes edges that would hop to
|
||||
// an already visited node.
|
||||
//
|
||||
// The value returned by Traverse determines whether
|
||||
// an edge can be traversed during the walk.
|
||||
Traverse func(graph.Edge) bool
|
||||
|
||||
queue linear.NodeQueue
|
||||
visited set.Int64s
|
||||
}
|
||||
|
||||
// Walk performs a breadth-first traversal of the graph g starting from the given node,
|
||||
// depending on the the EdgeFilter field and the until parameter if they are non-nil. The
|
||||
// traversal follows edges for which EdgeFilter(edge) is true and returns the first node
|
||||
// depending on the Traverse field and the until parameter if they are non-nil.
|
||||
// The traversal follows edges for which Traverse(edge) is true and returns the first node
|
||||
// for which until(node, depth) is true. During the traversal, if the Visit field is
|
||||
// non-nil, it is called with the nodes joined by each followed edge.
|
||||
// non-nil, it is called with each node the first time it is visited.
|
||||
func (b *BreadthFirst) Walk(g Graph, from graph.Node, until func(n graph.Node, d int) bool) graph.Node {
|
||||
if b.visited == nil {
|
||||
b.visited = make(set.Int64s)
|
||||
}
|
||||
b.queue.Enqueue(from)
|
||||
if b.Visit != nil && !b.visited.Has(from.ID()) {
|
||||
b.Visit(from)
|
||||
}
|
||||
b.visited.Add(from.ID())
|
||||
|
||||
var (
|
||||
@@ -56,16 +68,18 @@ func (b *BreadthFirst) Walk(g Graph, from graph.Node, until func(n graph.Node, d
|
||||
return t
|
||||
}
|
||||
tid := t.ID()
|
||||
for _, n := range g.From(tid) {
|
||||
to := g.From(tid)
|
||||
for to.Next() {
|
||||
n := to.Node()
|
||||
nid := n.ID()
|
||||
if b.EdgeFilter != nil && !b.EdgeFilter(g.Edge(tid, nid)) {
|
||||
if b.Traverse != nil && !b.Traverse(g.Edge(tid, nid)) {
|
||||
continue
|
||||
}
|
||||
if b.visited.Has(nid) {
|
||||
continue
|
||||
}
|
||||
if b.Visit != nil {
|
||||
b.Visit(t, n)
|
||||
b.Visit(n)
|
||||
}
|
||||
b.visited.Add(nid)
|
||||
children++
|
||||
@@ -87,7 +101,9 @@ func (b *BreadthFirst) Walk(g Graph, from graph.Node, until func(n graph.Node, d
|
||||
// during is called on each node as it is traversed.
|
||||
func (b *BreadthFirst) WalkAll(g graph.Undirected, before, after func(), during func(graph.Node)) {
|
||||
b.Reset()
|
||||
for _, from := range g.Nodes() {
|
||||
nodes := g.Nodes()
|
||||
for nodes.Next() {
|
||||
from := nodes.Node()
|
||||
if b.Visited(from) {
|
||||
continue
|
||||
}
|
||||
@@ -119,22 +135,34 @@ func (b *BreadthFirst) Reset() {
|
||||
|
||||
// DepthFirst implements stateful depth-first graph traversal.
|
||||
type DepthFirst struct {
|
||||
EdgeFilter func(graph.Edge) bool
|
||||
Visit func(u, v graph.Node)
|
||||
stack linear.NodeStack
|
||||
visited set.Int64s
|
||||
// Visit is called on all nodes on their first visit.
|
||||
Visit func(graph.Node)
|
||||
|
||||
// Traverse is called on all edges that may be traversed
|
||||
// during the walk. This includes edges that would hop to
|
||||
// an already visited node.
|
||||
//
|
||||
// The value returned by Traverse determines whether an
|
||||
// edge can be traversed during the walk.
|
||||
Traverse func(graph.Edge) bool
|
||||
|
||||
stack linear.NodeStack
|
||||
visited set.Int64s
|
||||
}
|
||||
|
||||
// Walk performs a depth-first traversal of the graph g starting from the given node,
|
||||
// depending on the the EdgeFilter field and the until parameter if they are non-nil. The
|
||||
// traversal follows edges for which EdgeFilter(edge) is true and returns the first node
|
||||
// depending on the Traverse field and the until parameter if they are non-nil.
|
||||
// The traversal follows edges for which Traverse(edge) is true and returns the first node
|
||||
// for which until(node) is true. During the traversal, if the Visit field is non-nil, it
|
||||
// is called with the nodes joined by each followed edge.
|
||||
// is called with each node the first time it is visited.
|
||||
func (d *DepthFirst) Walk(g Graph, from graph.Node, until func(graph.Node) bool) graph.Node {
|
||||
if d.visited == nil {
|
||||
d.visited = make(set.Int64s)
|
||||
}
|
||||
d.stack.Push(from)
|
||||
if d.Visit != nil && !d.visited.Has(from.ID()) {
|
||||
d.Visit(from)
|
||||
}
|
||||
d.visited.Add(from.ID())
|
||||
|
||||
for d.stack.Len() > 0 {
|
||||
@@ -143,16 +171,18 @@ func (d *DepthFirst) Walk(g Graph, from graph.Node, until func(graph.Node) bool)
|
||||
return t
|
||||
}
|
||||
tid := t.ID()
|
||||
for _, n := range g.From(tid) {
|
||||
to := g.From(tid)
|
||||
for to.Next() {
|
||||
n := to.Node()
|
||||
nid := n.ID()
|
||||
if d.EdgeFilter != nil && !d.EdgeFilter(g.Edge(tid, nid)) {
|
||||
if d.Traverse != nil && !d.Traverse(g.Edge(tid, nid)) {
|
||||
continue
|
||||
}
|
||||
if d.visited.Has(nid) {
|
||||
continue
|
||||
}
|
||||
if d.Visit != nil {
|
||||
d.Visit(t, n)
|
||||
d.Visit(n)
|
||||
}
|
||||
d.visited.Add(nid)
|
||||
d.stack.Push(n)
|
||||
@@ -168,7 +198,9 @@ func (d *DepthFirst) Walk(g Graph, from graph.Node, until func(graph.Node) bool)
|
||||
// during is called on each node as it is traversed.
|
||||
func (d *DepthFirst) WalkAll(g graph.Undirected, before, after func(), during func(graph.Node)) {
|
||||
d.Reset()
|
||||
for _, from := range g.Nodes() {
|
||||
nodes := g.Nodes()
|
||||
for nodes.Next() {
|
||||
from := nodes.Node()
|
||||
if d.Visited(from) {
|
||||
continue
|
||||
}
|
||||
|
||||
120
vendor/gonum.org/v1/gonum/graph/undirect.go
generated
vendored
120
vendor/gonum.org/v1/gonum/graph/undirect.go
generated
vendored
@@ -11,29 +11,16 @@ type Undirect struct {
|
||||
|
||||
var _ Undirected = Undirect{}
|
||||
|
||||
// Has returns whether the node exists within the graph.
|
||||
func (g Undirect) Has(id int64) bool { return g.G.Has(id) }
|
||||
// Node returns the node with the given ID if it exists in the graph,
|
||||
// and nil otherwise.
|
||||
func (g Undirect) Node(id int64) Node { return g.G.Node(id) }
|
||||
|
||||
// Nodes returns all the nodes in the graph.
|
||||
func (g Undirect) Nodes() []Node { return g.G.Nodes() }
|
||||
func (g Undirect) Nodes() Nodes { return g.G.Nodes() }
|
||||
|
||||
// From returns all nodes in g that can be reached directly from u.
|
||||
func (g Undirect) From(uid int64) []Node {
|
||||
var nodes []Node
|
||||
seen := make(map[int64]struct{})
|
||||
for _, n := range g.G.From(uid) {
|
||||
seen[n.ID()] = struct{}{}
|
||||
nodes = append(nodes, n)
|
||||
}
|
||||
for _, n := range g.G.To(uid) {
|
||||
id := n.ID()
|
||||
if _, ok := seen[id]; ok {
|
||||
continue
|
||||
}
|
||||
seen[n.ID()] = struct{}{}
|
||||
nodes = append(nodes, n)
|
||||
}
|
||||
return nodes
|
||||
func (g Undirect) From(uid int64) Nodes {
|
||||
return newNodeFilterIterator(g.G.From(uid), g.G.To(uid))
|
||||
}
|
||||
|
||||
// HasEdgeBetween returns whether an edge exists between nodes x and y.
|
||||
@@ -90,29 +77,16 @@ var (
|
||||
_ WeightedUndirected = UndirectWeighted{}
|
||||
)
|
||||
|
||||
// Has returns whether the node exists within the graph.
|
||||
func (g UndirectWeighted) Has(id int64) bool { return g.G.Has(id) }
|
||||
// Node returns the node with the given ID if it exists in the graph,
|
||||
// and nil otherwise.
|
||||
func (g UndirectWeighted) Node(id int64) Node { return g.G.Node(id) }
|
||||
|
||||
// Nodes returns all the nodes in the graph.
|
||||
func (g UndirectWeighted) Nodes() []Node { return g.G.Nodes() }
|
||||
func (g UndirectWeighted) Nodes() Nodes { return g.G.Nodes() }
|
||||
|
||||
// From returns all nodes in g that can be reached directly from u.
|
||||
func (g UndirectWeighted) From(uid int64) []Node {
|
||||
var nodes []Node
|
||||
seen := make(map[int64]struct{})
|
||||
for _, n := range g.G.From(uid) {
|
||||
seen[n.ID()] = struct{}{}
|
||||
nodes = append(nodes, n)
|
||||
}
|
||||
for _, n := range g.G.To(uid) {
|
||||
id := n.ID()
|
||||
if _, ok := seen[id]; ok {
|
||||
continue
|
||||
}
|
||||
seen[n.ID()] = struct{}{}
|
||||
nodes = append(nodes, n)
|
||||
}
|
||||
return nodes
|
||||
func (g UndirectWeighted) From(uid int64) Nodes {
|
||||
return newNodeFilterIterator(g.G.From(uid), g.G.To(uid))
|
||||
}
|
||||
|
||||
// HasEdgeBetween returns whether an edge exists between nodes x and y.
|
||||
@@ -216,11 +190,81 @@ func (e EdgePair) To() Node {
|
||||
return nil
|
||||
}
|
||||
|
||||
// ReversedEdge returns a new Edge with the end point of the
|
||||
// edges in the pair swapped.
|
||||
func (e EdgePair) ReversedEdge() Edge {
|
||||
if e[0] != nil {
|
||||
e[0] = e[0].ReversedEdge()
|
||||
}
|
||||
if e[1] != nil {
|
||||
e[1] = e[1].ReversedEdge()
|
||||
}
|
||||
return e
|
||||
}
|
||||
|
||||
// WeightedEdgePair is an opposed pair of directed edges.
|
||||
type WeightedEdgePair struct {
|
||||
EdgePair
|
||||
W float64
|
||||
}
|
||||
|
||||
// ReversedEdge returns a new Edge with the end point of the
|
||||
// edges in the pair swapped.
|
||||
func (e WeightedEdgePair) ReversedEdge() Edge {
|
||||
e.EdgePair = e.EdgePair.ReversedEdge().(EdgePair)
|
||||
return e
|
||||
}
|
||||
|
||||
// Weight returns the merged edge weights of the two edges.
|
||||
func (e WeightedEdgePair) Weight() float64 { return e.W }
|
||||
|
||||
// nodeFilterIterator combines two Nodes to produce a single stream of
|
||||
// unique nodes.
|
||||
type nodeFilterIterator struct {
|
||||
a, b Nodes
|
||||
|
||||
// unique indicates the node in b with the key ID is unique.
|
||||
unique map[int64]bool
|
||||
}
|
||||
|
||||
func newNodeFilterIterator(a, b Nodes) *nodeFilterIterator {
|
||||
n := nodeFilterIterator{a: a, b: b, unique: make(map[int64]bool)}
|
||||
for n.b.Next() {
|
||||
n.unique[n.b.Node().ID()] = true
|
||||
}
|
||||
n.b.Reset()
|
||||
for n.a.Next() {
|
||||
n.unique[n.a.Node().ID()] = false
|
||||
}
|
||||
n.a.Reset()
|
||||
return &n
|
||||
}
|
||||
|
||||
func (n *nodeFilterIterator) Len() int {
|
||||
return len(n.unique)
|
||||
}
|
||||
|
||||
func (n *nodeFilterIterator) Next() bool {
|
||||
n.Len()
|
||||
if n.a.Next() {
|
||||
return true
|
||||
}
|
||||
for n.b.Next() {
|
||||
if n.unique[n.b.Node().ID()] {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (n *nodeFilterIterator) Node() Node {
|
||||
if n.a.Len() != 0 {
|
||||
return n.a.Node()
|
||||
}
|
||||
return n.b.Node()
|
||||
}
|
||||
|
||||
func (n *nodeFilterIterator) Reset() {
|
||||
n.a.Reset()
|
||||
n.b.Reset()
|
||||
}
|
||||
|
||||
37
vendor/gonum.org/v1/gonum/internal/asm/c64/BUILD
generated
vendored
Normal file
37
vendor/gonum.org/v1/gonum/internal/asm/c64/BUILD
generated
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"axpyinc_amd64.s",
|
||||
"axpyincto_amd64.s",
|
||||
"axpyunitary_amd64.s",
|
||||
"axpyunitaryto_amd64.s",
|
||||
"conj.go",
|
||||
"doc.go",
|
||||
"dotcinc_amd64.s",
|
||||
"dotcunitary_amd64.s",
|
||||
"dotuinc_amd64.s",
|
||||
"dotuunitary_amd64.s",
|
||||
"scal.go",
|
||||
"stubs_amd64.go",
|
||||
"stubs_noasm.go",
|
||||
],
|
||||
importmap = "k8s.io/kubernetes/vendor/gonum.org/v1/gonum/internal/asm/c64",
|
||||
importpath = "gonum.org/v1/gonum/internal/asm/c64",
|
||||
visibility = ["//vendor/gonum.org/v1/gonum:__subpackages__"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
151
vendor/gonum.org/v1/gonum/internal/asm/c64/axpyinc_amd64.s
generated
vendored
Normal file
151
vendor/gonum.org/v1/gonum/internal/asm/c64/axpyinc_amd64.s
generated
vendored
Normal file
@@ -0,0 +1,151 @@
|
||||
// Copyright ©2016 The Gonum Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//+build !noasm,!appengine,!safe
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
// MOVSHDUP X3, X2
|
||||
#define MOVSHDUP_X3_X2 BYTE $0xF3; BYTE $0x0F; BYTE $0x16; BYTE $0xD3
|
||||
// MOVSLDUP X3, X3
|
||||
#define MOVSLDUP_X3_X3 BYTE $0xF3; BYTE $0x0F; BYTE $0x12; BYTE $0xDB
|
||||
// ADDSUBPS X2, X3
|
||||
#define ADDSUBPS_X2_X3 BYTE $0xF2; BYTE $0x0F; BYTE $0xD0; BYTE $0xDA
|
||||
|
||||
// MOVSHDUP X5, X4
|
||||
#define MOVSHDUP_X5_X4 BYTE $0xF3; BYTE $0x0F; BYTE $0x16; BYTE $0xE5
|
||||
// MOVSLDUP X5, X5
|
||||
#define MOVSLDUP_X5_X5 BYTE $0xF3; BYTE $0x0F; BYTE $0x12; BYTE $0xED
|
||||
// ADDSUBPS X4, X5
|
||||
#define ADDSUBPS_X4_X5 BYTE $0xF2; BYTE $0x0F; BYTE $0xD0; BYTE $0xEC
|
||||
|
||||
// MOVSHDUP X7, X6
|
||||
#define MOVSHDUP_X7_X6 BYTE $0xF3; BYTE $0x0F; BYTE $0x16; BYTE $0xF7
|
||||
// MOVSLDUP X7, X7
|
||||
#define MOVSLDUP_X7_X7 BYTE $0xF3; BYTE $0x0F; BYTE $0x12; BYTE $0xFF
|
||||
// ADDSUBPS X6, X7
|
||||
#define ADDSUBPS_X6_X7 BYTE $0xF2; BYTE $0x0F; BYTE $0xD0; BYTE $0xFE
|
||||
|
||||
// MOVSHDUP X9, X8
|
||||
#define MOVSHDUP_X9_X8 BYTE $0xF3; BYTE $0x45; BYTE $0x0F; BYTE $0x16; BYTE $0xC1
|
||||
// MOVSLDUP X9, X9
|
||||
#define MOVSLDUP_X9_X9 BYTE $0xF3; BYTE $0x45; BYTE $0x0F; BYTE $0x12; BYTE $0xC9
|
||||
// ADDSUBPS X8, X9
|
||||
#define ADDSUBPS_X8_X9 BYTE $0xF2; BYTE $0x45; BYTE $0x0F; BYTE $0xD0; BYTE $0xC8
|
||||
|
||||
// func AxpyInc(alpha complex64, x, y []complex64, n, incX, incY, ix, iy uintptr)
|
||||
TEXT ·AxpyInc(SB), NOSPLIT, $0
|
||||
MOVQ x_base+8(FP), SI // SI = &x
|
||||
MOVQ y_base+32(FP), DI // DI = &y
|
||||
MOVQ n+56(FP), CX // CX = n
|
||||
CMPQ CX, $0 // if n==0 { return }
|
||||
JE axpyi_end
|
||||
MOVQ ix+80(FP), R8 // R8 = ix
|
||||
MOVQ iy+88(FP), R9 // R9 = iy
|
||||
LEAQ (SI)(R8*8), SI // SI = &(x[ix])
|
||||
LEAQ (DI)(R9*8), DI // DI = &(y[iy])
|
||||
MOVQ DI, DX // DX = DI // Read/Write pointers
|
||||
MOVQ incX+64(FP), R8 // R8 = incX
|
||||
SHLQ $3, R8 // R8 *= sizeof(complex64)
|
||||
MOVQ incY+72(FP), R9 // R9 = incY
|
||||
SHLQ $3, R9 // R9 *= sizeof(complex64)
|
||||
MOVSD alpha+0(FP), X0 // X0 = { 0, 0, imag(a), real(a) }
|
||||
MOVAPS X0, X1
|
||||
SHUFPS $0x11, X1, X1 // X1 = { 0, 0, real(a), imag(a) }
|
||||
MOVAPS X0, X10 // Copy X0 and X1 for pipelining
|
||||
MOVAPS X1, X11
|
||||
MOVQ CX, BX
|
||||
ANDQ $3, CX // CX = n % 4
|
||||
SHRQ $2, BX // BX = floor( n / 4 )
|
||||
JZ axpyi_tail // if BX == 0 { goto axpyi_tail }
|
||||
|
||||
axpyi_loop: // do {
|
||||
MOVSD (SI), X3 // X_i = { imag(x[i+1]), real(x[i+1]) }
|
||||
MOVSD (SI)(R8*1), X5
|
||||
LEAQ (SI)(R8*2), SI // SI = &(SI[incX*2])
|
||||
MOVSD (SI), X7
|
||||
MOVSD (SI)(R8*1), X9
|
||||
|
||||
// X_(i-1) = { imag(x[i]), imag(x[i]) }
|
||||
MOVSHDUP_X3_X2
|
||||
MOVSHDUP_X5_X4
|
||||
MOVSHDUP_X7_X6
|
||||
MOVSHDUP_X9_X8
|
||||
|
||||
// X_i = { real(x[i]), real(x[i]) }
|
||||
MOVSLDUP_X3_X3
|
||||
MOVSLDUP_X5_X5
|
||||
MOVSLDUP_X7_X7
|
||||
MOVSLDUP_X9_X9
|
||||
|
||||
// X_(i-1) = { real(a) * imag(x[i]), imag(a) * imag(x[i]) }
|
||||
// X_i = { imag(a) * real(x[i]), real(a) * real(x[i]) }
|
||||
MULPS X1, X2
|
||||
MULPS X0, X3
|
||||
MULPS X11, X4
|
||||
MULPS X10, X5
|
||||
MULPS X1, X6
|
||||
MULPS X0, X7
|
||||
MULPS X11, X8
|
||||
MULPS X10, X9
|
||||
|
||||
// X_i = {
|
||||
// imag(result[i]): imag(a)*real(x[i]) + real(a)*imag(x[i]),
|
||||
// real(result[i]): real(a)*real(x[i]) - imag(a)*imag(x[i]),
|
||||
// }
|
||||
ADDSUBPS_X2_X3
|
||||
ADDSUBPS_X4_X5
|
||||
ADDSUBPS_X6_X7
|
||||
ADDSUBPS_X8_X9
|
||||
|
||||
// X_i = { imag(result[i]) + imag(y[i]), real(result[i]) + real(y[i]) }
|
||||
MOVSD (DX), X2
|
||||
MOVSD (DX)(R9*1), X4
|
||||
LEAQ (DX)(R9*2), DX // DX = &(DX[incY*2])
|
||||
MOVSD (DX), X6
|
||||
MOVSD (DX)(R9*1), X8
|
||||
ADDPS X2, X3
|
||||
ADDPS X4, X5
|
||||
ADDPS X6, X7
|
||||
ADDPS X8, X9
|
||||
|
||||
MOVSD X3, (DI) // y[i] = X_i
|
||||
MOVSD X5, (DI)(R9*1)
|
||||
LEAQ (DI)(R9*2), DI // DI = &(DI[incDst])
|
||||
MOVSD X7, (DI)
|
||||
MOVSD X9, (DI)(R9*1)
|
||||
LEAQ (SI)(R8*2), SI // SI = &(SI[incX*2])
|
||||
LEAQ (DX)(R9*2), DX // DX = &(DX[incY*2])
|
||||
LEAQ (DI)(R9*2), DI // DI = &(DI[incDst])
|
||||
DECQ BX
|
||||
JNZ axpyi_loop // } while --BX > 0
|
||||
CMPQ CX, $0 // if CX == 0 { return }
|
||||
JE axpyi_end
|
||||
|
||||
axpyi_tail: // do {
|
||||
MOVSD (SI), X3 // X_i = { imag(x[i+1]), real(x[i+1]) }
|
||||
MOVSHDUP_X3_X2 // X_(i-1) = { real(x[i]), real(x[i]) }
|
||||
MOVSLDUP_X3_X3 // X_i = { imag(x[i]), imag(x[i]) }
|
||||
|
||||
// X_i = { imag(a) * real(x[i]), real(a) * real(x[i]) }
|
||||
// X_(i-1) = { real(a) * imag(x[i]), imag(a) * imag(x[i]) }
|
||||
MULPS X1, X2
|
||||
MULPS X0, X3
|
||||
|
||||
// X_i = {
|
||||
// imag(result[i]): imag(a)*real(x[i]) + real(a)*imag(x[i]),
|
||||
// real(result[i]): real(a)*real(x[i]) - imag(a)*imag(x[i]),
|
||||
// }
|
||||
ADDSUBPS_X2_X3 // (ai*x1r+ar*x1i, ar*x1r-ai*x1i)
|
||||
|
||||
// X_i = { imag(result[i]) + imag(y[i]), real(result[i]) + real(y[i]) }
|
||||
MOVSD (DI), X4
|
||||
ADDPS X4, X3
|
||||
MOVSD X3, (DI) // y[i] = X_i
|
||||
ADDQ R8, SI // SI += incX
|
||||
ADDQ R9, DI // DI += incY
|
||||
LOOP axpyi_tail // } while --CX > 0
|
||||
|
||||
axpyi_end:
|
||||
RET
|
||||
156
vendor/gonum.org/v1/gonum/internal/asm/c64/axpyincto_amd64.s
generated
vendored
Normal file
156
vendor/gonum.org/v1/gonum/internal/asm/c64/axpyincto_amd64.s
generated
vendored
Normal file
@@ -0,0 +1,156 @@
|
||||
// Copyright ©2016 The Gonum Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//+build !noasm,!appengine,!safe
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
// MOVSHDUP X3, X2
|
||||
#define MOVSHDUP_X3_X2 BYTE $0xF3; BYTE $0x0F; BYTE $0x16; BYTE $0xD3
|
||||
// MOVSLDUP X3, X3
|
||||
#define MOVSLDUP_X3_X3 BYTE $0xF3; BYTE $0x0F; BYTE $0x12; BYTE $0xDB
|
||||
// ADDSUBPS X2, X3
|
||||
#define ADDSUBPS_X2_X3 BYTE $0xF2; BYTE $0x0F; BYTE $0xD0; BYTE $0xDA
|
||||
|
||||
// MOVSHDUP X5, X4
|
||||
#define MOVSHDUP_X5_X4 BYTE $0xF3; BYTE $0x0F; BYTE $0x16; BYTE $0xE5
|
||||
// MOVSLDUP X5, X5
|
||||
#define MOVSLDUP_X5_X5 BYTE $0xF3; BYTE $0x0F; BYTE $0x12; BYTE $0xED
|
||||
// ADDSUBPS X4, X5
|
||||
#define ADDSUBPS_X4_X5 BYTE $0xF2; BYTE $0x0F; BYTE $0xD0; BYTE $0xEC
|
||||
|
||||
// MOVSHDUP X7, X6
|
||||
#define MOVSHDUP_X7_X6 BYTE $0xF3; BYTE $0x0F; BYTE $0x16; BYTE $0xF7
|
||||
// MOVSLDUP X7, X7
|
||||
#define MOVSLDUP_X7_X7 BYTE $0xF3; BYTE $0x0F; BYTE $0x12; BYTE $0xFF
|
||||
// ADDSUBPS X6, X7
|
||||
#define ADDSUBPS_X6_X7 BYTE $0xF2; BYTE $0x0F; BYTE $0xD0; BYTE $0xFE
|
||||
|
||||
// MOVSHDUP X9, X8
|
||||
#define MOVSHDUP_X9_X8 BYTE $0xF3; BYTE $0x45; BYTE $0x0F; BYTE $0x16; BYTE $0xC1
|
||||
// MOVSLDUP X9, X9
|
||||
#define MOVSLDUP_X9_X9 BYTE $0xF3; BYTE $0x45; BYTE $0x0F; BYTE $0x12; BYTE $0xC9
|
||||
// ADDSUBPS X8, X9
|
||||
#define ADDSUBPS_X8_X9 BYTE $0xF2; BYTE $0x45; BYTE $0x0F; BYTE $0xD0; BYTE $0xC8
|
||||
|
||||
// func AxpyIncTo(dst []complex64, incDst, idst uintptr, alpha complex64, x, y []complex64, n, incX, incY, ix, iy uintptr)
|
||||
TEXT ·AxpyIncTo(SB), NOSPLIT, $0
|
||||
MOVQ dst_base+0(FP), DI // DI = &dst
|
||||
MOVQ x_base+48(FP), SI // SI = &x
|
||||
MOVQ y_base+72(FP), DX // DX = &y
|
||||
MOVQ n+96(FP), CX // CX = n
|
||||
CMPQ CX, $0 // if n==0 { return }
|
||||
JE axpyi_end
|
||||
MOVQ ix+120(FP), R8 // Load the first index
|
||||
MOVQ iy+128(FP), R9
|
||||
MOVQ idst+32(FP), R10
|
||||
LEAQ (SI)(R8*8), SI // SI = &(x[ix])
|
||||
LEAQ (DX)(R9*8), DX // DX = &(y[iy])
|
||||
LEAQ (DI)(R10*8), DI // DI = &(dst[idst])
|
||||
MOVQ incX+104(FP), R8 // Incrementors*8 for easy iteration (ADDQ)
|
||||
SHLQ $3, R8
|
||||
MOVQ incY+112(FP), R9
|
||||
SHLQ $3, R9
|
||||
MOVQ incDst+24(FP), R10
|
||||
SHLQ $3, R10
|
||||
MOVSD alpha+40(FP), X0 // X0 = { 0, 0, imag(a), real(a) }
|
||||
MOVAPS X0, X1
|
||||
SHUFPS $0x11, X1, X1 // X1 = { 0, 0, real(a), imag(a) }
|
||||
MOVAPS X0, X10 // Copy X0 and X1 for pipelining
|
||||
MOVAPS X1, X11
|
||||
MOVQ CX, BX
|
||||
ANDQ $3, CX // CX = n % 4
|
||||
SHRQ $2, BX // BX = floor( n / 4 )
|
||||
JZ axpyi_tail // if BX == 0 { goto axpyi_tail }
|
||||
|
||||
axpyi_loop: // do {
|
||||
MOVSD (SI), X3 // X_i = { imag(x[i]), real(x[i]) }
|
||||
MOVSD (SI)(R8*1), X5
|
||||
LEAQ (SI)(R8*2), SI // SI = &(SI[incX*2])
|
||||
MOVSD (SI), X7
|
||||
MOVSD (SI)(R8*1), X9
|
||||
|
||||
// X_(i-1) = { imag(x[i]), imag(x[i]) }
|
||||
MOVSHDUP_X3_X2
|
||||
MOVSHDUP_X5_X4
|
||||
MOVSHDUP_X7_X6
|
||||
MOVSHDUP_X9_X8
|
||||
|
||||
// X_i = { real(x[i]), real(x[i]) }
|
||||
MOVSLDUP_X3_X3
|
||||
MOVSLDUP_X5_X5
|
||||
MOVSLDUP_X7_X7
|
||||
MOVSLDUP_X9_X9
|
||||
|
||||
// X_(i-1) = { real(a) * imag(x[i]), imag(a) * imag(x[i]) }
|
||||
// X_i = { imag(a) * real(x[i]), real(a) * real(x[i]) }
|
||||
MULPS X1, X2
|
||||
MULPS X0, X3
|
||||
MULPS X11, X4
|
||||
MULPS X10, X5
|
||||
MULPS X1, X6
|
||||
MULPS X0, X7
|
||||
MULPS X11, X8
|
||||
MULPS X10, X9
|
||||
|
||||
// X_i = {
|
||||
// imag(result[i]): imag(a)*real(x[i]) + real(a)*imag(x[i]),
|
||||
// real(result[i]): real(a)*real(x[i]) - imag(a)*imag(x[i]),
|
||||
// }
|
||||
ADDSUBPS_X2_X3
|
||||
ADDSUBPS_X4_X5
|
||||
ADDSUBPS_X6_X7
|
||||
ADDSUBPS_X8_X9
|
||||
|
||||
// X_i = { imag(result[i]) + imag(y[i]), real(result[i]) + real(y[i]) }
|
||||
MOVSD (DX), X2
|
||||
MOVSD (DX)(R9*1), X4
|
||||
LEAQ (DX)(R9*2), DX // DX = &(DX[incY*2])
|
||||
MOVSD (DX), X6
|
||||
MOVSD (DX)(R9*1), X8
|
||||
ADDPS X2, X3
|
||||
ADDPS X4, X5
|
||||
ADDPS X6, X7
|
||||
ADDPS X8, X9
|
||||
|
||||
MOVSD X3, (DI) // y[i] = X_i
|
||||
MOVSD X5, (DI)(R10*1)
|
||||
LEAQ (DI)(R10*2), DI // DI = &(DI[incDst])
|
||||
MOVSD X7, (DI)
|
||||
MOVSD X9, (DI)(R10*1)
|
||||
LEAQ (SI)(R8*2), SI // SI = &(SI[incX*2])
|
||||
LEAQ (DX)(R9*2), DX // DX = &(DX[incY*2])
|
||||
LEAQ (DI)(R10*2), DI // DI = &(DI[incDst])
|
||||
DECQ BX
|
||||
JNZ axpyi_loop // } while --BX > 0
|
||||
CMPQ CX, $0 // if CX == 0 { return }
|
||||
JE axpyi_end
|
||||
|
||||
axpyi_tail:
|
||||
MOVSD (SI), X3 // X_i = { imag(x[i]), real(x[i]) }
|
||||
MOVSHDUP_X3_X2 // X_(i-1) = { imag(x[i]), imag(x[i]) }
|
||||
MOVSLDUP_X3_X3 // X_i = { real(x[i]), real(x[i]) }
|
||||
|
||||
// X_i = { imag(a) * real(x[i]), real(a) * real(x[i]) }
|
||||
// X_(i-1) = { real(a) * imag(x[i]), imag(a) * imag(x[i]) }
|
||||
MULPS X1, X2
|
||||
MULPS X0, X3
|
||||
|
||||
// X_i = {
|
||||
// imag(result[i]): imag(a)*real(x[i]) + real(a)*imag(x[i]),
|
||||
// real(result[i]): real(a)*real(x[i]) - imag(a)*imag(x[i]),
|
||||
// }
|
||||
ADDSUBPS_X2_X3
|
||||
|
||||
// X_i = { imag(result[i]) + imag(y[i]), real(result[i]) + real(y[i]) }
|
||||
MOVSD (DX), X4
|
||||
ADDPS X4, X3
|
||||
MOVSD X3, (DI) // y[i] = X_i
|
||||
ADDQ R8, SI // SI += incX
|
||||
ADDQ R9, DX // DX += incY
|
||||
ADDQ R10, DI // DI += incDst
|
||||
LOOP axpyi_tail // } while --CX > 0
|
||||
|
||||
axpyi_end:
|
||||
RET
|
||||
160
vendor/gonum.org/v1/gonum/internal/asm/c64/axpyunitary_amd64.s
generated
vendored
Normal file
160
vendor/gonum.org/v1/gonum/internal/asm/c64/axpyunitary_amd64.s
generated
vendored
Normal file
@@ -0,0 +1,160 @@
|
||||
// Copyright ©2016 The Gonum Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//+build !noasm,!appengine,!safe
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
// MOVSHDUP X3, X2
|
||||
#define MOVSHDUP_X3_X2 BYTE $0xF3; BYTE $0x0F; BYTE $0x16; BYTE $0xD3
|
||||
// MOVSLDUP X3, X3
|
||||
#define MOVSLDUP_X3_X3 BYTE $0xF3; BYTE $0x0F; BYTE $0x12; BYTE $0xDB
|
||||
// ADDSUBPS X2, X3
|
||||
#define ADDSUBPS_X2_X3 BYTE $0xF2; BYTE $0x0F; BYTE $0xD0; BYTE $0xDA
|
||||
|
||||
// MOVSHDUP X5, X4
|
||||
#define MOVSHDUP_X5_X4 BYTE $0xF3; BYTE $0x0F; BYTE $0x16; BYTE $0xE5
|
||||
// MOVSLDUP X5, X5
|
||||
#define MOVSLDUP_X5_X5 BYTE $0xF3; BYTE $0x0F; BYTE $0x12; BYTE $0xED
|
||||
// ADDSUBPS X4, X5
|
||||
#define ADDSUBPS_X4_X5 BYTE $0xF2; BYTE $0x0F; BYTE $0xD0; BYTE $0xEC
|
||||
|
||||
// MOVSHDUP X7, X6
|
||||
#define MOVSHDUP_X7_X6 BYTE $0xF3; BYTE $0x0F; BYTE $0x16; BYTE $0xF7
|
||||
// MOVSLDUP X7, X7
|
||||
#define MOVSLDUP_X7_X7 BYTE $0xF3; BYTE $0x0F; BYTE $0x12; BYTE $0xFF
|
||||
// ADDSUBPS X6, X7
|
||||
#define ADDSUBPS_X6_X7 BYTE $0xF2; BYTE $0x0F; BYTE $0xD0; BYTE $0xFE
|
||||
|
||||
// MOVSHDUP X9, X8
|
||||
#define MOVSHDUP_X9_X8 BYTE $0xF3; BYTE $0x45; BYTE $0x0F; BYTE $0x16; BYTE $0xC1
|
||||
// MOVSLDUP X9, X9
|
||||
#define MOVSLDUP_X9_X9 BYTE $0xF3; BYTE $0x45; BYTE $0x0F; BYTE $0x12; BYTE $0xC9
|
||||
// ADDSUBPS X8, X9
|
||||
#define ADDSUBPS_X8_X9 BYTE $0xF2; BYTE $0x45; BYTE $0x0F; BYTE $0xD0; BYTE $0xC8
|
||||
|
||||
// func AxpyUnitary(alpha complex64, x, y []complex64)
|
||||
TEXT ·AxpyUnitary(SB), NOSPLIT, $0
|
||||
MOVQ x_base+8(FP), SI // SI = &x
|
||||
MOVQ y_base+32(FP), DI // DI = &y
|
||||
MOVQ x_len+16(FP), CX // CX = min( len(x), len(y) )
|
||||
CMPQ y_len+40(FP), CX
|
||||
CMOVQLE y_len+40(FP), CX
|
||||
CMPQ CX, $0 // if CX == 0 { return }
|
||||
JE caxy_end
|
||||
PXOR X0, X0 // Clear work registers and cache-align loop
|
||||
PXOR X1, X1
|
||||
MOVSD alpha+0(FP), X0 // X0 = { 0, 0, imag(a), real(a) }
|
||||
SHUFPD $0, X0, X0 // X0 = { imag(a), real(a), imag(a), real(a) }
|
||||
MOVAPS X0, X1
|
||||
SHUFPS $0x11, X1, X1 // X1 = { real(a), imag(a), real(a), imag(a) }
|
||||
XORQ AX, AX // i = 0
|
||||
MOVQ DI, BX // Align on 16-byte boundary for ADDPS
|
||||
ANDQ $15, BX // BX = &y & 15
|
||||
JZ caxy_no_trim // if BX == 0 { goto caxy_no_trim }
|
||||
|
||||
// Trim first value in unaligned buffer
|
||||
XORPS X2, X2 // Clear work registers and cache-align loop
|
||||
XORPS X3, X3
|
||||
XORPS X4, X4
|
||||
MOVSD (SI)(AX*8), X3 // X3 = { imag(x[i]), real(x[i]) }
|
||||
MOVSHDUP_X3_X2 // X2 = { imag(x[i]), imag(x[i]) }
|
||||
MOVSLDUP_X3_X3 // X3 = { real(x[i]), real(x[i]) }
|
||||
MULPS X1, X2 // X2 = { real(a) * imag(x[i]), imag(a) * imag(x[i]) }
|
||||
MULPS X0, X3 // X3 = { imag(a) * real(x[i]), real(a) * real(x[i]) }
|
||||
|
||||
// X3 = { imag(a)*real(x[i]) + real(a)*imag(x[i]), real(a)*real(x[i]) - imag(a)*imag(x[i]) }
|
||||
ADDSUBPS_X2_X3
|
||||
MOVSD (DI)(AX*8), X4 // X3 += y[i]
|
||||
ADDPS X4, X3
|
||||
MOVSD X3, (DI)(AX*8) // y[i] = X3
|
||||
INCQ AX // i++
|
||||
DECQ CX // --CX
|
||||
JZ caxy_end // if CX == 0 { return }
|
||||
|
||||
caxy_no_trim:
|
||||
MOVAPS X0, X10 // Copy X0 and X1 for pipelineing
|
||||
MOVAPS X1, X11
|
||||
MOVQ CX, BX
|
||||
ANDQ $7, CX // CX = n % 8
|
||||
SHRQ $3, BX // BX = floor( n / 8 )
|
||||
JZ caxy_tail // if BX == 0 { goto caxy_tail }
|
||||
|
||||
caxy_loop: // do {
|
||||
// X_i = { imag(x[i]), real(x[i]), imag(x[i+1]), real(x[i+1]) }
|
||||
MOVUPS (SI)(AX*8), X3
|
||||
MOVUPS 16(SI)(AX*8), X5
|
||||
MOVUPS 32(SI)(AX*8), X7
|
||||
MOVUPS 48(SI)(AX*8), X9
|
||||
|
||||
// X_(i-1) = { imag(x[i]), imag(x[i]), imag(x[i]+1), imag(x[i]+1) }
|
||||
MOVSHDUP_X3_X2
|
||||
MOVSHDUP_X5_X4
|
||||
MOVSHDUP_X7_X6
|
||||
MOVSHDUP_X9_X8
|
||||
|
||||
// X_i = { real(x[i]), real(x[i]), real(x[i+1]), real(x[i+1]) }
|
||||
MOVSLDUP_X3_X3
|
||||
MOVSLDUP_X5_X5
|
||||
MOVSLDUP_X7_X7
|
||||
MOVSLDUP_X9_X9
|
||||
|
||||
// X_i = { imag(a) * real(x[i]), real(a) * real(x[i]),
|
||||
// imag(a) * real(x[i+1]), real(a) * real(x[i+1]) }
|
||||
// X_(i-1) = { real(a) * imag(x[i]), imag(a) * imag(x[i]),
|
||||
// real(a) * imag(x[i+1]), imag(a) * imag(x[i+1]) }
|
||||
MULPS X1, X2
|
||||
MULPS X0, X3
|
||||
MULPS X11, X4
|
||||
MULPS X10, X5
|
||||
MULPS X1, X6
|
||||
MULPS X0, X7
|
||||
MULPS X11, X8
|
||||
MULPS X10, X9
|
||||
|
||||
// X_i = {
|
||||
// imag(result[i]): imag(a)*real(x[i]) + real(a)*imag(x[i]),
|
||||
// real(result[i]): real(a)*real(x[i]) - imag(a)*imag(x[i]),
|
||||
// imag(result[i+1]): imag(a)*real(x[i+1]) + real(a)*imag(x[i+1]),
|
||||
// real(result[i+1]): real(a)*real(x[i+1]) - imag(a)*imag(x[i+1]),
|
||||
// }
|
||||
ADDSUBPS_X2_X3
|
||||
ADDSUBPS_X4_X5
|
||||
ADDSUBPS_X6_X7
|
||||
ADDSUBPS_X8_X9
|
||||
|
||||
// X_i = { imag(result[i]) + imag(y[i]), real(result[i]) + real(y[i]),
|
||||
// imag(result[i+1]) + imag(y[i+1]), real(result[i+1]) + real(y[i+1]) }
|
||||
ADDPS (DI)(AX*8), X3
|
||||
ADDPS 16(DI)(AX*8), X5
|
||||
ADDPS 32(DI)(AX*8), X7
|
||||
ADDPS 48(DI)(AX*8), X9
|
||||
MOVUPS X3, (DI)(AX*8) // y[i:i+1] = X_i
|
||||
MOVUPS X5, 16(DI)(AX*8)
|
||||
MOVUPS X7, 32(DI)(AX*8)
|
||||
MOVUPS X9, 48(DI)(AX*8)
|
||||
ADDQ $8, AX // i += 8
|
||||
DECQ BX // --BX
|
||||
JNZ caxy_loop // } while BX > 0
|
||||
CMPQ CX, $0 // if CX == 0 { return }
|
||||
JE caxy_end
|
||||
|
||||
caxy_tail: // do {
|
||||
MOVSD (SI)(AX*8), X3 // X3 = { imag(x[i]), real(x[i]) }
|
||||
MOVSHDUP_X3_X2 // X2 = { imag(x[i]), imag(x[i]) }
|
||||
MOVSLDUP_X3_X3 // X3 = { real(x[i]), real(x[i]) }
|
||||
MULPS X1, X2 // X2 = { real(a) * imag(x[i]), imag(a) * imag(x[i]) }
|
||||
MULPS X0, X3 // X3 = { imag(a) * real(x[i]), real(a) * real(x[i]) }
|
||||
|
||||
// X3 = { imag(a)*real(x[i]) + real(a)*imag(x[i]),
|
||||
// real(a)*real(x[i]) - imag(a)*imag(x[i]) }
|
||||
ADDSUBPS_X2_X3
|
||||
MOVSD (DI)(AX*8), X4 // X3 += y[i]
|
||||
ADDPS X4, X3
|
||||
MOVSD X3, (DI)(AX*8) // y[i] = X3
|
||||
INCQ AX // ++i
|
||||
LOOP caxy_tail // } while --CX > 0
|
||||
|
||||
caxy_end:
|
||||
RET
|
||||
157
vendor/gonum.org/v1/gonum/internal/asm/c64/axpyunitaryto_amd64.s
generated
vendored
Normal file
157
vendor/gonum.org/v1/gonum/internal/asm/c64/axpyunitaryto_amd64.s
generated
vendored
Normal file
@@ -0,0 +1,157 @@
|
||||
// Copyright ©2016 The Gonum Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//+build !noasm,!appengine,!safe
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
// MOVSHDUP X3, X2
|
||||
#define MOVSHDUP_X3_X2 BYTE $0xF3; BYTE $0x0F; BYTE $0x16; BYTE $0xD3
|
||||
// MOVSLDUP X3, X3
|
||||
#define MOVSLDUP_X3_X3 BYTE $0xF3; BYTE $0x0F; BYTE $0x12; BYTE $0xDB
|
||||
// ADDSUBPS X2, X3
|
||||
#define ADDSUBPS_X2_X3 BYTE $0xF2; BYTE $0x0F; BYTE $0xD0; BYTE $0xDA
|
||||
|
||||
// MOVSHDUP X5, X4
|
||||
#define MOVSHDUP_X5_X4 BYTE $0xF3; BYTE $0x0F; BYTE $0x16; BYTE $0xE5
|
||||
// MOVSLDUP X5, X5
|
||||
#define MOVSLDUP_X5_X5 BYTE $0xF3; BYTE $0x0F; BYTE $0x12; BYTE $0xED
|
||||
// ADDSUBPS X4, X5
|
||||
#define ADDSUBPS_X4_X5 BYTE $0xF2; BYTE $0x0F; BYTE $0xD0; BYTE $0xEC
|
||||
|
||||
// MOVSHDUP X7, X6
|
||||
#define MOVSHDUP_X7_X6 BYTE $0xF3; BYTE $0x0F; BYTE $0x16; BYTE $0xF7
|
||||
// MOVSLDUP X7, X7
|
||||
#define MOVSLDUP_X7_X7 BYTE $0xF3; BYTE $0x0F; BYTE $0x12; BYTE $0xFF
|
||||
// ADDSUBPS X6, X7
|
||||
#define ADDSUBPS_X6_X7 BYTE $0xF2; BYTE $0x0F; BYTE $0xD0; BYTE $0xFE
|
||||
|
||||
// MOVSHDUP X9, X8
|
||||
#define MOVSHDUP_X9_X8 BYTE $0xF3; BYTE $0x45; BYTE $0x0F; BYTE $0x16; BYTE $0xC1
|
||||
// MOVSLDUP X9, X9
|
||||
#define MOVSLDUP_X9_X9 BYTE $0xF3; BYTE $0x45; BYTE $0x0F; BYTE $0x12; BYTE $0xC9
|
||||
// ADDSUBPS X8, X9
|
||||
#define ADDSUBPS_X8_X9 BYTE $0xF2; BYTE $0x45; BYTE $0x0F; BYTE $0xD0; BYTE $0xC8
|
||||
|
||||
// func AxpyUnitaryTo(dst []complex64, alpha complex64, x, y []complex64)
|
||||
TEXT ·AxpyUnitaryTo(SB), NOSPLIT, $0
|
||||
MOVQ dst_base+0(FP), DI // DI = &dst
|
||||
MOVQ x_base+32(FP), SI // SI = &x
|
||||
MOVQ y_base+56(FP), DX // DX = &y
|
||||
MOVQ x_len+40(FP), CX
|
||||
CMPQ y_len+64(FP), CX // CX = min( len(x), len(y), len(dst) )
|
||||
CMOVQLE y_len+64(FP), CX
|
||||
CMPQ dst_len+8(FP), CX
|
||||
CMOVQLE dst_len+8(FP), CX
|
||||
CMPQ CX, $0 // if CX == 0 { return }
|
||||
JE caxy_end
|
||||
MOVSD alpha+24(FP), X0 // X0 = { 0, 0, imag(a), real(a) }
|
||||
SHUFPD $0, X0, X0 // X0 = { imag(a), real(a), imag(a), real(a) }
|
||||
MOVAPS X0, X1
|
||||
SHUFPS $0x11, X1, X1 // X1 = { real(a), imag(a), real(a), imag(a) }
|
||||
XORQ AX, AX // i = 0
|
||||
MOVQ DX, BX // Align on 16-byte boundary for ADDPS
|
||||
ANDQ $15, BX // BX = &y & 15
|
||||
JZ caxy_no_trim // if BX == 0 { goto caxy_no_trim }
|
||||
|
||||
MOVSD (SI)(AX*8), X3 // X3 = { imag(x[i]), real(x[i]) }
|
||||
MOVSHDUP_X3_X2 // X2 = { imag(x[i]), imag(x[i]) }
|
||||
MOVSLDUP_X3_X3 // X3 = { real(x[i]), real(x[i]) }
|
||||
MULPS X1, X2 // X2 = { real(a) * imag(x[i]), imag(a) * imag(x[i]) }
|
||||
MULPS X0, X3 // X3 = { imag(a) * real(x[i]), real(a) * real(x[i]) }
|
||||
|
||||
// X3 = { imag(a)*real(x[i]) + real(a)*imag(x[i]), real(a)*real(x[i]) - imag(a)*imag(x[i]) }
|
||||
ADDSUBPS_X2_X3
|
||||
MOVSD (DX)(AX*8), X4 // X3 += y[i]
|
||||
ADDPS X4, X3
|
||||
MOVSD X3, (DI)(AX*8) // dst[i] = X3
|
||||
INCQ AX // i++
|
||||
DECQ CX // --CX
|
||||
JZ caxy_tail // if BX == 0 { goto caxy_tail }
|
||||
|
||||
caxy_no_trim:
|
||||
MOVAPS X0, X10 // Copy X0 and X1 for pipelineing
|
||||
MOVAPS X1, X11
|
||||
MOVQ CX, BX
|
||||
ANDQ $7, CX // CX = n % 8
|
||||
SHRQ $3, BX // BX = floor( n / 8 )
|
||||
JZ caxy_tail // if BX == 0 { goto caxy_tail }
|
||||
|
||||
caxy_loop:
|
||||
// X_i = { imag(x[i]), real(x[i]), imag(x[i+1]), real(x[i+1]) }
|
||||
MOVUPS (SI)(AX*8), X3
|
||||
MOVUPS 16(SI)(AX*8), X5
|
||||
MOVUPS 32(SI)(AX*8), X7
|
||||
MOVUPS 48(SI)(AX*8), X9
|
||||
|
||||
// X_(i-1) = { imag(x[i]), imag(x[i]), imag(x[i]+1), imag(x[i]+1) }
|
||||
MOVSHDUP_X3_X2
|
||||
MOVSHDUP_X5_X4
|
||||
MOVSHDUP_X7_X6
|
||||
MOVSHDUP_X9_X8
|
||||
|
||||
// X_i = { real(x[i]), real(x[i]), real(x[i+1]), real(x[i+1]) }
|
||||
MOVSLDUP_X3_X3
|
||||
MOVSLDUP_X5_X5
|
||||
MOVSLDUP_X7_X7
|
||||
MOVSLDUP_X9_X9
|
||||
|
||||
// X_i = { imag(a) * real(x[i]), real(a) * real(x[i]),
|
||||
// imag(a) * real(x[i+1]), real(a) * real(x[i+1]) }
|
||||
// X_(i-1) = { real(a) * imag(x[i]), imag(a) * imag(x[i]),
|
||||
// real(a) * imag(x[i+1]), imag(a) * imag(x[i+1]) }
|
||||
MULPS X1, X2
|
||||
MULPS X0, X3
|
||||
MULPS X11, X4
|
||||
MULPS X10, X5
|
||||
MULPS X1, X6
|
||||
MULPS X0, X7
|
||||
MULPS X11, X8
|
||||
MULPS X10, X9
|
||||
|
||||
// X_i = {
|
||||
// imag(result[i]): imag(a)*real(x[i]) + real(a)*imag(x[i]),
|
||||
// real(result[i]): real(a)*real(x[i]) - imag(a)*imag(x[i]),
|
||||
// imag(result[i+1]): imag(a)*real(x[i+1]) + real(a)*imag(x[i+1]),
|
||||
// real(result[i+1]): real(a)*real(x[i+1]) - imag(a)*imag(x[i+1]),
|
||||
// }
|
||||
ADDSUBPS_X2_X3
|
||||
ADDSUBPS_X4_X5
|
||||
ADDSUBPS_X6_X7
|
||||
ADDSUBPS_X8_X9
|
||||
|
||||
// X_i = { imag(result[i]) + imag(y[i]), real(result[i]) + real(y[i]),
|
||||
// imag(result[i+1]) + imag(y[i+1]), real(result[i+1]) + real(y[i+1]) }
|
||||
ADDPS (DX)(AX*8), X3
|
||||
ADDPS 16(DX)(AX*8), X5
|
||||
ADDPS 32(DX)(AX*8), X7
|
||||
ADDPS 48(DX)(AX*8), X9
|
||||
MOVUPS X3, (DI)(AX*8) // y[i:i+1] = X_i
|
||||
MOVUPS X5, 16(DI)(AX*8)
|
||||
MOVUPS X7, 32(DI)(AX*8)
|
||||
MOVUPS X9, 48(DI)(AX*8)
|
||||
ADDQ $8, AX // i += 8
|
||||
DECQ BX // --BX
|
||||
JNZ caxy_loop // } while BX > 0
|
||||
CMPQ CX, $0 // if CX == 0 { return }
|
||||
JE caxy_end
|
||||
|
||||
caxy_tail: // do {
|
||||
MOVSD (SI)(AX*8), X3 // X3 = { imag(x[i]), real(x[i]) }
|
||||
MOVSHDUP_X3_X2 // X2 = { imag(x[i]), imag(x[i]) }
|
||||
MOVSLDUP_X3_X3 // X3 = { real(x[i]), real(x[i]) }
|
||||
MULPS X1, X2 // X2 = { real(a) * imag(x[i]), imag(a) * imag(x[i]) }
|
||||
MULPS X0, X3 // X3 = { imag(a) * real(x[i]), real(a) * real(x[i]) }
|
||||
|
||||
// X3 = { imag(a)*real(x[i]) + real(a)*imag(x[i]),
|
||||
// real(a)*real(x[i]) - imag(a)*imag(x[i]) }
|
||||
ADDSUBPS_X2_X3
|
||||
MOVSD (DX)(AX*8), X4 // X3 += y[i]
|
||||
ADDPS X4, X3
|
||||
MOVSD X3, (DI)(AX*8) // y[i] = X3
|
||||
INCQ AX // ++i
|
||||
LOOP caxy_tail // } while --CX > 0
|
||||
|
||||
caxy_end:
|
||||
RET
|
||||
@@ -2,4 +2,6 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package dot
|
||||
package c64
|
||||
|
||||
func conj(c complex64) complex64 { return complex(real(c), -imag(c)) }
|
||||
6
vendor/gonum.org/v1/gonum/internal/asm/c64/doc.go
generated
vendored
Normal file
6
vendor/gonum.org/v1/gonum/internal/asm/c64/doc.go
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
// Copyright ©2017 The Gonum Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package c64 provides complex64 vector primitives.
|
||||
package c64 // import "gonum.org/v1/gonum/internal/asm/c64"
|
||||
160
vendor/gonum.org/v1/gonum/internal/asm/c64/dotcinc_amd64.s
generated
vendored
Normal file
160
vendor/gonum.org/v1/gonum/internal/asm/c64/dotcinc_amd64.s
generated
vendored
Normal file
@@ -0,0 +1,160 @@
|
||||
// Copyright ©2016 The Gonum Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//+build !noasm,!appengine,!safe
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
#define MOVSHDUP_X3_X2 LONG $0xD3160FF3 // MOVSHDUP X3, X2
|
||||
#define MOVSHDUP_X5_X4 LONG $0xE5160FF3 // MOVSHDUP X5, X4
|
||||
#define MOVSHDUP_X7_X6 LONG $0xF7160FF3 // MOVSHDUP X7, X6
|
||||
#define MOVSHDUP_X9_X8 LONG $0x160F45F3; BYTE $0xC1 // MOVSHDUP X9, X8
|
||||
|
||||
#define MOVSLDUP_X3_X3 LONG $0xDB120FF3 // MOVSLDUP X3, X3
|
||||
#define MOVSLDUP_X5_X5 LONG $0xED120FF3 // MOVSLDUP X5, X5
|
||||
#define MOVSLDUP_X7_X7 LONG $0xFF120FF3 // MOVSLDUP X7, X7
|
||||
#define MOVSLDUP_X9_X9 LONG $0x120F45F3; BYTE $0xC9 // MOVSLDUP X9, X9
|
||||
|
||||
#define ADDSUBPS_X2_X3 LONG $0xDAD00FF2 // ADDSUBPS X2, X3
|
||||
#define ADDSUBPS_X4_X5 LONG $0xECD00FF2 // ADDSUBPS X4, X5
|
||||
#define ADDSUBPS_X6_X7 LONG $0xFED00FF2 // ADDSUBPS X6, X7
|
||||
#define ADDSUBPS_X8_X9 LONG $0xD00F45F2; BYTE $0xC8 // ADDSUBPS X8, X9
|
||||
|
||||
#define X_PTR SI
|
||||
#define Y_PTR DI
|
||||
#define LEN CX
|
||||
#define TAIL BX
|
||||
#define SUM X0
|
||||
#define P_SUM X1
|
||||
#define INC_X R8
|
||||
#define INCx3_X R9
|
||||
#define INC_Y R10
|
||||
#define INCx3_Y R11
|
||||
#define NEG1 X15
|
||||
#define P_NEG1 X14
|
||||
|
||||
// func DotcInc(x, y []complex64, n, incX, incY, ix, iy uintptr) (sum complex64)
|
||||
TEXT ·DotcInc(SB), NOSPLIT, $0
|
||||
MOVQ x_base+0(FP), X_PTR // X_PTR = &x
|
||||
MOVQ y_base+24(FP), Y_PTR // Y_PTR = &y
|
||||
PXOR SUM, SUM // SUM = 0
|
||||
PXOR P_SUM, P_SUM // P_SUM = 0
|
||||
MOVQ n+48(FP), LEN // LEN = n
|
||||
CMPQ LEN, $0 // if LEN == 0 { return }
|
||||
JE dotc_end
|
||||
MOVQ ix+72(FP), INC_X
|
||||
MOVQ iy+80(FP), INC_Y
|
||||
LEAQ (X_PTR)(INC_X*8), X_PTR // X_PTR = &(X_PTR[ix])
|
||||
LEAQ (Y_PTR)(INC_Y*8), Y_PTR // Y_PTR = &(Y_PTR[iy])
|
||||
MOVQ incX+56(FP), INC_X // INC_X = incX * sizeof(complex64)
|
||||
SHLQ $3, INC_X
|
||||
MOVQ incY+64(FP), INC_Y // INC_Y = incY * sizeof(complex64)
|
||||
SHLQ $3, INC_Y
|
||||
MOVSS $(-1.0), NEG1
|
||||
SHUFPS $0, NEG1, NEG1 // { -1, -1, -1, -1 }
|
||||
|
||||
MOVQ LEN, TAIL
|
||||
ANDQ $3, TAIL // TAIL = LEN % 4
|
||||
SHRQ $2, LEN // LEN = floor( LEN / 4 )
|
||||
JZ dotc_tail // if LEN == 0 { goto dotc_tail }
|
||||
|
||||
MOVUPS NEG1, P_NEG1 // Copy NEG1 for pipelining
|
||||
LEAQ (INC_X)(INC_X*2), INCx3_X // INCx3_X = INC_X * 3
|
||||
LEAQ (INC_Y)(INC_Y*2), INCx3_Y // INCx3_Y = INC_Y * 3
|
||||
|
||||
dotc_loop: // do {
|
||||
MOVSD (X_PTR), X3 // X_i = { imag(x[i]), real(x[i]) }
|
||||
MOVSD (X_PTR)(INC_X*1), X5
|
||||
MOVSD (X_PTR)(INC_X*2), X7
|
||||
MOVSD (X_PTR)(INCx3_X*1), X9
|
||||
|
||||
// X_(i-1) = { imag(x[i]), imag(x[i]) }
|
||||
MOVSHDUP_X3_X2
|
||||
MOVSHDUP_X5_X4
|
||||
MOVSHDUP_X7_X6
|
||||
MOVSHDUP_X9_X8
|
||||
|
||||
// X_i = { real(x[i]), real(x[i]) }
|
||||
MOVSLDUP_X3_X3
|
||||
MOVSLDUP_X5_X5
|
||||
MOVSLDUP_X7_X7
|
||||
MOVSLDUP_X9_X9
|
||||
|
||||
// X_(i-1) = { -imag(x[i]), -imag(x[i]) }
|
||||
MULPS NEG1, X2
|
||||
MULPS P_NEG1, X4
|
||||
MULPS NEG1, X6
|
||||
MULPS P_NEG1, X8
|
||||
|
||||
// X_j = { imag(y[i]), real(y[i]) }
|
||||
MOVSD (Y_PTR), X10
|
||||
MOVSD (Y_PTR)(INC_Y*1), X11
|
||||
MOVSD (Y_PTR)(INC_Y*2), X12
|
||||
MOVSD (Y_PTR)(INCx3_Y*1), X13
|
||||
|
||||
// X_i = { imag(y[i]) * real(x[i]), real(y[i]) * real(x[i]) }
|
||||
MULPS X10, X3
|
||||
MULPS X11, X5
|
||||
MULPS X12, X7
|
||||
MULPS X13, X9
|
||||
|
||||
// X_j = { real(y[i]), imag(y[i]) }
|
||||
SHUFPS $0xB1, X10, X10
|
||||
SHUFPS $0xB1, X11, X11
|
||||
SHUFPS $0xB1, X12, X12
|
||||
SHUFPS $0xB1, X13, X13
|
||||
|
||||
// X_(i-1) = { real(y[i]) * imag(x[i]), imag(y[i]) * imag(x[i]) }
|
||||
MULPS X10, X2
|
||||
MULPS X11, X4
|
||||
MULPS X12, X6
|
||||
MULPS X13, X8
|
||||
|
||||
// X_i = {
|
||||
// imag(result[i]): imag(y[i]) * real(x[i]) + real(y[i]) * imag(x[i]),
|
||||
// real(result[i]): real(y[i]) * real(x[i]) - imag(y[i]) * imag(x[i]) }
|
||||
ADDSUBPS_X2_X3
|
||||
ADDSUBPS_X4_X5
|
||||
ADDSUBPS_X6_X7
|
||||
ADDSUBPS_X8_X9
|
||||
|
||||
// SUM += X_i
|
||||
ADDPS X3, SUM
|
||||
ADDPS X5, P_SUM
|
||||
ADDPS X7, SUM
|
||||
ADDPS X9, P_SUM
|
||||
|
||||
LEAQ (X_PTR)(INC_X*4), X_PTR // X_PTR = &(X_PTR[INC_X*4])
|
||||
LEAQ (Y_PTR)(INC_Y*4), Y_PTR // Y_PTR = &(Y_PTR[INC_Y*4])
|
||||
|
||||
DECQ LEN
|
||||
JNZ dotc_loop // } while --LEN > 0
|
||||
|
||||
ADDPS P_SUM, SUM // SUM = { P_SUM + SUM }
|
||||
CMPQ TAIL, $0 // if TAIL == 0 { return }
|
||||
JE dotc_end
|
||||
|
||||
dotc_tail: // do {
|
||||
MOVSD (X_PTR), X3 // X_i = { imag(x[i]), real(x[i]) }
|
||||
MOVSHDUP_X3_X2 // X_(i-1) = { imag(x[i]), imag(x[i]) }
|
||||
MOVSLDUP_X3_X3 // X_i = { real(x[i]), real(x[i]) }
|
||||
MULPS NEG1, X2 // X_(i-1) = { -imag(x[i]), imag(x[i]) }
|
||||
MOVUPS (Y_PTR), X10 // X_j = { imag(y[i]), real(y[i]) }
|
||||
MULPS X10, X3 // X_i = { imag(y[i]) * real(x[i]), real(y[i]) * real(x[i]) }
|
||||
SHUFPS $0x1, X10, X10 // X_j = { real(y[i]), imag(y[i]) }
|
||||
MULPS X10, X2 // X_(i-1) = { real(y[i]) * imag(x[i]), imag(y[i]) * imag(x[i]) }
|
||||
|
||||
// X_i = {
|
||||
// imag(result[i]): imag(y[i])*real(x[i]) + real(y[i])*imag(x[i]),
|
||||
// real(result[i]): real(y[i])*real(x[i]) - imag(y[i])*imag(x[i]) }
|
||||
ADDSUBPS_X2_X3
|
||||
ADDPS X3, SUM // SUM += X_i
|
||||
ADDQ INC_X, X_PTR // X_PTR += INC_X
|
||||
ADDQ INC_Y, Y_PTR // Y_PTR += INC_Y
|
||||
DECQ TAIL
|
||||
JNZ dotc_tail // } while --TAIL > 0
|
||||
|
||||
dotc_end:
|
||||
MOVSD SUM, sum+88(FP) // return SUM
|
||||
RET
|
||||
208
vendor/gonum.org/v1/gonum/internal/asm/c64/dotcunitary_amd64.s
generated
vendored
Normal file
208
vendor/gonum.org/v1/gonum/internal/asm/c64/dotcunitary_amd64.s
generated
vendored
Normal file
@@ -0,0 +1,208 @@
|
||||
// Copyright ©2017 The Gonum Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//+build !noasm,!appengine,!safe
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
#define MOVSLDUP_XPTR_IDX_8__X3 LONG $0x1C120FF3; BYTE $0xC6 // MOVSLDUP (SI)(AX*8), X3
|
||||
#define MOVSLDUP_16_XPTR_IDX_8__X5 LONG $0x6C120FF3; WORD $0x10C6 // MOVSLDUP 16(SI)(AX*8), X5
|
||||
#define MOVSLDUP_32_XPTR_IDX_8__X7 LONG $0x7C120FF3; WORD $0x20C6 // MOVSLDUP 32(SI)(AX*8), X7
|
||||
#define MOVSLDUP_48_XPTR_IDX_8__X9 LONG $0x120F44F3; WORD $0xC64C; BYTE $0x30 // MOVSLDUP 48(SI)(AX*8), X9
|
||||
|
||||
#define MOVSHDUP_XPTR_IDX_8__X2 LONG $0x14160FF3; BYTE $0xC6 // MOVSHDUP (SI)(AX*8), X2
|
||||
#define MOVSHDUP_16_XPTR_IDX_8__X4 LONG $0x64160FF3; WORD $0x10C6 // MOVSHDUP 16(SI)(AX*8), X4
|
||||
#define MOVSHDUP_32_XPTR_IDX_8__X6 LONG $0x74160FF3; WORD $0x20C6 // MOVSHDUP 32(SI)(AX*8), X6
|
||||
#define MOVSHDUP_48_XPTR_IDX_8__X8 LONG $0x160F44F3; WORD $0xC644; BYTE $0x30 // MOVSHDUP 48(SI)(AX*8), X8
|
||||
|
||||
#define MOVSHDUP_X3_X2 LONG $0xD3160FF3 // MOVSHDUP X3, X2
|
||||
#define MOVSLDUP_X3_X3 LONG $0xDB120FF3 // MOVSLDUP X3, X3
|
||||
|
||||
#define ADDSUBPS_X2_X3 LONG $0xDAD00FF2 // ADDSUBPS X2, X3
|
||||
#define ADDSUBPS_X4_X5 LONG $0xECD00FF2 // ADDSUBPS X4, X5
|
||||
#define ADDSUBPS_X6_X7 LONG $0xFED00FF2 // ADDSUBPS X6, X7
|
||||
#define ADDSUBPS_X8_X9 LONG $0xD00F45F2; BYTE $0xC8 // ADDSUBPS X8, X9
|
||||
|
||||
#define X_PTR SI
|
||||
#define Y_PTR DI
|
||||
#define LEN CX
|
||||
#define TAIL BX
|
||||
#define SUM X0
|
||||
#define P_SUM X1
|
||||
#define IDX AX
|
||||
#define I_IDX DX
|
||||
#define NEG1 X15
|
||||
#define P_NEG1 X14
|
||||
|
||||
// func DotcUnitary(x, y []complex64) (sum complex64)
|
||||
TEXT ·DotcUnitary(SB), NOSPLIT, $0
|
||||
MOVQ x_base+0(FP), X_PTR // X_PTR = &x
|
||||
MOVQ y_base+24(FP), Y_PTR // Y_PTR = &y
|
||||
PXOR SUM, SUM // SUM = 0
|
||||
PXOR P_SUM, P_SUM // P_SUM = 0
|
||||
MOVQ x_len+8(FP), LEN // LEN = min( len(x), len(y) )
|
||||
CMPQ y_len+32(FP), LEN
|
||||
CMOVQLE y_len+32(FP), LEN
|
||||
CMPQ LEN, $0 // if LEN == 0 { return }
|
||||
JE dotc_end
|
||||
XORQ IDX, IDX // i = 0
|
||||
MOVSS $(-1.0), NEG1
|
||||
SHUFPS $0, NEG1, NEG1 // { -1, -1, -1, -1 }
|
||||
|
||||
MOVQ X_PTR, DX
|
||||
ANDQ $15, DX // DX = &x & 15
|
||||
JZ dotc_aligned // if DX == 0 { goto dotc_aligned }
|
||||
|
||||
MOVSD (X_PTR)(IDX*8), X3 // X_i = { imag(x[i]), real(x[i]) }
|
||||
MOVSHDUP_X3_X2 // X_(i-1) = { imag(x[i]), imag(x[i]) }
|
||||
MOVSLDUP_X3_X3 // X_i = { real(x[i]), real(x[i]) }
|
||||
MOVSD (Y_PTR)(IDX*8), X10 // X_j = { imag(y[i]), real(y[i]) }
|
||||
MULPS NEG1, X2 // X_(i-1) = { -imag(x[i]), imag(x[i]) }
|
||||
MULPS X10, X3 // X_i = { imag(y[i]) * real(x[i]), real(y[i]) * real(x[i]) }
|
||||
SHUFPS $0x1, X10, X10 // X_j = { real(y[i]), imag(y[i]) }
|
||||
MULPS X10, X2 // X_(i-1) = { real(y[i]) * imag(x[i]), imag(y[i]) * imag(x[i]) }
|
||||
|
||||
// X_i = {
|
||||
// imag(result[i]): imag(y[i])*real(x[i]) + real(y[i])*imag(x[i]),
|
||||
// real(result[i]): real(y[i])*real(x[i]) - imag(y[i])*imag(x[i]) }
|
||||
ADDSUBPS_X2_X3
|
||||
|
||||
MOVAPS X3, SUM // SUM = X_i
|
||||
INCQ IDX // IDX++
|
||||
DECQ LEN // LEN--
|
||||
JZ dotc_ret // if LEN == 0 { goto dotc_ret }
|
||||
|
||||
dotc_aligned:
|
||||
MOVQ LEN, TAIL
|
||||
ANDQ $7, TAIL // TAIL = LEN % 8
|
||||
SHRQ $3, LEN // LEN = floor( LEN / 8 )
|
||||
JZ dotc_tail // if LEN == 0 { return }
|
||||
MOVUPS NEG1, P_NEG1 // Copy NEG1 for pipelining
|
||||
|
||||
dotc_loop: // do {
|
||||
MOVSLDUP_XPTR_IDX_8__X3 // X_i = { real(x[i]), real(x[i]), real(x[i+1]), real(x[i+1]) }
|
||||
MOVSLDUP_16_XPTR_IDX_8__X5
|
||||
MOVSLDUP_32_XPTR_IDX_8__X7
|
||||
MOVSLDUP_48_XPTR_IDX_8__X9
|
||||
|
||||
MOVSHDUP_XPTR_IDX_8__X2 // X_(i-1) = { imag(x[i]), imag(x[i]), imag(x[i+1]), imag(x[i+1]) }
|
||||
MOVSHDUP_16_XPTR_IDX_8__X4
|
||||
MOVSHDUP_32_XPTR_IDX_8__X6
|
||||
MOVSHDUP_48_XPTR_IDX_8__X8
|
||||
|
||||
// X_j = { imag(y[i]), real(y[i]), imag(y[i+1]), real(y[i+1]) }
|
||||
MOVUPS (Y_PTR)(IDX*8), X10
|
||||
MOVUPS 16(Y_PTR)(IDX*8), X11
|
||||
MOVUPS 32(Y_PTR)(IDX*8), X12
|
||||
MOVUPS 48(Y_PTR)(IDX*8), X13
|
||||
|
||||
// X_(i-1) = { -imag(x[i]), -imag(x[i]), -imag(x[i]+1), -imag(x[i]+1) }
|
||||
MULPS NEG1, X2
|
||||
MULPS P_NEG1, X4
|
||||
MULPS NEG1, X6
|
||||
MULPS P_NEG1, X8
|
||||
|
||||
// X_i = { imag(y[i]) * real(x[i]), real(y[i]) * real(x[i]),
|
||||
// imag(y[i+1]) * real(x[i+1]), real(y[i+1]) * real(x[i+1]) }
|
||||
MULPS X10, X3
|
||||
MULPS X11, X5
|
||||
MULPS X12, X7
|
||||
MULPS X13, X9
|
||||
|
||||
// X_j = { real(y[i]), imag(y[i]), real(y[i+1]), imag(y[i+1]) }
|
||||
SHUFPS $0xB1, X10, X10
|
||||
SHUFPS $0xB1, X11, X11
|
||||
SHUFPS $0xB1, X12, X12
|
||||
SHUFPS $0xB1, X13, X13
|
||||
|
||||
// X_(i-1) = { real(y[i]) * imag(x[i]), imag(y[i]) * imag(x[i]),
|
||||
// real(y[i+1]) * imag(x[i+1]), imag(y[i+1]) * imag(x[i+1]) }
|
||||
MULPS X10, X2
|
||||
MULPS X11, X4
|
||||
MULPS X12, X6
|
||||
MULPS X13, X8
|
||||
|
||||
// X_i = {
|
||||
// imag(result[i]): imag(y[i]) * real(x[i]) + real(y[i]) * imag(x[i]),
|
||||
// real(result[i]): real(y[i]) * real(x[i]) - imag(y[i]) * imag(x[i]),
|
||||
// imag(result[i+1]): imag(y[i+1]) * real(x[i+1]) + real(y[i+1]) * imag(x[i+1]),
|
||||
// real(result[i+1]): real(y[i+1]) * real(x[i+1]) - imag(y[i+1]) * imag(x[i+1]),
|
||||
// }
|
||||
ADDSUBPS_X2_X3
|
||||
ADDSUBPS_X4_X5
|
||||
ADDSUBPS_X6_X7
|
||||
ADDSUBPS_X8_X9
|
||||
|
||||
// SUM += X_i
|
||||
ADDPS X3, SUM
|
||||
ADDPS X5, P_SUM
|
||||
ADDPS X7, SUM
|
||||
ADDPS X9, P_SUM
|
||||
|
||||
ADDQ $8, IDX // IDX += 8
|
||||
DECQ LEN
|
||||
JNZ dotc_loop // } while --LEN > 0
|
||||
|
||||
ADDPS SUM, P_SUM // P_SUM = { P_SUM[1] + SUM[1], P_SUM[0] + SUM[0] }
|
||||
XORPS SUM, SUM // SUM = 0
|
||||
|
||||
CMPQ TAIL, $0 // if TAIL == 0 { return }
|
||||
JE dotc_end
|
||||
|
||||
dotc_tail:
|
||||
MOVQ TAIL, LEN
|
||||
SHRQ $1, LEN // LEN = floor( LEN / 2 )
|
||||
JZ dotc_tail_one // if LEN == 0 { goto dotc_tail_one }
|
||||
|
||||
dotc_tail_two: // do {
|
||||
MOVSLDUP_XPTR_IDX_8__X3 // X_i = { real(x[i]), real(x[i]), real(x[i+1]), real(x[i+1]) }
|
||||
MOVSHDUP_XPTR_IDX_8__X2 // X_(i-1) = { imag(x[i]), imag(x[i]), imag(x[i]+1), imag(x[i]+1) }
|
||||
MOVUPS (Y_PTR)(IDX*8), X10 // X_j = { imag(y[i]), real(y[i]) }
|
||||
MULPS NEG1, X2 // X_(i-1) = { -imag(x[i]), imag(x[i]) }
|
||||
MULPS X10, X3 // X_i = { imag(y[i]) * real(x[i]), real(y[i]) * real(x[i]) }
|
||||
SHUFPS $0xB1, X10, X10 // X_j = { real(y[i]), imag(y[i]) }
|
||||
MULPS X10, X2 // X_(i-1) = { real(y[i]) * imag(x[i]), imag(y[i]) * imag(x[i]) }
|
||||
|
||||
// X_i = {
|
||||
// imag(result[i]): imag(y[i])*real(x[i]) + real(y[i])*imag(x[i]),
|
||||
// real(result[i]): real(y[i])*real(x[i]) - imag(y[i])*imag(x[i]) }
|
||||
ADDSUBPS_X2_X3
|
||||
|
||||
ADDPS X3, SUM // SUM += X_i
|
||||
|
||||
ADDQ $2, IDX // IDX += 2
|
||||
DECQ LEN
|
||||
JNZ dotc_tail_two // } while --LEN > 0
|
||||
|
||||
ADDPS SUM, P_SUM // P_SUM = { P_SUM[1] + SUM[1], P_SUM[0] + SUM[0] }
|
||||
XORPS SUM, SUM // SUM = 0
|
||||
|
||||
ANDQ $1, TAIL
|
||||
JZ dotc_end
|
||||
|
||||
dotc_tail_one:
|
||||
MOVSD (X_PTR)(IDX*8), X3 // X_i = { imag(x[i]), real(x[i]) }
|
||||
MOVSHDUP_X3_X2 // X_(i-1) = { imag(x[i]), imag(x[i]) }
|
||||
MOVSLDUP_X3_X3 // X_i = { real(x[i]), real(x[i]) }
|
||||
MOVSD (Y_PTR)(IDX*8), X10 // X_j = { imag(y[i]), real(y[i]) }
|
||||
MULPS NEG1, X2 // X_(i-1) = { -imag(x[i]), imag(x[i]) }
|
||||
MULPS X10, X3 // X_i = { imag(y[i]) * real(x[i]), real(y[i]) * real(x[i]) }
|
||||
SHUFPS $0x1, X10, X10 // X_j = { real(y[i]), imag(y[i]) }
|
||||
MULPS X10, X2 // X_(i-1) = { real(y[i]) * imag(x[i]), imag(y[i]) * imag(x[i]) }
|
||||
|
||||
// X_i = {
|
||||
// imag(result[i]): imag(y[i])*real(x[i]) + real(y[i])*imag(x[i]),
|
||||
// real(result[i]): real(y[i])*real(x[i]) - imag(y[i])*imag(x[i]) }
|
||||
ADDSUBPS_X2_X3
|
||||
|
||||
ADDPS X3, SUM // SUM += X_i
|
||||
|
||||
dotc_end:
|
||||
ADDPS P_SUM, SUM // SUM = { P_SUM[0] + SUM[0] }
|
||||
MOVHLPS P_SUM, P_SUM // P_SUM = { P_SUM[1], P_SUM[1] }
|
||||
ADDPS P_SUM, SUM // SUM = { P_SUM[1] + SUM[0] }
|
||||
|
||||
dotc_ret:
|
||||
MOVSD SUM, sum+48(FP) // return SUM
|
||||
RET
|
||||
148
vendor/gonum.org/v1/gonum/internal/asm/c64/dotuinc_amd64.s
generated
vendored
Normal file
148
vendor/gonum.org/v1/gonum/internal/asm/c64/dotuinc_amd64.s
generated
vendored
Normal file
@@ -0,0 +1,148 @@
|
||||
// Copyright ©2016 The Gonum Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//+build !noasm,!appengine,!safe
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
#define MOVSHDUP_X3_X2 LONG $0xD3160FF3 // MOVSHDUP X3, X2
|
||||
#define MOVSHDUP_X5_X4 LONG $0xE5160FF3 // MOVSHDUP X5, X4
|
||||
#define MOVSHDUP_X7_X6 LONG $0xF7160FF3 // MOVSHDUP X7, X6
|
||||
#define MOVSHDUP_X9_X8 LONG $0x160F45F3; BYTE $0xC1 // MOVSHDUP X9, X8
|
||||
|
||||
#define MOVSLDUP_X3_X3 LONG $0xDB120FF3 // MOVSLDUP X3, X3
|
||||
#define MOVSLDUP_X5_X5 LONG $0xED120FF3 // MOVSLDUP X5, X5
|
||||
#define MOVSLDUP_X7_X7 LONG $0xFF120FF3 // MOVSLDUP X7, X7
|
||||
#define MOVSLDUP_X9_X9 LONG $0x120F45F3; BYTE $0xC9 // MOVSLDUP X9, X9
|
||||
|
||||
#define ADDSUBPS_X2_X3 LONG $0xDAD00FF2 // ADDSUBPS X2, X3
|
||||
#define ADDSUBPS_X4_X5 LONG $0xECD00FF2 // ADDSUBPS X4, X5
|
||||
#define ADDSUBPS_X6_X7 LONG $0xFED00FF2 // ADDSUBPS X6, X7
|
||||
#define ADDSUBPS_X8_X9 LONG $0xD00F45F2; BYTE $0xC8 // ADDSUBPS X8, X9
|
||||
|
||||
#define X_PTR SI
|
||||
#define Y_PTR DI
|
||||
#define LEN CX
|
||||
#define TAIL BX
|
||||
#define SUM X0
|
||||
#define P_SUM X1
|
||||
#define INC_X R8
|
||||
#define INCx3_X R9
|
||||
#define INC_Y R10
|
||||
#define INCx3_Y R11
|
||||
|
||||
// func DotuInc(x, y []complex64, n, incX, incY, ix, iy uintptr) (sum complex64)
|
||||
TEXT ·DotuInc(SB), NOSPLIT, $0
|
||||
MOVQ x_base+0(FP), X_PTR // X_PTR = &x
|
||||
MOVQ y_base+24(FP), Y_PTR // Y_PTR = &y
|
||||
PXOR SUM, SUM // SUM = 0
|
||||
PXOR P_SUM, P_SUM // P_SUM = 0
|
||||
MOVQ n+48(FP), LEN // LEN = n
|
||||
CMPQ LEN, $0 // if LEN == 0 { return }
|
||||
JE dotu_end
|
||||
MOVQ ix+72(FP), INC_X
|
||||
MOVQ iy+80(FP), INC_Y
|
||||
LEAQ (X_PTR)(INC_X*8), X_PTR // X_PTR = &(X_PTR[ix])
|
||||
LEAQ (Y_PTR)(INC_Y*8), Y_PTR // Y_PTR = &(Y_PTR[iy])
|
||||
MOVQ incX+56(FP), INC_X // INC_X = incX * sizeof(complex64)
|
||||
SHLQ $3, INC_X
|
||||
MOVQ incY+64(FP), INC_Y // INC_Y = incY * sizeof(complex64)
|
||||
SHLQ $3, INC_Y
|
||||
|
||||
MOVQ LEN, TAIL
|
||||
ANDQ $3, TAIL // TAIL = LEN % 4
|
||||
SHRQ $2, LEN // LEN = floor( LEN / 4 )
|
||||
JZ dotu_tail // if TAIL == 0 { goto dotu_tail }
|
||||
|
||||
LEAQ (INC_X)(INC_X*2), INCx3_X // INCx3_X = INC_X * 3
|
||||
LEAQ (INC_Y)(INC_Y*2), INCx3_Y // INCx3_Y = INC_Y * 3
|
||||
|
||||
dotu_loop: // do {
|
||||
MOVSD (X_PTR), X3 // X_i = { imag(x[i]), real(x[i]) }
|
||||
MOVSD (X_PTR)(INC_X*1), X5
|
||||
MOVSD (X_PTR)(INC_X*2), X7
|
||||
MOVSD (X_PTR)(INCx3_X*1), X9
|
||||
|
||||
// X_(i-1) = { imag(x[i]), imag(x[i]) }
|
||||
MOVSHDUP_X3_X2
|
||||
MOVSHDUP_X5_X4
|
||||
MOVSHDUP_X7_X6
|
||||
MOVSHDUP_X9_X8
|
||||
|
||||
// X_i = { real(x[i]), real(x[i]) }
|
||||
MOVSLDUP_X3_X3
|
||||
MOVSLDUP_X5_X5
|
||||
MOVSLDUP_X7_X7
|
||||
MOVSLDUP_X9_X9
|
||||
|
||||
// X_j = { imag(y[i]), real(y[i]) }
|
||||
MOVSD (Y_PTR), X10
|
||||
MOVSD (Y_PTR)(INC_Y*1), X11
|
||||
MOVSD (Y_PTR)(INC_Y*2), X12
|
||||
MOVSD (Y_PTR)(INCx3_Y*1), X13
|
||||
|
||||
// X_i = { imag(y[i]) * real(x[i]), real(y[i]) * real(x[i]) }
|
||||
MULPS X10, X3
|
||||
MULPS X11, X5
|
||||
MULPS X12, X7
|
||||
MULPS X13, X9
|
||||
|
||||
// X_j = { real(y[i]), imag(y[i]) }
|
||||
SHUFPS $0xB1, X10, X10
|
||||
SHUFPS $0xB1, X11, X11
|
||||
SHUFPS $0xB1, X12, X12
|
||||
SHUFPS $0xB1, X13, X13
|
||||
|
||||
// X_(i-1) = { real(y[i]) * imag(x[i]), imag(y[i]) * imag(x[i]) }
|
||||
MULPS X10, X2
|
||||
MULPS X11, X4
|
||||
MULPS X12, X6
|
||||
MULPS X13, X8
|
||||
|
||||
// X_i = {
|
||||
// imag(result[i]): imag(y[i]) * real(x[i]) + real(y[i]) * imag(x[i]),
|
||||
// real(result[i]): real(y[i]) * real(x[i]) - imag(y[i]) * imag(x[i]) }
|
||||
ADDSUBPS_X2_X3
|
||||
ADDSUBPS_X4_X5
|
||||
ADDSUBPS_X6_X7
|
||||
ADDSUBPS_X8_X9
|
||||
|
||||
// SUM += X_i
|
||||
ADDPS X3, SUM
|
||||
ADDPS X5, P_SUM
|
||||
ADDPS X7, SUM
|
||||
ADDPS X9, P_SUM
|
||||
|
||||
LEAQ (X_PTR)(INC_X*4), X_PTR // X_PTR = &(X_PTR[INC_X*4])
|
||||
LEAQ (Y_PTR)(INC_Y*4), Y_PTR // Y_PTR = &(Y_PTR[INC_Y*4])
|
||||
|
||||
DECQ LEN
|
||||
JNZ dotu_loop // } while --LEN > 0
|
||||
|
||||
ADDPS P_SUM, SUM // SUM = { P_SUM + SUM }
|
||||
CMPQ TAIL, $0 // if TAIL == 0 { return }
|
||||
JE dotu_end
|
||||
|
||||
dotu_tail: // do {
|
||||
MOVSD (X_PTR), X3 // X_i = { imag(x[i]), real(x[i]) }
|
||||
MOVSHDUP_X3_X2 // X_(i-1) = { imag(x[i]), imag(x[i]) }
|
||||
MOVSLDUP_X3_X3 // X_i = { real(x[i]), real(x[i]) }
|
||||
MOVUPS (Y_PTR), X10 // X_j = { imag(y[i]), real(y[i]) }
|
||||
MULPS X10, X3 // X_i = { imag(y[i]) * real(x[i]), real(y[i]) * real(x[i]) }
|
||||
SHUFPS $0x1, X10, X10 // X_j = { real(y[i]), imag(y[i]) }
|
||||
MULPS X10, X2 // X_(i-1) = { real(y[i]) * imag(x[i]), imag(y[i]) * imag(x[i]) }
|
||||
|
||||
// X_i = {
|
||||
// imag(result[i]): imag(y[i])*real(x[i]) + real(y[i])*imag(x[i]),
|
||||
// real(result[i]): real(y[i])*real(x[i]) - imag(y[i])*imag(x[i]) }
|
||||
ADDSUBPS_X2_X3
|
||||
ADDPS X3, SUM // SUM += X_i
|
||||
ADDQ INC_X, X_PTR // X_PTR += INC_X
|
||||
ADDQ INC_Y, Y_PTR // Y_PTR += INC_Y
|
||||
DECQ TAIL
|
||||
JNZ dotu_tail // } while --TAIL > 0
|
||||
|
||||
dotu_end:
|
||||
MOVSD SUM, sum+88(FP) // return SUM
|
||||
RET
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user