mirror of
https://github.com/optim-enterprises-bv/kubernetes.git
synced 2025-11-07 13:54:19 +00:00
Merge pull request #112692 from liggitt/dot-cleanup
Drop DOT dependency
This commit is contained in:
26
LICENSES/vendor/gonum.org/v1/gonum/LICENSE
generated
vendored
26
LICENSES/vendor/gonum.org/v1/gonum/LICENSE
generated
vendored
@@ -1,26 +0,0 @@
|
|||||||
= vendor/gonum.org/v1/gonum licensed under: =
|
|
||||||
|
|
||||||
Copyright ©2013 The Gonum Authors. All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions are met:
|
|
||||||
* Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
* Redistributions in binary form must reproduce the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer in the
|
|
||||||
documentation and/or other materials provided with the distribution.
|
|
||||||
* Neither the name of the gonum project nor the names of its authors and
|
|
||||||
contributors may be used to endorse or promote products derived from this
|
|
||||||
software without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
||||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
||||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
||||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
||||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
||||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
||||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
= vendor/gonum.org/v1/gonum/LICENSE 665e67d07d85e236cceb8de602c6255a
|
|
||||||
23
go.mod
23
go.mod
@@ -86,7 +86,6 @@ require (
|
|||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211
|
||||||
golang.org/x/time v0.0.0-20220210224613-90d013bbcef8
|
golang.org/x/time v0.0.0-20220210224613-90d013bbcef8
|
||||||
golang.org/x/tools v0.1.12
|
golang.org/x/tools v0.1.12
|
||||||
gonum.org/v1/gonum v0.6.2
|
|
||||||
google.golang.org/api v0.60.0
|
google.golang.org/api v0.60.0
|
||||||
google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21
|
google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21
|
||||||
google.golang.org/grpc v1.49.0
|
google.golang.org/grpc v1.49.0
|
||||||
@@ -235,10 +234,8 @@ require (
|
|||||||
go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 // indirect
|
go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 // indirect
|
||||||
go.uber.org/atomic v1.7.0 // indirect
|
go.uber.org/atomic v1.7.0 // indirect
|
||||||
go.uber.org/multierr v1.6.0 // indirect
|
go.uber.org/multierr v1.6.0 // indirect
|
||||||
golang.org/x/exp v0.0.0-20210220032938-85be41e4509f // indirect
|
|
||||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
|
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
|
||||||
golang.org/x/text v0.3.7 // indirect
|
golang.org/x/text v0.3.7 // indirect
|
||||||
gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e // indirect
|
|
||||||
google.golang.org/appengine v1.6.7 // indirect
|
google.golang.org/appengine v1.6.7 // indirect
|
||||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
|
gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
|
||||||
@@ -256,7 +253,6 @@ replace (
|
|||||||
cloud.google.com/go => cloud.google.com/go v0.97.0
|
cloud.google.com/go => cloud.google.com/go v0.97.0
|
||||||
cloud.google.com/go/bigquery => cloud.google.com/go/bigquery v1.8.0
|
cloud.google.com/go/bigquery => cloud.google.com/go/bigquery v1.8.0
|
||||||
cloud.google.com/go/storage => cloud.google.com/go/storage v1.10.0
|
cloud.google.com/go/storage => cloud.google.com/go/storage v1.10.0
|
||||||
dmitri.shuralyov.com/gpu/mtl => dmitri.shuralyov.com/gpu/mtl v0.0.0-20201218220906-28db891af037
|
|
||||||
github.com/Azure/azure-sdk-for-go => github.com/Azure/azure-sdk-for-go v55.0.0+incompatible
|
github.com/Azure/azure-sdk-for-go => github.com/Azure/azure-sdk-for-go v55.0.0+incompatible
|
||||||
github.com/Azure/go-ansiterm => github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1
|
github.com/Azure/go-ansiterm => github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1
|
||||||
github.com/Azure/go-autorest => github.com/Azure/go-autorest v14.2.0+incompatible
|
github.com/Azure/go-autorest => github.com/Azure/go-autorest v14.2.0+incompatible
|
||||||
@@ -269,7 +265,6 @@ replace (
|
|||||||
github.com/Azure/go-autorest/logger => github.com/Azure/go-autorest/logger v0.2.1
|
github.com/Azure/go-autorest/logger => github.com/Azure/go-autorest/logger v0.2.1
|
||||||
github.com/Azure/go-autorest/tracing => github.com/Azure/go-autorest/tracing v0.6.0
|
github.com/Azure/go-autorest/tracing => github.com/Azure/go-autorest/tracing v0.6.0
|
||||||
github.com/BurntSushi/toml => github.com/BurntSushi/toml v0.3.1
|
github.com/BurntSushi/toml => github.com/BurntSushi/toml v0.3.1
|
||||||
github.com/BurntSushi/xgb => github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802
|
|
||||||
github.com/GoogleCloudPlatform/k8s-cloud-provider => github.com/GoogleCloudPlatform/k8s-cloud-provider v1.18.1-0.20220218231025-f11817397a1b
|
github.com/GoogleCloudPlatform/k8s-cloud-provider => github.com/GoogleCloudPlatform/k8s-cloud-provider v1.18.1-0.20220218231025-f11817397a1b
|
||||||
github.com/JeffAshton/win_pdh => github.com/JeffAshton/win_pdh v0.0.0-20161109143554-76bb4ee9f0ab
|
github.com/JeffAshton/win_pdh => github.com/JeffAshton/win_pdh v0.0.0-20161109143554-76bb4ee9f0ab
|
||||||
github.com/MakeNowJust/heredoc => github.com/MakeNowJust/heredoc v1.0.0
|
github.com/MakeNowJust/heredoc => github.com/MakeNowJust/heredoc v1.0.0
|
||||||
@@ -278,7 +273,6 @@ replace (
|
|||||||
github.com/NYTimes/gziphandler => github.com/NYTimes/gziphandler v1.1.1
|
github.com/NYTimes/gziphandler => github.com/NYTimes/gziphandler v1.1.1
|
||||||
github.com/PuerkitoBio/purell => github.com/PuerkitoBio/purell v1.1.1
|
github.com/PuerkitoBio/purell => github.com/PuerkitoBio/purell v1.1.1
|
||||||
github.com/PuerkitoBio/urlesc => github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578
|
github.com/PuerkitoBio/urlesc => github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578
|
||||||
github.com/ajstarks/svgo => github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af
|
|
||||||
github.com/antihax/optional => github.com/antihax/optional v1.0.0
|
github.com/antihax/optional => github.com/antihax/optional v1.0.0
|
||||||
github.com/antlr/antlr4/runtime/Go/antlr => github.com/antlr/antlr4/runtime/Go/antlr v1.4.10
|
github.com/antlr/antlr4/runtime/Go/antlr => github.com/antlr/antlr4/runtime/Go/antlr v1.4.10
|
||||||
github.com/armon/circbuf => github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e
|
github.com/armon/circbuf => github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e
|
||||||
@@ -340,7 +334,6 @@ replace (
|
|||||||
github.com/fatih/camelcase => github.com/fatih/camelcase v1.0.0
|
github.com/fatih/camelcase => github.com/fatih/camelcase v1.0.0
|
||||||
github.com/felixge/httpsnoop => github.com/felixge/httpsnoop v1.0.3
|
github.com/felixge/httpsnoop => github.com/felixge/httpsnoop v1.0.3
|
||||||
github.com/flynn/go-shlex => github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568
|
github.com/flynn/go-shlex => github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568
|
||||||
github.com/fogleman/gg => github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90
|
|
||||||
github.com/form3tech-oss/jwt-go => github.com/form3tech-oss/jwt-go v3.2.3+incompatible
|
github.com/form3tech-oss/jwt-go => github.com/form3tech-oss/jwt-go v3.2.3+incompatible
|
||||||
github.com/frankban/quicktest => github.com/frankban/quicktest v1.11.3
|
github.com/frankban/quicktest => github.com/frankban/quicktest v1.11.3
|
||||||
github.com/fsnotify/fsnotify => github.com/fsnotify/fsnotify v1.5.4
|
github.com/fsnotify/fsnotify => github.com/fsnotify/fsnotify v1.5.4
|
||||||
@@ -349,7 +342,6 @@ replace (
|
|||||||
github.com/getsentry/raven-go => github.com/getsentry/raven-go v0.2.0
|
github.com/getsentry/raven-go => github.com/getsentry/raven-go v0.2.0
|
||||||
github.com/ghodss/yaml => github.com/ghodss/yaml v1.0.0
|
github.com/ghodss/yaml => github.com/ghodss/yaml v1.0.0
|
||||||
github.com/go-errors/errors => github.com/go-errors/errors v1.0.1
|
github.com/go-errors/errors => github.com/go-errors/errors v1.0.1
|
||||||
github.com/go-gl/glfw/v3.3/glfw => github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4
|
|
||||||
github.com/go-kit/kit => github.com/go-kit/kit v0.9.0
|
github.com/go-kit/kit => github.com/go-kit/kit v0.9.0
|
||||||
github.com/go-kit/log => github.com/go-kit/log v0.2.0
|
github.com/go-kit/log => github.com/go-kit/log v0.2.0
|
||||||
github.com/go-logfmt/logfmt => github.com/go-logfmt/logfmt v0.5.1
|
github.com/go-logfmt/logfmt => github.com/go-logfmt/logfmt v0.5.1
|
||||||
@@ -366,7 +358,6 @@ replace (
|
|||||||
github.com/gogo/googleapis => github.com/gogo/googleapis v1.4.1
|
github.com/gogo/googleapis => github.com/gogo/googleapis v1.4.1
|
||||||
github.com/gogo/protobuf => github.com/gogo/protobuf v1.3.2
|
github.com/gogo/protobuf => github.com/gogo/protobuf v1.3.2
|
||||||
github.com/golang-jwt/jwt/v4 => github.com/golang-jwt/jwt/v4 v4.2.0
|
github.com/golang-jwt/jwt/v4 => github.com/golang-jwt/jwt/v4 v4.2.0
|
||||||
github.com/golang/freetype => github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0
|
|
||||||
github.com/golang/glog => github.com/golang/glog v1.0.0
|
github.com/golang/glog => github.com/golang/glog v1.0.0
|
||||||
github.com/golang/groupcache => github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da
|
github.com/golang/groupcache => github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da
|
||||||
github.com/golang/mock => github.com/golang/mock v1.6.0
|
github.com/golang/mock => github.com/golang/mock v1.6.0
|
||||||
@@ -404,7 +395,6 @@ replace (
|
|||||||
github.com/jpillora/backoff => github.com/jpillora/backoff v1.0.0
|
github.com/jpillora/backoff => github.com/jpillora/backoff v1.0.0
|
||||||
github.com/json-iterator/go => github.com/json-iterator/go v1.1.12
|
github.com/json-iterator/go => github.com/json-iterator/go v1.1.12
|
||||||
github.com/julienschmidt/httprouter => github.com/julienschmidt/httprouter v1.3.0
|
github.com/julienschmidt/httprouter => github.com/julienschmidt/httprouter v1.3.0
|
||||||
github.com/jung-kurt/gofpdf => github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5
|
|
||||||
github.com/karrick/godirwalk => github.com/karrick/godirwalk v1.16.1
|
github.com/karrick/godirwalk => github.com/karrick/godirwalk v1.16.1
|
||||||
github.com/kisielk/errcheck => github.com/kisielk/errcheck v1.5.0
|
github.com/kisielk/errcheck => github.com/kisielk/errcheck v1.5.0
|
||||||
github.com/kisielk/gotool => github.com/kisielk/gotool v1.0.0
|
github.com/kisielk/gotool => github.com/kisielk/gotool v1.0.0
|
||||||
@@ -453,7 +443,6 @@ replace (
|
|||||||
github.com/prometheus/client_model => github.com/prometheus/client_model v0.2.0
|
github.com/prometheus/client_model => github.com/prometheus/client_model v0.2.0
|
||||||
github.com/prometheus/common => github.com/prometheus/common v0.37.0
|
github.com/prometheus/common => github.com/prometheus/common v0.37.0
|
||||||
github.com/prometheus/procfs => github.com/prometheus/procfs v0.8.0
|
github.com/prometheus/procfs => github.com/prometheus/procfs v0.8.0
|
||||||
github.com/remyoudompheng/bigfft => github.com/remyoudompheng/bigfft v0.0.0-20170806203942-52369c62f446
|
|
||||||
github.com/robfig/cron/v3 => github.com/robfig/cron/v3 v3.0.1
|
github.com/robfig/cron/v3 => github.com/robfig/cron/v3 v3.0.1
|
||||||
github.com/rogpeppe/fastuuid => github.com/rogpeppe/fastuuid v1.2.0
|
github.com/rogpeppe/fastuuid => github.com/rogpeppe/fastuuid v1.2.0
|
||||||
github.com/rogpeppe/go-internal => github.com/rogpeppe/go-internal v1.3.0
|
github.com/rogpeppe/go-internal => github.com/rogpeppe/go-internal v1.3.0
|
||||||
@@ -505,10 +494,7 @@ replace (
|
|||||||
go.uber.org/multierr => go.uber.org/multierr v1.6.0
|
go.uber.org/multierr => go.uber.org/multierr v1.6.0
|
||||||
go.uber.org/zap => go.uber.org/zap v1.19.0
|
go.uber.org/zap => go.uber.org/zap v1.19.0
|
||||||
golang.org/x/crypto => golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4
|
golang.org/x/crypto => golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4
|
||||||
golang.org/x/exp => golang.org/x/exp v0.0.0-20210220032938-85be41e4509f
|
|
||||||
golang.org/x/image => golang.org/x/image v0.0.0-20190802002840-cff245a6509b
|
|
||||||
golang.org/x/lint => golang.org/x/lint v0.0.0-20190930215403-16217165b5de
|
golang.org/x/lint => golang.org/x/lint v0.0.0-20190930215403-16217165b5de
|
||||||
golang.org/x/mobile => golang.org/x/mobile v0.0.0-20201217150744-e6ae53a27f4f
|
|
||||||
golang.org/x/mod => golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4
|
golang.org/x/mod => golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4
|
||||||
golang.org/x/net => golang.org/x/net v0.0.0-20220722155237-a158d28d115b
|
golang.org/x/net => golang.org/x/net v0.0.0-20220722155237-a158d28d115b
|
||||||
golang.org/x/oauth2 => golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b
|
golang.org/x/oauth2 => golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b
|
||||||
@@ -519,9 +505,6 @@ replace (
|
|||||||
golang.org/x/time => golang.org/x/time v0.0.0-20220210224613-90d013bbcef8
|
golang.org/x/time => golang.org/x/time v0.0.0-20220210224613-90d013bbcef8
|
||||||
golang.org/x/tools => golang.org/x/tools v0.1.12
|
golang.org/x/tools => golang.org/x/tools v0.1.12
|
||||||
golang.org/x/xerrors => golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1
|
golang.org/x/xerrors => golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1
|
||||||
gonum.org/v1/gonum => gonum.org/v1/gonum v0.6.2
|
|
||||||
gonum.org/v1/netlib => gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e
|
|
||||||
gonum.org/v1/plot => gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b
|
|
||||||
google.golang.org/api => google.golang.org/api v0.60.0
|
google.golang.org/api => google.golang.org/api v0.60.0
|
||||||
google.golang.org/appengine => google.golang.org/appengine v1.6.7
|
google.golang.org/appengine => google.golang.org/appengine v1.6.7
|
||||||
google.golang.org/genproto => google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21
|
google.golang.org/genproto => google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21
|
||||||
@@ -572,12 +555,6 @@ replace (
|
|||||||
k8s.io/sample-controller => ./staging/src/k8s.io/sample-controller
|
k8s.io/sample-controller => ./staging/src/k8s.io/sample-controller
|
||||||
k8s.io/system-validators => k8s.io/system-validators v1.8.0
|
k8s.io/system-validators => k8s.io/system-validators v1.8.0
|
||||||
k8s.io/utils => k8s.io/utils v0.0.0-20220922133306-665eaaec4324
|
k8s.io/utils => k8s.io/utils v0.0.0-20220922133306-665eaaec4324
|
||||||
modernc.org/cc => modernc.org/cc v1.0.0
|
|
||||||
modernc.org/golex => modernc.org/golex v1.0.0
|
|
||||||
modernc.org/mathutil => modernc.org/mathutil v1.0.0
|
|
||||||
modernc.org/strutil => modernc.org/strutil v1.0.0
|
|
||||||
modernc.org/xc => modernc.org/xc v1.0.0
|
|
||||||
rsc.io/pdf => rsc.io/pdf v0.1.1
|
|
||||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client => sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.32
|
sigs.k8s.io/apiserver-network-proxy/konnectivity-client => sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.32
|
||||||
sigs.k8s.io/json => sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2
|
sigs.k8s.io/json => sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2
|
||||||
sigs.k8s.io/kustomize/api => sigs.k8s.io/kustomize/api v0.12.1
|
sigs.k8s.io/kustomize/api => sigs.k8s.io/kustomize/api v0.12.1
|
||||||
|
|||||||
23
go.sum
23
go.sum
@@ -5,7 +5,6 @@ cloud.google.com/go v0.97.0 h1:3DXvAyifywvq64LfkKaMOmkWPS1CikIQdMe2lY9vxU8=
|
|||||||
cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc=
|
cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc=
|
||||||
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
|
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
|
||||||
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
||||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20201218220906-28db891af037/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
|
||||||
github.com/Azure/azure-sdk-for-go v55.0.0+incompatible h1:L4/vUGbg1Xkw5L20LZD+hJI5I+ibWSytqQ68lTCfLwY=
|
github.com/Azure/azure-sdk-for-go v55.0.0+incompatible h1:L4/vUGbg1Xkw5L20LZD+hJI5I+ibWSytqQ68lTCfLwY=
|
||||||
github.com/Azure/azure-sdk-for-go v55.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
github.com/Azure/azure-sdk-for-go v55.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
||||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8=
|
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8=
|
||||||
@@ -30,7 +29,6 @@ github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUM
|
|||||||
github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
|
github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
|
||||||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
|
||||||
github.com/GoogleCloudPlatform/k8s-cloud-provider v1.18.1-0.20220218231025-f11817397a1b h1:Heo1J/ttaQFgGJSVnCZquy3e5eH5j1nqxBuomztB3P0=
|
github.com/GoogleCloudPlatform/k8s-cloud-provider v1.18.1-0.20220218231025-f11817397a1b h1:Heo1J/ttaQFgGJSVnCZquy3e5eH5j1nqxBuomztB3P0=
|
||||||
github.com/GoogleCloudPlatform/k8s-cloud-provider v1.18.1-0.20220218231025-f11817397a1b/go.mod h1:FNj4KYEAAHfYu68kRYolGoxkaJn+6mdEsaM12VTwuI0=
|
github.com/GoogleCloudPlatform/k8s-cloud-provider v1.18.1-0.20220218231025-f11817397a1b/go.mod h1:FNj4KYEAAHfYu68kRYolGoxkaJn+6mdEsaM12VTwuI0=
|
||||||
github.com/JeffAshton/win_pdh v0.0.0-20161109143554-76bb4ee9f0ab h1:UKkYhof1njT1/xq4SEg5z+VpTgjmNeHwPGRQl7takDI=
|
github.com/JeffAshton/win_pdh v0.0.0-20161109143554-76bb4ee9f0ab h1:UKkYhof1njT1/xq4SEg5z+VpTgjmNeHwPGRQl7takDI=
|
||||||
@@ -43,7 +41,6 @@ github.com/Microsoft/hcsshim v0.8.22 h1:CulZ3GW8sNJExknToo+RWD+U+6ZM5kkNfuxywSDP
|
|||||||
github.com/Microsoft/hcsshim v0.8.22/go.mod h1:91uVCVzvX2QD16sMCenoxxXo6L1wJnLMX2PSufFMtF0=
|
github.com/Microsoft/hcsshim v0.8.22/go.mod h1:91uVCVzvX2QD16sMCenoxxXo6L1wJnLMX2PSufFMtF0=
|
||||||
github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I=
|
github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I=
|
||||||
github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c=
|
github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c=
|
||||||
github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw=
|
|
||||||
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
||||||
github.com/antlr/antlr4/runtime/Go/antlr v1.4.10 h1:yL7+Jz0jTC6yykIK/Wh74gnTJnrGr5AyrNMXuA0gves=
|
github.com/antlr/antlr4/runtime/Go/antlr v1.4.10 h1:yL7+Jz0jTC6yykIK/Wh74gnTJnrGr5AyrNMXuA0gves=
|
||||||
github.com/antlr/antlr4/runtime/Go/antlr v1.4.10/go.mod h1:F7bn7fEU90QkQ3tnmaTx3LTKLEDqnwWODIYppRQ5hnY=
|
github.com/antlr/antlr4/runtime/Go/antlr v1.4.10/go.mod h1:F7bn7fEU90QkQ3tnmaTx3LTKLEDqnwWODIYppRQ5hnY=
|
||||||
@@ -150,7 +147,6 @@ github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwo
|
|||||||
github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk=
|
github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk=
|
||||||
github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||||
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
|
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
|
||||||
github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
|
|
||||||
github.com/form3tech-oss/jwt-go v3.2.3+incompatible h1:7ZaBxOI7TMoYBfyA3cQHErNNyAWIKUMIwqxEtgHOs5c=
|
github.com/form3tech-oss/jwt-go v3.2.3+incompatible h1:7ZaBxOI7TMoYBfyA3cQHErNNyAWIKUMIwqxEtgHOs5c=
|
||||||
github.com/form3tech-oss/jwt-go v3.2.3+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
|
github.com/form3tech-oss/jwt-go v3.2.3+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
|
||||||
github.com/frankban/quicktest v1.11.3 h1:8sXhOn0uLys67V8EsXLc6eszDs8VXWxL3iRvebPhedY=
|
github.com/frankban/quicktest v1.11.3 h1:8sXhOn0uLys67V8EsXLc6eszDs8VXWxL3iRvebPhedY=
|
||||||
@@ -164,7 +160,6 @@ github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49P
|
|||||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||||
github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w=
|
github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w=
|
||||||
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
|
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
|
||||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
|
||||||
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||||
github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0=
|
github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0=
|
||||||
github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
|
github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
|
||||||
@@ -192,7 +187,6 @@ github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
|||||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||||
github.com/golang-jwt/jwt/v4 v4.2.0 h1:besgBTC8w8HjP6NzQdxwKH9Z5oQMZ24ThTrHp3cZ8eU=
|
github.com/golang-jwt/jwt/v4 v4.2.0 h1:besgBTC8w8HjP6NzQdxwKH9Z5oQMZ24ThTrHp3cZ8eU=
|
||||||
github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
|
github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
|
||||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
|
|
||||||
github.com/golang/glog v1.0.0 h1:nfP3RFugxnNRyKgeWd4oI1nYvXpxrx8ck8ZrcizshdQ=
|
github.com/golang/glog v1.0.0 h1:nfP3RFugxnNRyKgeWd4oI1nYvXpxrx8ck8ZrcizshdQ=
|
||||||
github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4=
|
github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4=
|
||||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
|
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
|
||||||
@@ -259,7 +253,6 @@ github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX
|
|||||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||||
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
|
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
|
||||||
github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=
|
|
||||||
github.com/karrick/godirwalk v1.16.1 h1:DynhcF+bztK8gooS0+NDJFrdNZjJ3gzVzC545UNA9iw=
|
github.com/karrick/godirwalk v1.16.1 h1:DynhcF+bztK8gooS0+NDJFrdNZjJ3gzVzC545UNA9iw=
|
||||||
github.com/karrick/godirwalk v1.16.1/go.mod h1:j4mkqPuvaLI8mp1DroR3P6ad7cyYd4c1qeJ3RV7ULlk=
|
github.com/karrick/godirwalk v1.16.1/go.mod h1:j4mkqPuvaLI8mp1DroR3P6ad7cyYd4c1qeJ3RV7ULlk=
|
||||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||||
@@ -346,7 +339,6 @@ github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8
|
|||||||
github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA=
|
github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA=
|
||||||
github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo=
|
github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo=
|
||||||
github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4=
|
github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4=
|
||||||
github.com/remyoudompheng/bigfft v0.0.0-20170806203942-52369c62f446/go.mod h1:uYEyJGbgTkfkS4+E/PavXkNJcbFIpEtjt2B0KDQ5+9M=
|
|
||||||
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
|
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
|
||||||
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
|
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
|
||||||
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||||
@@ -443,11 +435,7 @@ go.uber.org/zap v1.19.0 h1:mZQZefskPPCMIBCSEH0v2/iUqqLrYtaeqwD6FUGUnFE=
|
|||||||
go.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI=
|
go.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI=
|
||||||
golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 h1:kUhD7nTDoI3fVd9G4ORWrbV5NY0liEs/Jg2pv5f+bBA=
|
golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 h1:kUhD7nTDoI3fVd9G4ORWrbV5NY0liEs/Jg2pv5f+bBA=
|
||||||
golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
golang.org/x/exp v0.0.0-20210220032938-85be41e4509f h1:GrkO5AtFUU9U/1f5ctbIBXtBGeSJbWwIYfIsTcFMaX4=
|
|
||||||
golang.org/x/exp v0.0.0-20210220032938-85be41e4509f/go.mod h1:I6l2HNBLBZEcrOoCpyKLdY2lHoRZ8lI4x60KMCQDft4=
|
|
||||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
|
||||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||||
golang.org/x/mobile v0.0.0-20201217150744-e6ae53a27f4f/go.mod h1:skQtrUTUwhdJvXM/2KKJzY8pDgNr9I/FOMqDVRPBUS4=
|
|
||||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s=
|
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s=
|
||||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b h1:PxfKdU9lEEDYjdIzOtC4qFWgkU2rGHdKlKowJSMN9h0=
|
golang.org/x/net v0.0.0-20220722155237-a158d28d115b h1:PxfKdU9lEEDYjdIzOtC4qFWgkU2rGHdKlKowJSMN9h0=
|
||||||
@@ -467,11 +455,6 @@ golang.org/x/time v0.0.0-20220210224613-90d013bbcef8/go.mod h1:tRJNPiyCQ0inRvYxb
|
|||||||
golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU=
|
golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU=
|
||||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
gonum.org/v1/gonum v0.6.2 h1:4r+yNT0+8SWcOkXP+63H2zQbN+USnC73cjGUxnDF94Q=
|
|
||||||
gonum.org/v1/gonum v0.6.2/go.mod h1:9mxDZsDKxgMAuccQkewq682L+0eCu4dCN2yonUJTCLU=
|
|
||||||
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=
|
|
||||||
gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc=
|
|
||||||
google.golang.org/api v0.60.0 h1:eq/zs5WPH4J9undYM9IP1O7dSr7Yh8Y0GtSCpzGzIUk=
|
google.golang.org/api v0.60.0 h1:eq/zs5WPH4J9undYM9IP1O7dSr7Yh8Y0GtSCpzGzIUk=
|
||||||
google.golang.org/api v0.60.0/go.mod h1:d7rl65NZAkEQ90JFzqBjcRq1TVeG5ZoGV3sSpEnnVb4=
|
google.golang.org/api v0.60.0/go.mod h1:d7rl65NZAkEQ90JFzqBjcRq1TVeG5ZoGV3sSpEnnVb4=
|
||||||
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
|
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
|
||||||
@@ -514,12 +497,6 @@ k8s.io/system-validators v1.8.0 h1:tq05tdO9zdJZnNF3SXrq6LE7Knc/KfJm5wk68467JDg=
|
|||||||
k8s.io/system-validators v1.8.0/go.mod h1:gP1Ky+R9wtrSiFbrpEPwWMeYz9yqyy1S/KOh0Vci7WI=
|
k8s.io/system-validators v1.8.0/go.mod h1:gP1Ky+R9wtrSiFbrpEPwWMeYz9yqyy1S/KOh0Vci7WI=
|
||||||
k8s.io/utils v0.0.0-20220922133306-665eaaec4324 h1:i+xdFemcSNuJvIfBlaYuXgRondKxK4z4prVPKzEaelI=
|
k8s.io/utils v0.0.0-20220922133306-665eaaec4324 h1:i+xdFemcSNuJvIfBlaYuXgRondKxK4z4prVPKzEaelI=
|
||||||
k8s.io/utils v0.0.0-20220922133306-665eaaec4324/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
|
k8s.io/utils v0.0.0-20220922133306-665eaaec4324/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
|
||||||
modernc.org/cc v1.0.0/go.mod h1:1Sk4//wdnYJiUIxnW8ddKpaOJCF37yAdqYnkxUpaYxw=
|
|
||||||
modernc.org/golex v1.0.0/go.mod h1:b/QX9oBD/LhixY6NDh+IdGv17hgB+51fET1i2kPSmvk=
|
|
||||||
modernc.org/mathutil v1.0.0/go.mod h1:wU0vUrJsVWBZ4P6e7xtFJEhFSNsfRLJ8H458uRjg03k=
|
|
||||||
modernc.org/strutil v1.0.0/go.mod h1:lstksw84oURvj9y3tn8lGvRxyRC1S2+g5uuIzNfIOBs=
|
|
||||||
modernc.org/xc v1.0.0/go.mod h1:mRNCo0bvLjGhHO9WsyuKVU4q0ceiDDDoEeWDJHrNx8I=
|
|
||||||
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
|
|
||||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.32 h1:2WjukG7txtEsbXsSKWtTibCdsyYAhcu6KFnttyDdZOQ=
|
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.32 h1:2WjukG7txtEsbXsSKWtTibCdsyYAhcu6KFnttyDdZOQ=
|
||||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.32/go.mod h1:fEO7lRTdivWO2qYVCVG7dEADOMo/MLDCVr8So2g88Uw=
|
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.32/go.mod h1:fEO7lRTdivWO2qYVCVG7dEADOMo/MLDCVr8So2g88Uw=
|
||||||
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k=
|
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k=
|
||||||
|
|||||||
@@ -17,22 +17,20 @@ limitations under the License.
|
|||||||
package garbagecollector
|
package garbagecollector
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"gonum.org/v1/gonum/graph"
|
|
||||||
"gonum.org/v1/gonum/graph/encoding"
|
|
||||||
"gonum.org/v1/gonum/graph/encoding/dot"
|
|
||||||
"gonum.org/v1/gonum/graph/simple"
|
|
||||||
|
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
"k8s.io/apimachinery/pkg/types"
|
"k8s.io/apimachinery/pkg/types"
|
||||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||||
)
|
)
|
||||||
|
|
||||||
type gonumVertex struct {
|
type dotVertex struct {
|
||||||
uid types.UID
|
uid types.UID
|
||||||
gvk schema.GroupVersionKind
|
gvk schema.GroupVersionKind
|
||||||
namespace string
|
namespace string
|
||||||
@@ -41,14 +39,25 @@ type gonumVertex struct {
|
|||||||
beingDeleted bool
|
beingDeleted bool
|
||||||
deletingDependents bool
|
deletingDependents bool
|
||||||
virtual bool
|
virtual bool
|
||||||
vertexID int64
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *gonumVertex) ID() int64 {
|
func (v *dotVertex) MarshalDOT(w io.Writer) error {
|
||||||
return v.vertexID
|
attrs := v.Attributes()
|
||||||
|
if _, err := fmt.Fprintf(w, " %q [\n", v.uid); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, a := range attrs {
|
||||||
|
if _, err := fmt.Fprintf(w, " %s=%q\n", a.Key, a.Value); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if _, err := fmt.Fprintf(w, " ];\n"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *gonumVertex) String() string {
|
func (v *dotVertex) String() string {
|
||||||
kind := v.gvk.Kind + "." + v.gvk.Version
|
kind := v.gvk.Kind + "." + v.gvk.Version
|
||||||
if len(v.gvk.Group) > 0 {
|
if len(v.gvk.Group) > 0 {
|
||||||
kind = kind + "." + v.gvk.Group
|
kind = kind + "." + v.gvk.Group
|
||||||
@@ -72,7 +81,12 @@ func (v *gonumVertex) String() string {
|
|||||||
return fmt.Sprintf(`%s/%s[%s]-%v%s%s%s%s`, kind, v.name, v.namespace, v.uid, missing, deleting, deletingDependents, virtual)
|
return fmt.Sprintf(`%s/%s[%s]-%v%s%s%s%s`, kind, v.name, v.namespace, v.uid, missing, deleting, deletingDependents, virtual)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *gonumVertex) Attributes() []encoding.Attribute {
|
type attribute struct {
|
||||||
|
Key string
|
||||||
|
Value string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *dotVertex) Attributes() []attribute {
|
||||||
kubectlString := v.gvk.Kind + "." + v.gvk.Version
|
kubectlString := v.gvk.Kind + "." + v.gvk.Version
|
||||||
if len(v.gvk.Group) > 0 {
|
if len(v.gvk.Group) > 0 {
|
||||||
kubectlString = kubectlString + "." + v.gvk.Group
|
kubectlString = kubectlString + "." + v.gvk.Group
|
||||||
@@ -106,30 +120,30 @@ namespace=%v
|
|||||||
label = label + conditionString + "\n"
|
label = label + conditionString + "\n"
|
||||||
}
|
}
|
||||||
|
|
||||||
return []encoding.Attribute{
|
return []attribute{
|
||||||
{Key: "label", Value: fmt.Sprintf(`"%v"`, label)},
|
{Key: "label", Value: label},
|
||||||
// these place metadata in the correct location, but don't conform to any normal attribute for rendering
|
// these place metadata in the correct location, but don't conform to any normal attribute for rendering
|
||||||
{Key: "group", Value: fmt.Sprintf(`"%v"`, v.gvk.Group)},
|
{Key: "group", Value: v.gvk.Group},
|
||||||
{Key: "version", Value: fmt.Sprintf(`"%v"`, v.gvk.Version)},
|
{Key: "version", Value: v.gvk.Version},
|
||||||
{Key: "kind", Value: fmt.Sprintf(`"%v"`, v.gvk.Kind)},
|
{Key: "kind", Value: v.gvk.Kind},
|
||||||
{Key: "namespace", Value: fmt.Sprintf(`"%v"`, v.namespace)},
|
{Key: "namespace", Value: v.namespace},
|
||||||
{Key: "name", Value: fmt.Sprintf(`"%v"`, v.name)},
|
{Key: "name", Value: v.name},
|
||||||
{Key: "uid", Value: fmt.Sprintf(`"%v"`, v.uid)},
|
{Key: "uid", Value: string(v.uid)},
|
||||||
{Key: "missing", Value: fmt.Sprintf(`"%v"`, v.missingFromGraph)},
|
{Key: "missing", Value: fmt.Sprintf(`%v`, v.missingFromGraph)},
|
||||||
{Key: "beingDeleted", Value: fmt.Sprintf(`"%v"`, v.beingDeleted)},
|
{Key: "beingDeleted", Value: fmt.Sprintf(`%v`, v.beingDeleted)},
|
||||||
{Key: "deletingDependents", Value: fmt.Sprintf(`"%v"`, v.deletingDependents)},
|
{Key: "deletingDependents", Value: fmt.Sprintf(`%v`, v.deletingDependents)},
|
||||||
{Key: "virtual", Value: fmt.Sprintf(`"%v"`, v.virtual)},
|
{Key: "virtual", Value: fmt.Sprintf(`%v`, v.virtual)},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewGonumVertex creates a new gonumVertex.
|
// NewDOTVertex creates a new dotVertex.
|
||||||
func NewGonumVertex(node *node, nodeID int64) *gonumVertex {
|
func NewDOTVertex(node *node) *dotVertex {
|
||||||
gv, err := schema.ParseGroupVersion(node.identity.APIVersion)
|
gv, err := schema.ParseGroupVersion(node.identity.APIVersion)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// this indicates a bad data serialization that should be prevented during storage of the API
|
// this indicates a bad data serialization that should be prevented during storage of the API
|
||||||
utilruntime.HandleError(err)
|
utilruntime.HandleError(err)
|
||||||
}
|
}
|
||||||
return &gonumVertex{
|
return &dotVertex{
|
||||||
uid: node.identity.UID,
|
uid: node.identity.UID,
|
||||||
gvk: gv.WithKind(node.identity.Kind),
|
gvk: gv.WithKind(node.identity.Kind),
|
||||||
namespace: node.identity.Namespace,
|
namespace: node.identity.Namespace,
|
||||||
@@ -137,36 +151,46 @@ func NewGonumVertex(node *node, nodeID int64) *gonumVertex {
|
|||||||
beingDeleted: node.beingDeleted,
|
beingDeleted: node.beingDeleted,
|
||||||
deletingDependents: node.deletingDependents,
|
deletingDependents: node.deletingDependents,
|
||||||
virtual: node.virtual,
|
virtual: node.virtual,
|
||||||
vertexID: nodeID,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewMissingGonumVertex creates a new gonumVertex.
|
// NewMissingdotVertex creates a new dotVertex.
|
||||||
func NewMissingGonumVertex(ownerRef metav1.OwnerReference, nodeID int64) *gonumVertex {
|
func NewMissingdotVertex(ownerRef metav1.OwnerReference) *dotVertex {
|
||||||
gv, err := schema.ParseGroupVersion(ownerRef.APIVersion)
|
gv, err := schema.ParseGroupVersion(ownerRef.APIVersion)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// this indicates a bad data serialization that should be prevented during storage of the API
|
// this indicates a bad data serialization that should be prevented during storage of the API
|
||||||
utilruntime.HandleError(err)
|
utilruntime.HandleError(err)
|
||||||
}
|
}
|
||||||
return &gonumVertex{
|
return &dotVertex{
|
||||||
uid: ownerRef.UID,
|
uid: ownerRef.UID,
|
||||||
gvk: gv.WithKind(ownerRef.Kind),
|
gvk: gv.WithKind(ownerRef.Kind),
|
||||||
name: ownerRef.Name,
|
name: ownerRef.Name,
|
||||||
missingFromGraph: true,
|
missingFromGraph: true,
|
||||||
vertexID: nodeID,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *concurrentUIDToNode) ToGonumGraph() graph.Directed {
|
func (m *concurrentUIDToNode) ToDOTNodesAndEdges() ([]*dotVertex, []dotEdge) {
|
||||||
m.uidToNodeLock.Lock()
|
m.uidToNodeLock.Lock()
|
||||||
defer m.uidToNodeLock.Unlock()
|
defer m.uidToNodeLock.Unlock()
|
||||||
|
|
||||||
return toGonumGraph(m.uidToNode)
|
return toDOTNodesAndEdges(m.uidToNode)
|
||||||
}
|
}
|
||||||
|
|
||||||
func toGonumGraph(uidToNode map[types.UID]*node) graph.Directed {
|
type dotEdge struct {
|
||||||
uidToVertex := map[types.UID]*gonumVertex{}
|
F types.UID
|
||||||
graphBuilder := simple.NewDirectedGraph()
|
T types.UID
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e dotEdge) MarshalDOT(w io.Writer) error {
|
||||||
|
_, err := fmt.Fprintf(w, " %q -> %q;\n", e.F, e.T)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func toDOTNodesAndEdges(uidToNode map[types.UID]*node) ([]*dotVertex, []dotEdge) {
|
||||||
|
nodes := []*dotVertex{}
|
||||||
|
edges := []dotEdge{}
|
||||||
|
|
||||||
|
uidToVertex := map[types.UID]*dotVertex{}
|
||||||
|
|
||||||
// add the vertices first, then edges. That avoids having to deal with missing refs.
|
// add the vertices first, then edges. That avoids having to deal with missing refs.
|
||||||
for _, node := range uidToNode {
|
for _, node := range uidToNode {
|
||||||
@@ -174,38 +198,42 @@ func toGonumGraph(uidToNode map[types.UID]*node) graph.Directed {
|
|||||||
if len(node.dependents) == 0 && len(node.owners) == 0 {
|
if len(node.dependents) == 0 && len(node.owners) == 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
vertex := NewGonumVertex(node, graphBuilder.NewNode().ID())
|
vertex := NewDOTVertex(node)
|
||||||
uidToVertex[node.identity.UID] = vertex
|
uidToVertex[node.identity.UID] = vertex
|
||||||
graphBuilder.AddNode(vertex)
|
nodes = append(nodes, vertex)
|
||||||
}
|
}
|
||||||
for _, node := range uidToNode {
|
for _, node := range uidToNode {
|
||||||
currVertex := uidToVertex[node.identity.UID]
|
currVertex := uidToVertex[node.identity.UID]
|
||||||
for _, ownerRef := range node.owners {
|
for _, ownerRef := range node.owners {
|
||||||
currOwnerVertex, ok := uidToVertex[ownerRef.UID]
|
currOwnerVertex, ok := uidToVertex[ownerRef.UID]
|
||||||
if !ok {
|
if !ok {
|
||||||
currOwnerVertex = NewMissingGonumVertex(ownerRef, graphBuilder.NewNode().ID())
|
currOwnerVertex = NewMissingdotVertex(ownerRef)
|
||||||
uidToVertex[node.identity.UID] = currOwnerVertex
|
uidToVertex[node.identity.UID] = currOwnerVertex
|
||||||
graphBuilder.AddNode(currOwnerVertex)
|
nodes = append(nodes, currOwnerVertex)
|
||||||
}
|
}
|
||||||
graphBuilder.SetEdge(simple.Edge{
|
edges = append(edges, dotEdge{F: currVertex.uid, T: currOwnerVertex.uid})
|
||||||
F: currVertex,
|
|
||||||
T: currOwnerVertex,
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return graphBuilder
|
sort.SliceStable(nodes, func(i, j int) bool { return nodes[i].uid < nodes[j].uid })
|
||||||
|
sort.SliceStable(edges, func(i, j int) bool {
|
||||||
|
if edges[i].F != edges[j].F {
|
||||||
|
return edges[i].F < edges[j].F
|
||||||
|
}
|
||||||
|
return edges[i].T < edges[j].T
|
||||||
|
})
|
||||||
|
|
||||||
|
return nodes, edges
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *concurrentUIDToNode) ToGonumGraphForObj(uids ...types.UID) graph.Directed {
|
func (m *concurrentUIDToNode) ToDOTNodesAndEdgesForObj(uids ...types.UID) ([]*dotVertex, []dotEdge) {
|
||||||
m.uidToNodeLock.Lock()
|
m.uidToNodeLock.Lock()
|
||||||
defer m.uidToNodeLock.Unlock()
|
defer m.uidToNodeLock.Unlock()
|
||||||
|
|
||||||
return toGonumGraphForObj(m.uidToNode, uids...)
|
return toDOTNodesAndEdgesForObj(m.uidToNode, uids...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func toGonumGraphForObj(uidToNode map[types.UID]*node, uids ...types.UID) graph.Directed {
|
func toDOTNodesAndEdgesForObj(uidToNode map[types.UID]*node, uids ...types.UID) ([]*dotVertex, []dotEdge) {
|
||||||
uidsToCheck := append([]types.UID{}, uids...)
|
uidsToCheck := append([]types.UID{}, uids...)
|
||||||
interestingNodes := map[types.UID]*node{}
|
interestingNodes := map[types.UID]*node{}
|
||||||
|
|
||||||
@@ -241,7 +269,7 @@ func toGonumGraphForObj(uidToNode map[types.UID]*node, uids ...types.UID) graph.
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return toGonumGraph(interestingNodes)
|
return toDOTNodesAndEdges(interestingNodes)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDebugHandler creates a new debugHTTPHandler.
|
// NewDebugHandler creates a new debugHTTPHandler.
|
||||||
@@ -253,32 +281,64 @@ type debugHTTPHandler struct {
|
|||||||
controller *GarbageCollector
|
controller *GarbageCollector
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func marshalDOT(w io.Writer, nodes []*dotVertex, edges []dotEdge) error {
|
||||||
|
if _, err := w.Write([]byte("strict digraph full {\n")); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if len(nodes) > 0 {
|
||||||
|
if _, err := w.Write([]byte(" // Node definitions.\n")); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, node := range nodes {
|
||||||
|
if err := node.MarshalDOT(w); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(edges) > 0 {
|
||||||
|
if _, err := w.Write([]byte(" // Edge definitions.\n")); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, edge := range edges {
|
||||||
|
if err := edge.MarshalDOT(w); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if _, err := w.Write([]byte("}\n")); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (h *debugHTTPHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
func (h *debugHTTPHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
if req.URL.Path != "/graph" {
|
if req.URL.Path != "/graph" {
|
||||||
http.Error(w, "", http.StatusNotFound)
|
http.Error(w, "", http.StatusNotFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var graph graph.Directed
|
var nodes []*dotVertex
|
||||||
|
var edges []dotEdge
|
||||||
if uidStrings := req.URL.Query()["uid"]; len(uidStrings) > 0 {
|
if uidStrings := req.URL.Query()["uid"]; len(uidStrings) > 0 {
|
||||||
uids := []types.UID{}
|
uids := []types.UID{}
|
||||||
for _, uidString := range uidStrings {
|
for _, uidString := range uidStrings {
|
||||||
uids = append(uids, types.UID(uidString))
|
uids = append(uids, types.UID(uidString))
|
||||||
}
|
}
|
||||||
graph = h.controller.dependencyGraphBuilder.uidToNode.ToGonumGraphForObj(uids...)
|
nodes, edges = h.controller.dependencyGraphBuilder.uidToNode.ToDOTNodesAndEdgesForObj(uids...)
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
graph = h.controller.dependencyGraphBuilder.uidToNode.ToGonumGraph()
|
nodes, edges = h.controller.dependencyGraphBuilder.uidToNode.ToDOTNodesAndEdges()
|
||||||
}
|
}
|
||||||
|
|
||||||
data, err := dot.Marshal(graph, "full", "", " ")
|
b := bytes.NewBuffer(nil)
|
||||||
if err != nil {
|
if err := marshalDOT(b, nodes, edges); err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
w.Header().Set("Content-Type", "text/vnd.graphviz")
|
w.Header().Set("Content-Type", "text/vnd.graphviz")
|
||||||
w.Header().Set("X-Content-Type-Options", "nosniff")
|
w.Header().Set("X-Content-Type-Options", "nosniff")
|
||||||
w.Write(data)
|
w.Write(b.Bytes())
|
||||||
w.WriteHeader(http.StatusOK)
|
w.WriteHeader(http.StatusOK)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,12 +17,13 @@ limitations under the License.
|
|||||||
package garbagecollector
|
package garbagecollector
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"sort"
|
"bytes"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/davecgh/go-spew/spew"
|
"github.com/davecgh/go-spew/spew"
|
||||||
"gonum.org/v1/gonum/graph"
|
"github.com/google/go-cmp/cmp"
|
||||||
"gonum.org/v1/gonum/graph/simple"
|
|
||||||
|
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/types"
|
"k8s.io/apimachinery/pkg/types"
|
||||||
@@ -116,11 +117,12 @@ var (
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestToGonumGraph(t *testing.T) {
|
func TestToDOTGraph(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
uidToNode map[types.UID]*node
|
uidToNode map[types.UID]*node
|
||||||
expect graph.Directed
|
expectNodes []*dotVertex
|
||||||
|
expectEdges []dotEdge
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "simple",
|
name: "simple",
|
||||||
@@ -129,24 +131,15 @@ func TestToGonumGraph(t *testing.T) {
|
|||||||
types.UID("bravo"): bravoNode(),
|
types.UID("bravo"): bravoNode(),
|
||||||
types.UID("charlie"): charlieNode(),
|
types.UID("charlie"): charlieNode(),
|
||||||
},
|
},
|
||||||
expect: func() graph.Directed {
|
expectNodes: []*dotVertex{
|
||||||
graphBuilder := simple.NewDirectedGraph()
|
NewDOTVertex(alphaNode()),
|
||||||
alphaVertex := NewGonumVertex(alphaNode(), graphBuilder.NewNode().ID())
|
NewDOTVertex(bravoNode()),
|
||||||
graphBuilder.AddNode(alphaVertex)
|
NewDOTVertex(charlieNode()),
|
||||||
bravoVertex := NewGonumVertex(bravoNode(), graphBuilder.NewNode().ID())
|
},
|
||||||
graphBuilder.AddNode(bravoVertex)
|
expectEdges: []dotEdge{
|
||||||
charlieVertex := NewGonumVertex(charlieNode(), graphBuilder.NewNode().ID())
|
{F: types.UID("alpha"), T: types.UID("bravo")},
|
||||||
graphBuilder.AddNode(charlieVertex)
|
{F: types.UID("alpha"), T: types.UID("charlie")},
|
||||||
graphBuilder.SetEdge(simple.Edge{
|
},
|
||||||
F: alphaVertex,
|
|
||||||
T: bravoVertex,
|
|
||||||
})
|
|
||||||
graphBuilder.SetEdge(simple.Edge{
|
|
||||||
F: alphaVertex,
|
|
||||||
T: charlieVertex,
|
|
||||||
})
|
|
||||||
return graphBuilder
|
|
||||||
}(),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "missing", // synthetic vertex created
|
name: "missing", // synthetic vertex created
|
||||||
@@ -154,24 +147,15 @@ func TestToGonumGraph(t *testing.T) {
|
|||||||
types.UID("alpha"): alphaNode(),
|
types.UID("alpha"): alphaNode(),
|
||||||
types.UID("charlie"): charlieNode(),
|
types.UID("charlie"): charlieNode(),
|
||||||
},
|
},
|
||||||
expect: func() graph.Directed {
|
expectNodes: []*dotVertex{
|
||||||
graphBuilder := simple.NewDirectedGraph()
|
NewDOTVertex(alphaNode()),
|
||||||
alphaVertex := NewGonumVertex(alphaNode(), graphBuilder.NewNode().ID())
|
NewDOTVertex(bravoNode()),
|
||||||
graphBuilder.AddNode(alphaVertex)
|
NewDOTVertex(charlieNode()),
|
||||||
bravoVertex := NewGonumVertex(bravoNode(), graphBuilder.NewNode().ID())
|
},
|
||||||
graphBuilder.AddNode(bravoVertex)
|
expectEdges: []dotEdge{
|
||||||
charlieVertex := NewGonumVertex(charlieNode(), graphBuilder.NewNode().ID())
|
{F: types.UID("alpha"), T: types.UID("bravo")},
|
||||||
graphBuilder.AddNode(charlieVertex)
|
{F: types.UID("alpha"), T: types.UID("charlie")},
|
||||||
graphBuilder.SetEdge(simple.Edge{
|
},
|
||||||
F: alphaVertex,
|
|
||||||
T: bravoVertex,
|
|
||||||
})
|
|
||||||
graphBuilder.SetEdge(simple.Edge{
|
|
||||||
F: alphaVertex,
|
|
||||||
T: charlieVertex,
|
|
||||||
})
|
|
||||||
return graphBuilder
|
|
||||||
}(),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "drop-no-ref",
|
name: "drop-no-ref",
|
||||||
@@ -181,24 +165,15 @@ func TestToGonumGraph(t *testing.T) {
|
|||||||
types.UID("charlie"): charlieNode(),
|
types.UID("charlie"): charlieNode(),
|
||||||
types.UID("echo"): echoNode(),
|
types.UID("echo"): echoNode(),
|
||||||
},
|
},
|
||||||
expect: func() graph.Directed {
|
expectNodes: []*dotVertex{
|
||||||
graphBuilder := simple.NewDirectedGraph()
|
NewDOTVertex(alphaNode()),
|
||||||
alphaVertex := NewGonumVertex(alphaNode(), graphBuilder.NewNode().ID())
|
NewDOTVertex(bravoNode()),
|
||||||
graphBuilder.AddNode(alphaVertex)
|
NewDOTVertex(charlieNode()),
|
||||||
bravoVertex := NewGonumVertex(bravoNode(), graphBuilder.NewNode().ID())
|
},
|
||||||
graphBuilder.AddNode(bravoVertex)
|
expectEdges: []dotEdge{
|
||||||
charlieVertex := NewGonumVertex(charlieNode(), graphBuilder.NewNode().ID())
|
{F: types.UID("alpha"), T: types.UID("bravo")},
|
||||||
graphBuilder.AddNode(charlieVertex)
|
{F: types.UID("alpha"), T: types.UID("charlie")},
|
||||||
graphBuilder.SetEdge(simple.Edge{
|
},
|
||||||
F: alphaVertex,
|
|
||||||
T: bravoVertex,
|
|
||||||
})
|
|
||||||
graphBuilder.SetEdge(simple.Edge{
|
|
||||||
F: alphaVertex,
|
|
||||||
T: charlieVertex,
|
|
||||||
})
|
|
||||||
return graphBuilder
|
|
||||||
}(),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "two-chains",
|
name: "two-chains",
|
||||||
@@ -210,59 +185,38 @@ func TestToGonumGraph(t *testing.T) {
|
|||||||
types.UID("foxtrot"): foxtrotNode(),
|
types.UID("foxtrot"): foxtrotNode(),
|
||||||
types.UID("golf"): golfNode(),
|
types.UID("golf"): golfNode(),
|
||||||
},
|
},
|
||||||
expect: func() graph.Directed {
|
expectNodes: []*dotVertex{
|
||||||
graphBuilder := simple.NewDirectedGraph()
|
NewDOTVertex(alphaNode()),
|
||||||
alphaVertex := NewGonumVertex(alphaNode(), graphBuilder.NewNode().ID())
|
NewDOTVertex(bravoNode()),
|
||||||
graphBuilder.AddNode(alphaVertex)
|
NewDOTVertex(charlieNode()),
|
||||||
bravoVertex := NewGonumVertex(bravoNode(), graphBuilder.NewNode().ID())
|
NewDOTVertex(deltaNode()),
|
||||||
graphBuilder.AddNode(bravoVertex)
|
NewDOTVertex(foxtrotNode()),
|
||||||
charlieVertex := NewGonumVertex(charlieNode(), graphBuilder.NewNode().ID())
|
NewDOTVertex(golfNode()),
|
||||||
graphBuilder.AddNode(charlieVertex)
|
},
|
||||||
graphBuilder.SetEdge(simple.Edge{
|
expectEdges: []dotEdge{
|
||||||
F: alphaVertex,
|
{F: types.UID("alpha"), T: types.UID("bravo")},
|
||||||
T: bravoVertex,
|
{F: types.UID("alpha"), T: types.UID("charlie")},
|
||||||
})
|
{F: types.UID("delta"), T: types.UID("foxtrot")},
|
||||||
graphBuilder.SetEdge(simple.Edge{
|
{F: types.UID("foxtrot"), T: types.UID("golf")},
|
||||||
F: alphaVertex,
|
},
|
||||||
T: charlieVertex,
|
|
||||||
})
|
|
||||||
|
|
||||||
deltaVertex := NewGonumVertex(deltaNode(), graphBuilder.NewNode().ID())
|
|
||||||
graphBuilder.AddNode(deltaVertex)
|
|
||||||
foxtrotVertex := NewGonumVertex(foxtrotNode(), graphBuilder.NewNode().ID())
|
|
||||||
graphBuilder.AddNode(foxtrotVertex)
|
|
||||||
golfVertex := NewGonumVertex(golfNode(), graphBuilder.NewNode().ID())
|
|
||||||
graphBuilder.AddNode(golfVertex)
|
|
||||||
graphBuilder.SetEdge(simple.Edge{
|
|
||||||
F: deltaVertex,
|
|
||||||
T: foxtrotVertex,
|
|
||||||
})
|
|
||||||
graphBuilder.SetEdge(simple.Edge{
|
|
||||||
F: foxtrotVertex,
|
|
||||||
T: golfVertex,
|
|
||||||
})
|
|
||||||
|
|
||||||
return graphBuilder
|
|
||||||
}(),
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
t.Run(test.name, func(t *testing.T) {
|
t.Run(test.name, func(t *testing.T) {
|
||||||
actual := toGonumGraph(test.uidToNode)
|
actualNodes, actualEdges := toDOTNodesAndEdges(test.uidToNode)
|
||||||
|
compareGraphs(test.expectNodes, actualNodes, test.expectEdges, actualEdges, t)
|
||||||
compareGraphs(test.expect, actual, t)
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestToGonumGraphObj(t *testing.T) {
|
func TestToDOTGraphObj(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
uidToNode map[types.UID]*node
|
uidToNode map[types.UID]*node
|
||||||
uids []types.UID
|
uids []types.UID
|
||||||
expect graph.Directed
|
expectNodes []*dotVertex
|
||||||
|
expectEdges []dotEdge
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "simple",
|
name: "simple",
|
||||||
@@ -272,24 +226,15 @@ func TestToGonumGraphObj(t *testing.T) {
|
|||||||
types.UID("charlie"): charlieNode(),
|
types.UID("charlie"): charlieNode(),
|
||||||
},
|
},
|
||||||
uids: []types.UID{types.UID("bravo")},
|
uids: []types.UID{types.UID("bravo")},
|
||||||
expect: func() graph.Directed {
|
expectNodes: []*dotVertex{
|
||||||
graphBuilder := simple.NewDirectedGraph()
|
NewDOTVertex(alphaNode()),
|
||||||
alphaVertex := NewGonumVertex(alphaNode(), graphBuilder.NewNode().ID())
|
NewDOTVertex(bravoNode()),
|
||||||
graphBuilder.AddNode(alphaVertex)
|
NewDOTVertex(charlieNode()),
|
||||||
bravoVertex := NewGonumVertex(bravoNode(), graphBuilder.NewNode().ID())
|
},
|
||||||
graphBuilder.AddNode(bravoVertex)
|
expectEdges: []dotEdge{
|
||||||
charlieVertex := NewGonumVertex(charlieNode(), graphBuilder.NewNode().ID())
|
{F: types.UID("alpha"), T: types.UID("bravo")},
|
||||||
graphBuilder.AddNode(charlieVertex)
|
{F: types.UID("alpha"), T: types.UID("charlie")},
|
||||||
graphBuilder.SetEdge(simple.Edge{
|
},
|
||||||
F: alphaVertex,
|
|
||||||
T: bravoVertex,
|
|
||||||
})
|
|
||||||
graphBuilder.SetEdge(simple.Edge{
|
|
||||||
F: alphaVertex,
|
|
||||||
T: charlieVertex,
|
|
||||||
})
|
|
||||||
return graphBuilder
|
|
||||||
}(),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "missing", // synthetic vertex created
|
name: "missing", // synthetic vertex created
|
||||||
@@ -297,11 +242,9 @@ func TestToGonumGraphObj(t *testing.T) {
|
|||||||
types.UID("alpha"): alphaNode(),
|
types.UID("alpha"): alphaNode(),
|
||||||
types.UID("charlie"): charlieNode(),
|
types.UID("charlie"): charlieNode(),
|
||||||
},
|
},
|
||||||
uids: []types.UID{types.UID("bravo")},
|
uids: []types.UID{types.UID("bravo")},
|
||||||
expect: func() graph.Directed {
|
expectNodes: []*dotVertex{},
|
||||||
graphBuilder := simple.NewDirectedGraph()
|
expectEdges: []dotEdge{},
|
||||||
return graphBuilder
|
|
||||||
}(),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "drop-no-ref",
|
name: "drop-no-ref",
|
||||||
@@ -311,11 +254,9 @@ func TestToGonumGraphObj(t *testing.T) {
|
|||||||
types.UID("charlie"): charlieNode(),
|
types.UID("charlie"): charlieNode(),
|
||||||
types.UID("echo"): echoNode(),
|
types.UID("echo"): echoNode(),
|
||||||
},
|
},
|
||||||
uids: []types.UID{types.UID("echo")},
|
uids: []types.UID{types.UID("echo")},
|
||||||
expect: func() graph.Directed {
|
expectNodes: []*dotVertex{},
|
||||||
graphBuilder := simple.NewDirectedGraph()
|
expectEdges: []dotEdge{},
|
||||||
return graphBuilder
|
|
||||||
}(),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "two-chains-from-owner",
|
name: "two-chains-from-owner",
|
||||||
@@ -328,25 +269,15 @@ func TestToGonumGraphObj(t *testing.T) {
|
|||||||
types.UID("golf"): golfNode(),
|
types.UID("golf"): golfNode(),
|
||||||
},
|
},
|
||||||
uids: []types.UID{types.UID("golf")},
|
uids: []types.UID{types.UID("golf")},
|
||||||
expect: func() graph.Directed {
|
expectNodes: []*dotVertex{
|
||||||
graphBuilder := simple.NewDirectedGraph()
|
NewDOTVertex(deltaNode()),
|
||||||
deltaVertex := NewGonumVertex(deltaNode(), graphBuilder.NewNode().ID())
|
NewDOTVertex(foxtrotNode()),
|
||||||
graphBuilder.AddNode(deltaVertex)
|
NewDOTVertex(golfNode()),
|
||||||
foxtrotVertex := NewGonumVertex(foxtrotNode(), graphBuilder.NewNode().ID())
|
},
|
||||||
graphBuilder.AddNode(foxtrotVertex)
|
expectEdges: []dotEdge{
|
||||||
golfVertex := NewGonumVertex(golfNode(), graphBuilder.NewNode().ID())
|
{F: types.UID("delta"), T: types.UID("foxtrot")},
|
||||||
graphBuilder.AddNode(golfVertex)
|
{F: types.UID("foxtrot"), T: types.UID("golf")},
|
||||||
graphBuilder.SetEdge(simple.Edge{
|
},
|
||||||
F: deltaVertex,
|
|
||||||
T: foxtrotVertex,
|
|
||||||
})
|
|
||||||
graphBuilder.SetEdge(simple.Edge{
|
|
||||||
F: foxtrotVertex,
|
|
||||||
T: golfVertex,
|
|
||||||
})
|
|
||||||
|
|
||||||
return graphBuilder
|
|
||||||
}(),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "two-chains-from-child",
|
name: "two-chains-from-child",
|
||||||
@@ -359,25 +290,15 @@ func TestToGonumGraphObj(t *testing.T) {
|
|||||||
types.UID("golf"): golfNode(),
|
types.UID("golf"): golfNode(),
|
||||||
},
|
},
|
||||||
uids: []types.UID{types.UID("delta")},
|
uids: []types.UID{types.UID("delta")},
|
||||||
expect: func() graph.Directed {
|
expectNodes: []*dotVertex{
|
||||||
graphBuilder := simple.NewDirectedGraph()
|
NewDOTVertex(deltaNode()),
|
||||||
deltaVertex := NewGonumVertex(deltaNode(), graphBuilder.NewNode().ID())
|
NewDOTVertex(foxtrotNode()),
|
||||||
graphBuilder.AddNode(deltaVertex)
|
NewDOTVertex(golfNode()),
|
||||||
foxtrotVertex := NewGonumVertex(foxtrotNode(), graphBuilder.NewNode().ID())
|
},
|
||||||
graphBuilder.AddNode(foxtrotVertex)
|
expectEdges: []dotEdge{
|
||||||
golfVertex := NewGonumVertex(golfNode(), graphBuilder.NewNode().ID())
|
{F: types.UID("delta"), T: types.UID("foxtrot")},
|
||||||
graphBuilder.AddNode(golfVertex)
|
{F: types.UID("foxtrot"), T: types.UID("golf")},
|
||||||
graphBuilder.SetEdge(simple.Edge{
|
},
|
||||||
F: deltaVertex,
|
|
||||||
T: foxtrotVertex,
|
|
||||||
})
|
|
||||||
graphBuilder.SetEdge(simple.Edge{
|
|
||||||
F: foxtrotVertex,
|
|
||||||
T: golfVertex,
|
|
||||||
})
|
|
||||||
|
|
||||||
return graphBuilder
|
|
||||||
}(),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "two-chains-choose-both",
|
name: "two-chains-choose-both",
|
||||||
@@ -390,98 +311,125 @@ func TestToGonumGraphObj(t *testing.T) {
|
|||||||
types.UID("golf"): golfNode(),
|
types.UID("golf"): golfNode(),
|
||||||
},
|
},
|
||||||
uids: []types.UID{types.UID("delta"), types.UID("charlie")},
|
uids: []types.UID{types.UID("delta"), types.UID("charlie")},
|
||||||
expect: func() graph.Directed {
|
expectNodes: []*dotVertex{
|
||||||
graphBuilder := simple.NewDirectedGraph()
|
NewDOTVertex(alphaNode()),
|
||||||
alphaVertex := NewGonumVertex(alphaNode(), graphBuilder.NewNode().ID())
|
NewDOTVertex(bravoNode()),
|
||||||
graphBuilder.AddNode(alphaVertex)
|
NewDOTVertex(charlieNode()),
|
||||||
bravoVertex := NewGonumVertex(bravoNode(), graphBuilder.NewNode().ID())
|
NewDOTVertex(deltaNode()),
|
||||||
graphBuilder.AddNode(bravoVertex)
|
NewDOTVertex(foxtrotNode()),
|
||||||
charlieVertex := NewGonumVertex(charlieNode(), graphBuilder.NewNode().ID())
|
NewDOTVertex(golfNode()),
|
||||||
graphBuilder.AddNode(charlieVertex)
|
},
|
||||||
graphBuilder.SetEdge(simple.Edge{
|
expectEdges: []dotEdge{
|
||||||
F: alphaVertex,
|
{F: types.UID("alpha"), T: types.UID("bravo")},
|
||||||
T: bravoVertex,
|
{F: types.UID("alpha"), T: types.UID("charlie")},
|
||||||
})
|
{F: types.UID("delta"), T: types.UID("foxtrot")},
|
||||||
graphBuilder.SetEdge(simple.Edge{
|
{F: types.UID("foxtrot"), T: types.UID("golf")},
|
||||||
F: alphaVertex,
|
},
|
||||||
T: charlieVertex,
|
|
||||||
})
|
|
||||||
|
|
||||||
deltaVertex := NewGonumVertex(deltaNode(), graphBuilder.NewNode().ID())
|
|
||||||
graphBuilder.AddNode(deltaVertex)
|
|
||||||
foxtrotVertex := NewGonumVertex(foxtrotNode(), graphBuilder.NewNode().ID())
|
|
||||||
graphBuilder.AddNode(foxtrotVertex)
|
|
||||||
golfVertex := NewGonumVertex(golfNode(), graphBuilder.NewNode().ID())
|
|
||||||
graphBuilder.AddNode(golfVertex)
|
|
||||||
graphBuilder.SetEdge(simple.Edge{
|
|
||||||
F: deltaVertex,
|
|
||||||
T: foxtrotVertex,
|
|
||||||
})
|
|
||||||
graphBuilder.SetEdge(simple.Edge{
|
|
||||||
F: foxtrotVertex,
|
|
||||||
T: golfVertex,
|
|
||||||
})
|
|
||||||
|
|
||||||
return graphBuilder
|
|
||||||
}(),
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
t.Run(test.name, func(t *testing.T) {
|
t.Run(test.name, func(t *testing.T) {
|
||||||
actual := toGonumGraphForObj(test.uidToNode, test.uids...)
|
actualNodes, actualEdges := toDOTNodesAndEdgesForObj(test.uidToNode, test.uids...)
|
||||||
|
compareGraphs(test.expectNodes, actualNodes, test.expectEdges, actualEdges, t)
|
||||||
compareGraphs(test.expect, actual, t)
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func compareGraphs(expected, actual graph.Directed, t *testing.T) {
|
func compareGraphs(expectedNodes, actualNodes []*dotVertex, expectedEdges, actualEdges []dotEdge, t *testing.T) {
|
||||||
// sort the edges by from ID, then to ID
|
|
||||||
// (the slices we get back are from map iteration, where order is not guaranteed)
|
|
||||||
expectedNodes := expected.Nodes().(graph.NodeSlicer).NodeSlice()
|
|
||||||
actualNodes := actual.Nodes().(graph.NodeSlicer).NodeSlice()
|
|
||||||
sort.Sort(gonumByUID(expectedNodes))
|
|
||||||
sort.Sort(gonumByUID(actualNodes))
|
|
||||||
|
|
||||||
if len(expectedNodes) != len(actualNodes) {
|
if len(expectedNodes) != len(actualNodes) {
|
||||||
t.Fatal(spew.Sdump(actual))
|
t.Fatal(spew.Sdump(actualNodes))
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := range expectedNodes {
|
for i := range expectedNodes {
|
||||||
currExpected := *expectedNodes[i].(*gonumVertex)
|
currExpected := expectedNodes[i]
|
||||||
currActual := *actualNodes[i].(*gonumVertex)
|
currActual := actualNodes[i]
|
||||||
if currExpected.uid != currActual.uid {
|
if currExpected.uid != currActual.uid {
|
||||||
t.Errorf("expected %v, got %v", spew.Sdump(currExpected), spew.Sdump(currActual))
|
t.Errorf("expected %v, got %v", spew.Sdump(currExpected), spew.Sdump(currActual))
|
||||||
}
|
}
|
||||||
|
}
|
||||||
expectedFrom := append([]graph.Node{}, expected.From(expectedNodes[i].ID()).(graph.NodeSlicer).NodeSlice()...)
|
if len(expectedEdges) != len(actualEdges) {
|
||||||
actualFrom := append([]graph.Node{}, actual.From(actualNodes[i].ID()).(graph.NodeSlicer).NodeSlice()...)
|
t.Fatal(spew.Sdump(actualEdges))
|
||||||
sort.Sort(gonumByUID(expectedFrom))
|
}
|
||||||
sort.Sort(gonumByUID(actualFrom))
|
for i := range expectedEdges {
|
||||||
if len(expectedFrom) != len(actualFrom) {
|
currExpected := expectedEdges[i]
|
||||||
t.Errorf("%q: expected %v, got %v", currExpected.uid, spew.Sdump(expectedFrom), spew.Sdump(actualFrom))
|
currActual := actualEdges[i]
|
||||||
}
|
if currExpected != currActual {
|
||||||
for i := range expectedFrom {
|
t.Errorf("expected %v, got %v", spew.Sdump(currExpected), spew.Sdump(currActual))
|
||||||
currExpectedFrom := *expectedFrom[i].(*gonumVertex)
|
|
||||||
currActualFrom := *actualFrom[i].(*gonumVertex)
|
|
||||||
if currExpectedFrom.uid != currActualFrom.uid {
|
|
||||||
t.Errorf("expected %v, got %v", spew.Sdump(currExpectedFrom), spew.Sdump(currActualFrom))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type gonumByUID []graph.Node
|
func TestMarshalDOT(t *testing.T) {
|
||||||
|
ref1 := objectReference{
|
||||||
|
OwnerReference: metav1.OwnerReference{
|
||||||
|
UID: types.UID("ref1-[]\"\\Iñtërnâtiônàlizætiøn,🐹"),
|
||||||
|
Name: "ref1name-Iñtërnâtiônàlizætiøn,🐹",
|
||||||
|
Kind: "ref1kind-Iñtërnâtiônàlizætiøn,🐹",
|
||||||
|
APIVersion: "ref1group/version",
|
||||||
|
},
|
||||||
|
Namespace: "ref1ns",
|
||||||
|
}
|
||||||
|
ref2 := objectReference{
|
||||||
|
OwnerReference: metav1.OwnerReference{
|
||||||
|
UID: types.UID("ref2-"),
|
||||||
|
Name: "ref2name-",
|
||||||
|
Kind: "ref2kind-",
|
||||||
|
APIVersion: "ref2group/version",
|
||||||
|
},
|
||||||
|
Namespace: "ref2ns",
|
||||||
|
}
|
||||||
|
testcases := []struct {
|
||||||
|
file string
|
||||||
|
nodes []*dotVertex
|
||||||
|
edges []dotEdge
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
file: "empty.dot",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
file: "simple.dot",
|
||||||
|
nodes: []*dotVertex{
|
||||||
|
NewDOTVertex(alphaNode()),
|
||||||
|
NewDOTVertex(bravoNode()),
|
||||||
|
NewDOTVertex(charlieNode()),
|
||||||
|
NewDOTVertex(deltaNode()),
|
||||||
|
NewDOTVertex(foxtrotNode()),
|
||||||
|
NewDOTVertex(golfNode()),
|
||||||
|
},
|
||||||
|
edges: []dotEdge{
|
||||||
|
{F: types.UID("alpha"), T: types.UID("bravo")},
|
||||||
|
{F: types.UID("alpha"), T: types.UID("charlie")},
|
||||||
|
{F: types.UID("delta"), T: types.UID("foxtrot")},
|
||||||
|
{F: types.UID("foxtrot"), T: types.UID("golf")},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
file: "escaping.dot",
|
||||||
|
nodes: []*dotVertex{
|
||||||
|
NewDOTVertex(makeNode(ref1, withOwners(ref2))),
|
||||||
|
NewDOTVertex(makeNode(ref2)),
|
||||||
|
},
|
||||||
|
edges: []dotEdge{
|
||||||
|
{F: types.UID(ref1.UID), T: types.UID(ref2.UID)},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
func (s gonumByUID) Len() int { return len(s) }
|
for _, tc := range testcases {
|
||||||
func (s gonumByUID) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
t.Run(tc.file, func(t *testing.T) {
|
||||||
|
goldenData, err := os.ReadFile(filepath.Join("testdata", tc.file))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
b := bytes.NewBuffer(nil)
|
||||||
|
if err := marshalDOT(b, tc.nodes, tc.edges); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
func (s gonumByUID) Less(i, j int) bool {
|
if e, a := string(goldenData), string(b.Bytes()); cmp.Diff(e, a) != "" {
|
||||||
lhs := s[i].(*gonumVertex)
|
t.Logf("got\n%s", string(a))
|
||||||
lhsUID := string(lhs.uid)
|
t.Fatalf("unexpected diff:\n%s", cmp.Diff(e, a))
|
||||||
rhs := s[j].(*gonumVertex)
|
}
|
||||||
rhsUID := string(rhs.uid)
|
})
|
||||||
|
}
|
||||||
return lhsUID < rhsUID
|
|
||||||
}
|
}
|
||||||
|
|||||||
2
pkg/controller/garbagecollector/testdata/empty.dot
vendored
Normal file
2
pkg/controller/garbagecollector/testdata/empty.dot
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
strict digraph full {
|
||||||
|
}
|
||||||
31
pkg/controller/garbagecollector/testdata/escaping.dot
vendored
Normal file
31
pkg/controller/garbagecollector/testdata/escaping.dot
vendored
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
strict digraph full {
|
||||||
|
// Node definitions.
|
||||||
|
"ref1-[]\"\\Iñtërnâtiônàlizætiøn,🐹" [
|
||||||
|
label="uid=ref1-[]\"\\Iñtërnâtiônàlizætiøn,🐹\nnamespace=ref1ns\nref1kind-Iñtërnâtiônàlizætiøn,🐹.version.ref1group/ref1name-Iñtërnâtiônàlizætiøn,🐹\n"
|
||||||
|
group="ref1group"
|
||||||
|
version="version"
|
||||||
|
kind="ref1kind-Iñtërnâtiônàlizætiøn,🐹"
|
||||||
|
namespace="ref1ns"
|
||||||
|
name="ref1name-Iñtërnâtiônàlizætiøn,🐹"
|
||||||
|
uid="ref1-[]\"\\Iñtërnâtiônàlizætiøn,🐹"
|
||||||
|
missing="false"
|
||||||
|
beingDeleted="false"
|
||||||
|
deletingDependents="false"
|
||||||
|
virtual="false"
|
||||||
|
];
|
||||||
|
"ref2-" [
|
||||||
|
label="uid=ref2-\nnamespace=ref2ns\nref2kind-.version.ref2group/ref2name-\n"
|
||||||
|
group="ref2group"
|
||||||
|
version="version"
|
||||||
|
kind="ref2kind-"
|
||||||
|
namespace="ref2ns"
|
||||||
|
name="ref2name-"
|
||||||
|
uid="ref2-"
|
||||||
|
missing="false"
|
||||||
|
beingDeleted="false"
|
||||||
|
deletingDependents="false"
|
||||||
|
virtual="false"
|
||||||
|
];
|
||||||
|
// Edge definitions.
|
||||||
|
"ref1-[]\"\\Iñtërnâtiônàlizætiøn,🐹" -> "ref2-";
|
||||||
|
}
|
||||||
86
pkg/controller/garbagecollector/testdata/simple.dot
vendored
Normal file
86
pkg/controller/garbagecollector/testdata/simple.dot
vendored
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
strict digraph full {
|
||||||
|
// Node definitions.
|
||||||
|
"alpha" [
|
||||||
|
label="uid=alpha\nnamespace=\n./\n"
|
||||||
|
group=""
|
||||||
|
version=""
|
||||||
|
kind=""
|
||||||
|
namespace=""
|
||||||
|
name=""
|
||||||
|
uid="alpha"
|
||||||
|
missing="false"
|
||||||
|
beingDeleted="false"
|
||||||
|
deletingDependents="false"
|
||||||
|
virtual="false"
|
||||||
|
];
|
||||||
|
"bravo" [
|
||||||
|
label="uid=bravo\nnamespace=\n./\n"
|
||||||
|
group=""
|
||||||
|
version=""
|
||||||
|
kind=""
|
||||||
|
namespace=""
|
||||||
|
name=""
|
||||||
|
uid="bravo"
|
||||||
|
missing="false"
|
||||||
|
beingDeleted="false"
|
||||||
|
deletingDependents="false"
|
||||||
|
virtual="false"
|
||||||
|
];
|
||||||
|
"charlie" [
|
||||||
|
label="uid=charlie\nnamespace=\n./\n"
|
||||||
|
group=""
|
||||||
|
version=""
|
||||||
|
kind=""
|
||||||
|
namespace=""
|
||||||
|
name=""
|
||||||
|
uid="charlie"
|
||||||
|
missing="false"
|
||||||
|
beingDeleted="false"
|
||||||
|
deletingDependents="false"
|
||||||
|
virtual="false"
|
||||||
|
];
|
||||||
|
"delta" [
|
||||||
|
label="uid=delta\nnamespace=\n./\n"
|
||||||
|
group=""
|
||||||
|
version=""
|
||||||
|
kind=""
|
||||||
|
namespace=""
|
||||||
|
name=""
|
||||||
|
uid="delta"
|
||||||
|
missing="false"
|
||||||
|
beingDeleted="false"
|
||||||
|
deletingDependents="false"
|
||||||
|
virtual="false"
|
||||||
|
];
|
||||||
|
"foxtrot" [
|
||||||
|
label="uid=foxtrot\nnamespace=\n./\n"
|
||||||
|
group=""
|
||||||
|
version=""
|
||||||
|
kind=""
|
||||||
|
namespace=""
|
||||||
|
name=""
|
||||||
|
uid="foxtrot"
|
||||||
|
missing="false"
|
||||||
|
beingDeleted="false"
|
||||||
|
deletingDependents="false"
|
||||||
|
virtual="false"
|
||||||
|
];
|
||||||
|
"golf" [
|
||||||
|
label="uid=golf\nnamespace=\n./\n"
|
||||||
|
group=""
|
||||||
|
version=""
|
||||||
|
kind=""
|
||||||
|
namespace=""
|
||||||
|
name=""
|
||||||
|
uid="golf"
|
||||||
|
missing="false"
|
||||||
|
beingDeleted="false"
|
||||||
|
deletingDependents="false"
|
||||||
|
virtual="false"
|
||||||
|
];
|
||||||
|
// Edge definitions.
|
||||||
|
"alpha" -> "bravo";
|
||||||
|
"alpha" -> "charlie";
|
||||||
|
"delta" -> "foxtrot";
|
||||||
|
"foxtrot" -> "golf";
|
||||||
|
}
|
||||||
97
vendor/gonum.org/v1/gonum/AUTHORS
generated
vendored
97
vendor/gonum.org/v1/gonum/AUTHORS
generated
vendored
@@ -1,97 +0,0 @@
|
|||||||
# This is the official list of gonum authors for copyright purposes.
|
|
||||||
# This file is distinct from the CONTRIBUTORS files.
|
|
||||||
# See the latter for an explanation.
|
|
||||||
|
|
||||||
# Names should be added to this file as
|
|
||||||
# Name or Organization <email address>
|
|
||||||
# The email address is not required for organizations.
|
|
||||||
|
|
||||||
# Please keep the list sorted.
|
|
||||||
|
|
||||||
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>
|
|
||||||
Dario Heinisch <dario.heinisch@gmail.com>
|
|
||||||
David Kleiven <davidkleiven446@gmail.com>
|
|
||||||
David Samborski <bloggingarrow@gmail.com>
|
|
||||||
Davor Kapsa <davor.kapsa@gmail.com>
|
|
||||||
DeepMind Technologies
|
|
||||||
Delaney Gillilan <delaneygillilan@gmail.com>
|
|
||||||
Dezmond Goff <goff.dezmond@gmail.com>
|
|
||||||
Dong-hee Na <donghee.na92@gmail.com>
|
|
||||||
Egon Elbre <egonelbre@gmail.com>
|
|
||||||
Ekaterina Efimova <katerina.efimova@gmail.com>
|
|
||||||
Ethan Burns <burns.ethan@gmail.com>
|
|
||||||
Evert Lammerts <evert.lammerts@gmail.com>
|
|
||||||
Facundo Gaich <facugaich@gmail.com>
|
|
||||||
Fazlul Shahriar <fshahriar@gmail.com>
|
|
||||||
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>
|
|
||||||
James Holmes <32bitkid@gmail.com>
|
|
||||||
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 Reiter <jonreiter@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>
|
|
||||||
Nathan Edwards <etaoinshrdluwho@gmail.com>
|
|
||||||
Nick Potts <nick@the-potts.com>
|
|
||||||
Nils Wogatzky <odog@netcologne.de>
|
|
||||||
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>
|
|
||||||
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>
|
|
||||||
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>
|
|
||||||
Yucheng Zhu <zyctc000@gmail.com>
|
|
||||||
99
vendor/gonum.org/v1/gonum/CONTRIBUTORS
generated
vendored
99
vendor/gonum.org/v1/gonum/CONTRIBUTORS
generated
vendored
@@ -1,99 +0,0 @@
|
|||||||
# This is the official list of people who can contribute
|
|
||||||
# (and typically have contributed) code to the gonum
|
|
||||||
# repository.
|
|
||||||
#
|
|
||||||
# The AUTHORS file lists the copyright holders; this file
|
|
||||||
# lists people. For example, Google employees would be listed here
|
|
||||||
# but not in AUTHORS, because Google would hold the copyright.
|
|
||||||
#
|
|
||||||
# When adding J Random Contributor's name to this file,
|
|
||||||
# either J's name or J's organization's name should be
|
|
||||||
# added to the AUTHORS file.
|
|
||||||
#
|
|
||||||
# Names should be added to this file like so:
|
|
||||||
# Name <email address>
|
|
||||||
#
|
|
||||||
# Please keep the list sorted.
|
|
||||||
|
|
||||||
Alexander Egurnov <alexander.egurnov@gmail.com>
|
|
||||||
Andrew Brampton <brampton@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>
|
|
||||||
Dario Heinisch <dario.heinisch@gmail.com>
|
|
||||||
David Kleiven <davidkleiven446@gmail.com>
|
|
||||||
David Samborski <bloggingarrow@gmail.com>
|
|
||||||
Davor Kapsa <davor.kapsa@gmail.com>
|
|
||||||
Delaney Gillilan <delaneygillilan@gmail.com>
|
|
||||||
Dezmond Goff <goff.dezmond@gmail.com>
|
|
||||||
Dong-hee Na <donghee.na92@gmail.com>
|
|
||||||
Egon Elbre <egonelbre@gmail.com>
|
|
||||||
Ekaterina Efimova <katerina.efimova@gmail.com>
|
|
||||||
Ethan Burns <burns.ethan@gmail.com>
|
|
||||||
Evert Lammerts <evert.lammerts@gmail.com>
|
|
||||||
Facundo Gaich <facugaich@gmail.com>
|
|
||||||
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>
|
|
||||||
James Holmes <32bitkid@gmail.com>
|
|
||||||
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 Reiter <jonreiter@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>
|
|
||||||
Nathan Edwards <etaoinshrdluwho@gmail.com>
|
|
||||||
Nick Potts <nick@the-potts.com>
|
|
||||||
Nils Wogatzky <odog@netcologne.de>
|
|
||||||
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>
|
|
||||||
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>
|
|
||||||
Yucheng Zhu <zyctc000@gmail.com>
|
|
||||||
23
vendor/gonum.org/v1/gonum/LICENSE
generated
vendored
23
vendor/gonum.org/v1/gonum/LICENSE
generated
vendored
@@ -1,23 +0,0 @@
|
|||||||
Copyright ©2013 The Gonum Authors. All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions are met:
|
|
||||||
* Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
* Redistributions in binary form must reproduce the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer in the
|
|
||||||
documentation and/or other materials provided with the distribution.
|
|
||||||
* Neither the name of the gonum project nor the names of its authors and
|
|
||||||
contributors may be used to endorse or promote products derived from this
|
|
||||||
software without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
||||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
||||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
||||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
||||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
||||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
||||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
47
vendor/gonum.org/v1/gonum/blas/README.md
generated
vendored
47
vendor/gonum.org/v1/gonum/blas/README.md
generated
vendored
@@ -1,47 +0,0 @@
|
|||||||
# Gonum BLAS [](https://godoc.org/gonum.org/v1/gonum/blas)
|
|
||||||
|
|
||||||
A collection of packages to provide BLAS functionality for the [Go programming
|
|
||||||
language](http://golang.org)
|
|
||||||
|
|
||||||
## Installation
|
|
||||||
```sh
|
|
||||||
go get gonum.org/v1/gonum/blas/...
|
|
||||||
```
|
|
||||||
|
|
||||||
## Packages
|
|
||||||
|
|
||||||
### blas
|
|
||||||
|
|
||||||
Defines [BLAS API](http://www.netlib.org/blas/blast-forum/cinterface.pdf) split in several
|
|
||||||
interfaces.
|
|
||||||
|
|
||||||
### blas/gonum
|
|
||||||
|
|
||||||
Go implementation of the BLAS API (incomplete, implements the `float32` and `float64` API).
|
|
||||||
|
|
||||||
### blas/blas64 and blas/blas32
|
|
||||||
|
|
||||||
Wrappers for an implementation of the double (i.e., `float64`) and single (`float32`)
|
|
||||||
precision real parts of the BLAS API.
|
|
||||||
|
|
||||||
```Go
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"gonum.org/v1/gonum/blas/blas64"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
v := blas64.Vector{Inc: 1, Data: []float64{1, 1, 1}}
|
|
||||||
fmt.Println("v has length:", blas64.Nrm2(len(v.Data), v))
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### blas/cblas128 and blas/cblas64
|
|
||||||
|
|
||||||
Wrappers for an implementation of the double (i.e., `complex128`) and single (`complex64`)
|
|
||||||
precision complex parts of the blas API.
|
|
||||||
|
|
||||||
Currently blas/cblas64 and blas/cblas128 require gonum.org/v1/netlib/blas.
|
|
||||||
283
vendor/gonum.org/v1/gonum/blas/blas.go
generated
vendored
283
vendor/gonum.org/v1/gonum/blas/blas.go
generated
vendored
@@ -1,283 +0,0 @@
|
|||||||
// Copyright ©2013 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.
|
|
||||||
|
|
||||||
//go:generate ./conversions.bash
|
|
||||||
|
|
||||||
package blas
|
|
||||||
|
|
||||||
// Flag constants indicate Givens transformation H matrix state.
|
|
||||||
type Flag int
|
|
||||||
|
|
||||||
const (
|
|
||||||
Identity Flag = -2 // H is the identity matrix; no rotation is needed.
|
|
||||||
Rescaling Flag = -1 // H specifies rescaling.
|
|
||||||
OffDiagonal Flag = 0 // Off-diagonal elements of H are non-unit.
|
|
||||||
Diagonal Flag = 1 // Diagonal elements of H are non-unit.
|
|
||||||
)
|
|
||||||
|
|
||||||
// SrotmParams contains Givens transformation parameters returned
|
|
||||||
// by the Float32 Srotm method.
|
|
||||||
type SrotmParams struct {
|
|
||||||
Flag
|
|
||||||
H [4]float32 // Column-major 2 by 2 matrix.
|
|
||||||
}
|
|
||||||
|
|
||||||
// DrotmParams contains Givens transformation parameters returned
|
|
||||||
// by the Float64 Drotm method.
|
|
||||||
type DrotmParams struct {
|
|
||||||
Flag
|
|
||||||
H [4]float64 // Column-major 2 by 2 matrix.
|
|
||||||
}
|
|
||||||
|
|
||||||
// Transpose specifies the transposition operation of a matrix.
|
|
||||||
type Transpose byte
|
|
||||||
|
|
||||||
const (
|
|
||||||
NoTrans Transpose = 'N'
|
|
||||||
Trans Transpose = 'T'
|
|
||||||
ConjTrans Transpose = 'C'
|
|
||||||
)
|
|
||||||
|
|
||||||
// Uplo specifies whether a matrix is upper or lower triangular.
|
|
||||||
type Uplo byte
|
|
||||||
|
|
||||||
const (
|
|
||||||
Upper Uplo = 'U'
|
|
||||||
Lower Uplo = 'L'
|
|
||||||
All Uplo = 'A'
|
|
||||||
)
|
|
||||||
|
|
||||||
// Diag specifies whether a matrix is unit triangular.
|
|
||||||
type Diag byte
|
|
||||||
|
|
||||||
const (
|
|
||||||
NonUnit Diag = 'N'
|
|
||||||
Unit Diag = 'U'
|
|
||||||
)
|
|
||||||
|
|
||||||
// Side specifies from which side a multiplication operation is performed.
|
|
||||||
type Side byte
|
|
||||||
|
|
||||||
const (
|
|
||||||
Left Side = 'L'
|
|
||||||
Right Side = 'R'
|
|
||||||
)
|
|
||||||
|
|
||||||
// Float32 implements the single precision real BLAS routines.
|
|
||||||
type Float32 interface {
|
|
||||||
Float32Level1
|
|
||||||
Float32Level2
|
|
||||||
Float32Level3
|
|
||||||
}
|
|
||||||
|
|
||||||
// Float32Level1 implements the single precision real BLAS Level 1 routines.
|
|
||||||
type Float32Level1 interface {
|
|
||||||
Sdsdot(n int, alpha float32, x []float32, incX int, y []float32, incY int) float32
|
|
||||||
Dsdot(n int, x []float32, incX int, y []float32, incY int) float64
|
|
||||||
Sdot(n int, x []float32, incX int, y []float32, incY int) float32
|
|
||||||
Snrm2(n int, x []float32, incX int) float32
|
|
||||||
Sasum(n int, x []float32, incX int) float32
|
|
||||||
Isamax(n int, x []float32, incX int) int
|
|
||||||
Sswap(n int, x []float32, incX int, y []float32, incY int)
|
|
||||||
Scopy(n int, x []float32, incX int, y []float32, incY int)
|
|
||||||
Saxpy(n int, alpha float32, x []float32, incX int, y []float32, incY int)
|
|
||||||
Srotg(a, b float32) (c, s, r, z float32)
|
|
||||||
Srotmg(d1, d2, b1, b2 float32) (p SrotmParams, rd1, rd2, rb1 float32)
|
|
||||||
Srot(n int, x []float32, incX int, y []float32, incY int, c, s float32)
|
|
||||||
Srotm(n int, x []float32, incX int, y []float32, incY int, p SrotmParams)
|
|
||||||
Sscal(n int, alpha float32, x []float32, incX int)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Float32Level2 implements the single precision real BLAS Level 2 routines.
|
|
||||||
type Float32Level2 interface {
|
|
||||||
Sgemv(tA Transpose, m, n int, alpha float32, a []float32, lda int, x []float32, incX int, beta float32, y []float32, incY int)
|
|
||||||
Sgbmv(tA Transpose, m, n, kL, kU int, alpha float32, a []float32, lda int, x []float32, incX int, beta float32, y []float32, incY int)
|
|
||||||
Strmv(ul Uplo, tA Transpose, d Diag, n int, a []float32, lda int, x []float32, incX int)
|
|
||||||
Stbmv(ul Uplo, tA Transpose, d Diag, n, k int, a []float32, lda int, x []float32, incX int)
|
|
||||||
Stpmv(ul Uplo, tA Transpose, d Diag, n int, ap []float32, x []float32, incX int)
|
|
||||||
Strsv(ul Uplo, tA Transpose, d Diag, n int, a []float32, lda int, x []float32, incX int)
|
|
||||||
Stbsv(ul Uplo, tA Transpose, d Diag, n, k int, a []float32, lda int, x []float32, incX int)
|
|
||||||
Stpsv(ul Uplo, tA Transpose, d Diag, n int, ap []float32, x []float32, incX int)
|
|
||||||
Ssymv(ul Uplo, n int, alpha float32, a []float32, lda int, x []float32, incX int, beta float32, y []float32, incY int)
|
|
||||||
Ssbmv(ul Uplo, n, k int, alpha float32, a []float32, lda int, x []float32, incX int, beta float32, y []float32, incY int)
|
|
||||||
Sspmv(ul Uplo, n int, alpha float32, ap []float32, x []float32, incX int, beta float32, y []float32, incY int)
|
|
||||||
Sger(m, n int, alpha float32, x []float32, incX int, y []float32, incY int, a []float32, lda int)
|
|
||||||
Ssyr(ul Uplo, n int, alpha float32, x []float32, incX int, a []float32, lda int)
|
|
||||||
Sspr(ul Uplo, n int, alpha float32, x []float32, incX int, ap []float32)
|
|
||||||
Ssyr2(ul Uplo, n int, alpha float32, x []float32, incX int, y []float32, incY int, a []float32, lda int)
|
|
||||||
Sspr2(ul Uplo, n int, alpha float32, x []float32, incX int, y []float32, incY int, a []float32)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Float32Level3 implements the single precision real BLAS Level 3 routines.
|
|
||||||
type Float32Level3 interface {
|
|
||||||
Sgemm(tA, tB Transpose, m, n, k int, alpha float32, a []float32, lda int, b []float32, ldb int, beta float32, c []float32, ldc int)
|
|
||||||
Ssymm(s Side, ul Uplo, m, n int, alpha float32, a []float32, lda int, b []float32, ldb int, beta float32, c []float32, ldc int)
|
|
||||||
Ssyrk(ul Uplo, t Transpose, n, k int, alpha float32, a []float32, lda int, beta float32, c []float32, ldc int)
|
|
||||||
Ssyr2k(ul Uplo, t Transpose, n, k int, alpha float32, a []float32, lda int, b []float32, ldb int, beta float32, c []float32, ldc int)
|
|
||||||
Strmm(s Side, ul Uplo, tA Transpose, d Diag, m, n int, alpha float32, a []float32, lda int, b []float32, ldb int)
|
|
||||||
Strsm(s Side, ul Uplo, tA Transpose, d Diag, m, n int, alpha float32, a []float32, lda int, b []float32, ldb int)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Float64 implements the single precision real BLAS routines.
|
|
||||||
type Float64 interface {
|
|
||||||
Float64Level1
|
|
||||||
Float64Level2
|
|
||||||
Float64Level3
|
|
||||||
}
|
|
||||||
|
|
||||||
// Float64Level1 implements the double precision real BLAS Level 1 routines.
|
|
||||||
type Float64Level1 interface {
|
|
||||||
Ddot(n int, x []float64, incX int, y []float64, incY int) float64
|
|
||||||
Dnrm2(n int, x []float64, incX int) float64
|
|
||||||
Dasum(n int, x []float64, incX int) float64
|
|
||||||
Idamax(n int, x []float64, incX int) int
|
|
||||||
Dswap(n int, x []float64, incX int, y []float64, incY int)
|
|
||||||
Dcopy(n int, x []float64, incX int, y []float64, incY int)
|
|
||||||
Daxpy(n int, alpha float64, x []float64, incX int, y []float64, incY int)
|
|
||||||
Drotg(a, b float64) (c, s, r, z float64)
|
|
||||||
Drotmg(d1, d2, b1, b2 float64) (p DrotmParams, rd1, rd2, rb1 float64)
|
|
||||||
Drot(n int, x []float64, incX int, y []float64, incY int, c float64, s float64)
|
|
||||||
Drotm(n int, x []float64, incX int, y []float64, incY int, p DrotmParams)
|
|
||||||
Dscal(n int, alpha float64, x []float64, incX int)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Float64Level2 implements the double precision real BLAS Level 2 routines.
|
|
||||||
type Float64Level2 interface {
|
|
||||||
Dgemv(tA Transpose, m, n int, alpha float64, a []float64, lda int, x []float64, incX int, beta float64, y []float64, incY int)
|
|
||||||
Dgbmv(tA Transpose, m, n, kL, kU int, alpha float64, a []float64, lda int, x []float64, incX int, beta float64, y []float64, incY int)
|
|
||||||
Dtrmv(ul Uplo, tA Transpose, d Diag, n int, a []float64, lda int, x []float64, incX int)
|
|
||||||
Dtbmv(ul Uplo, tA Transpose, d Diag, n, k int, a []float64, lda int, x []float64, incX int)
|
|
||||||
Dtpmv(ul Uplo, tA Transpose, d Diag, n int, ap []float64, x []float64, incX int)
|
|
||||||
Dtrsv(ul Uplo, tA Transpose, d Diag, n int, a []float64, lda int, x []float64, incX int)
|
|
||||||
Dtbsv(ul Uplo, tA Transpose, d Diag, n, k int, a []float64, lda int, x []float64, incX int)
|
|
||||||
Dtpsv(ul Uplo, tA Transpose, d Diag, n int, ap []float64, x []float64, incX int)
|
|
||||||
Dsymv(ul Uplo, n int, alpha float64, a []float64, lda int, x []float64, incX int, beta float64, y []float64, incY int)
|
|
||||||
Dsbmv(ul Uplo, n, k int, alpha float64, a []float64, lda int, x []float64, incX int, beta float64, y []float64, incY int)
|
|
||||||
Dspmv(ul Uplo, n int, alpha float64, ap []float64, x []float64, incX int, beta float64, y []float64, incY int)
|
|
||||||
Dger(m, n int, alpha float64, x []float64, incX int, y []float64, incY int, a []float64, lda int)
|
|
||||||
Dsyr(ul Uplo, n int, alpha float64, x []float64, incX int, a []float64, lda int)
|
|
||||||
Dspr(ul Uplo, n int, alpha float64, x []float64, incX int, ap []float64)
|
|
||||||
Dsyr2(ul Uplo, n int, alpha float64, x []float64, incX int, y []float64, incY int, a []float64, lda int)
|
|
||||||
Dspr2(ul Uplo, n int, alpha float64, x []float64, incX int, y []float64, incY int, a []float64)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Float64Level3 implements the double precision real BLAS Level 3 routines.
|
|
||||||
type Float64Level3 interface {
|
|
||||||
Dgemm(tA, tB Transpose, m, n, k int, alpha float64, a []float64, lda int, b []float64, ldb int, beta float64, c []float64, ldc int)
|
|
||||||
Dsymm(s Side, ul Uplo, m, n int, alpha float64, a []float64, lda int, b []float64, ldb int, beta float64, c []float64, ldc int)
|
|
||||||
Dsyrk(ul Uplo, t Transpose, n, k int, alpha float64, a []float64, lda int, beta float64, c []float64, ldc int)
|
|
||||||
Dsyr2k(ul Uplo, t Transpose, n, k int, alpha float64, a []float64, lda int, b []float64, ldb int, beta float64, c []float64, ldc int)
|
|
||||||
Dtrmm(s Side, ul Uplo, tA Transpose, d Diag, m, n int, alpha float64, a []float64, lda int, b []float64, ldb int)
|
|
||||||
Dtrsm(s Side, ul Uplo, tA Transpose, d Diag, m, n int, alpha float64, a []float64, lda int, b []float64, ldb int)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Complex64 implements the single precision complex BLAS routines.
|
|
||||||
type Complex64 interface {
|
|
||||||
Complex64Level1
|
|
||||||
Complex64Level2
|
|
||||||
Complex64Level3
|
|
||||||
}
|
|
||||||
|
|
||||||
// Complex64Level1 implements the single precision complex BLAS Level 1 routines.
|
|
||||||
type Complex64Level1 interface {
|
|
||||||
Cdotu(n int, x []complex64, incX int, y []complex64, incY int) (dotu complex64)
|
|
||||||
Cdotc(n int, x []complex64, incX int, y []complex64, incY int) (dotc complex64)
|
|
||||||
Scnrm2(n int, x []complex64, incX int) float32
|
|
||||||
Scasum(n int, x []complex64, incX int) float32
|
|
||||||
Icamax(n int, x []complex64, incX int) int
|
|
||||||
Cswap(n int, x []complex64, incX int, y []complex64, incY int)
|
|
||||||
Ccopy(n int, x []complex64, incX int, y []complex64, incY int)
|
|
||||||
Caxpy(n int, alpha complex64, x []complex64, incX int, y []complex64, incY int)
|
|
||||||
Cscal(n int, alpha complex64, x []complex64, incX int)
|
|
||||||
Csscal(n int, alpha float32, x []complex64, incX int)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Complex64Level2 implements the single precision complex BLAS routines Level 2 routines.
|
|
||||||
type Complex64Level2 interface {
|
|
||||||
Cgemv(tA Transpose, m, n int, alpha complex64, a []complex64, lda int, x []complex64, incX int, beta complex64, y []complex64, incY int)
|
|
||||||
Cgbmv(tA Transpose, m, n, kL, kU int, alpha complex64, a []complex64, lda int, x []complex64, incX int, beta complex64, y []complex64, incY int)
|
|
||||||
Ctrmv(ul Uplo, tA Transpose, d Diag, n int, a []complex64, lda int, x []complex64, incX int)
|
|
||||||
Ctbmv(ul Uplo, tA Transpose, d Diag, n, k int, a []complex64, lda int, x []complex64, incX int)
|
|
||||||
Ctpmv(ul Uplo, tA Transpose, d Diag, n int, ap []complex64, x []complex64, incX int)
|
|
||||||
Ctrsv(ul Uplo, tA Transpose, d Diag, n int, a []complex64, lda int, x []complex64, incX int)
|
|
||||||
Ctbsv(ul Uplo, tA Transpose, d Diag, n, k int, a []complex64, lda int, x []complex64, incX int)
|
|
||||||
Ctpsv(ul Uplo, tA Transpose, d Diag, n int, ap []complex64, x []complex64, incX int)
|
|
||||||
Chemv(ul Uplo, n int, alpha complex64, a []complex64, lda int, x []complex64, incX int, beta complex64, y []complex64, incY int)
|
|
||||||
Chbmv(ul Uplo, n, k int, alpha complex64, a []complex64, lda int, x []complex64, incX int, beta complex64, y []complex64, incY int)
|
|
||||||
Chpmv(ul Uplo, n int, alpha complex64, ap []complex64, x []complex64, incX int, beta complex64, y []complex64, incY int)
|
|
||||||
Cgeru(m, n int, alpha complex64, x []complex64, incX int, y []complex64, incY int, a []complex64, lda int)
|
|
||||||
Cgerc(m, n int, alpha complex64, x []complex64, incX int, y []complex64, incY int, a []complex64, lda int)
|
|
||||||
Cher(ul Uplo, n int, alpha float32, x []complex64, incX int, a []complex64, lda int)
|
|
||||||
Chpr(ul Uplo, n int, alpha float32, x []complex64, incX int, a []complex64)
|
|
||||||
Cher2(ul Uplo, n int, alpha complex64, x []complex64, incX int, y []complex64, incY int, a []complex64, lda int)
|
|
||||||
Chpr2(ul Uplo, n int, alpha complex64, x []complex64, incX int, y []complex64, incY int, ap []complex64)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Complex64Level3 implements the single precision complex BLAS Level 3 routines.
|
|
||||||
type Complex64Level3 interface {
|
|
||||||
Cgemm(tA, tB Transpose, m, n, k int, alpha complex64, a []complex64, lda int, b []complex64, ldb int, beta complex64, c []complex64, ldc int)
|
|
||||||
Csymm(s Side, ul Uplo, m, n int, alpha complex64, a []complex64, lda int, b []complex64, ldb int, beta complex64, c []complex64, ldc int)
|
|
||||||
Csyrk(ul Uplo, t Transpose, n, k int, alpha complex64, a []complex64, lda int, beta complex64, c []complex64, ldc int)
|
|
||||||
Csyr2k(ul Uplo, t Transpose, n, k int, alpha complex64, a []complex64, lda int, b []complex64, ldb int, beta complex64, c []complex64, ldc int)
|
|
||||||
Ctrmm(s Side, ul Uplo, tA Transpose, d Diag, m, n int, alpha complex64, a []complex64, lda int, b []complex64, ldb int)
|
|
||||||
Ctrsm(s Side, ul Uplo, tA Transpose, d Diag, m, n int, alpha complex64, a []complex64, lda int, b []complex64, ldb int)
|
|
||||||
Chemm(s Side, ul Uplo, m, n int, alpha complex64, a []complex64, lda int, b []complex64, ldb int, beta complex64, c []complex64, ldc int)
|
|
||||||
Cherk(ul Uplo, t Transpose, n, k int, alpha float32, a []complex64, lda int, beta float32, c []complex64, ldc int)
|
|
||||||
Cher2k(ul Uplo, t Transpose, n, k int, alpha complex64, a []complex64, lda int, b []complex64, ldb int, beta float32, c []complex64, ldc int)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Complex128 implements the double precision complex BLAS routines.
|
|
||||||
type Complex128 interface {
|
|
||||||
Complex128Level1
|
|
||||||
Complex128Level2
|
|
||||||
Complex128Level3
|
|
||||||
}
|
|
||||||
|
|
||||||
// Complex128Level1 implements the double precision complex BLAS Level 1 routines.
|
|
||||||
type Complex128Level1 interface {
|
|
||||||
Zdotu(n int, x []complex128, incX int, y []complex128, incY int) (dotu complex128)
|
|
||||||
Zdotc(n int, x []complex128, incX int, y []complex128, incY int) (dotc complex128)
|
|
||||||
Dznrm2(n int, x []complex128, incX int) float64
|
|
||||||
Dzasum(n int, x []complex128, incX int) float64
|
|
||||||
Izamax(n int, x []complex128, incX int) int
|
|
||||||
Zswap(n int, x []complex128, incX int, y []complex128, incY int)
|
|
||||||
Zcopy(n int, x []complex128, incX int, y []complex128, incY int)
|
|
||||||
Zaxpy(n int, alpha complex128, x []complex128, incX int, y []complex128, incY int)
|
|
||||||
Zscal(n int, alpha complex128, x []complex128, incX int)
|
|
||||||
Zdscal(n int, alpha float64, x []complex128, incX int)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Complex128Level2 implements the double precision complex BLAS Level 2 routines.
|
|
||||||
type Complex128Level2 interface {
|
|
||||||
Zgemv(tA Transpose, m, n int, alpha complex128, a []complex128, lda int, x []complex128, incX int, beta complex128, y []complex128, incY int)
|
|
||||||
Zgbmv(tA Transpose, m, n int, kL int, kU int, alpha complex128, a []complex128, lda int, x []complex128, incX int, beta complex128, y []complex128, incY int)
|
|
||||||
Ztrmv(ul Uplo, tA Transpose, d Diag, n int, a []complex128, lda int, x []complex128, incX int)
|
|
||||||
Ztbmv(ul Uplo, tA Transpose, d Diag, n, k int, a []complex128, lda int, x []complex128, incX int)
|
|
||||||
Ztpmv(ul Uplo, tA Transpose, d Diag, n int, ap []complex128, x []complex128, incX int)
|
|
||||||
Ztrsv(ul Uplo, tA Transpose, d Diag, n int, a []complex128, lda int, x []complex128, incX int)
|
|
||||||
Ztbsv(ul Uplo, tA Transpose, d Diag, n, k int, a []complex128, lda int, x []complex128, incX int)
|
|
||||||
Ztpsv(ul Uplo, tA Transpose, d Diag, n int, ap []complex128, x []complex128, incX int)
|
|
||||||
Zhemv(ul Uplo, n int, alpha complex128, a []complex128, lda int, x []complex128, incX int, beta complex128, y []complex128, incY int)
|
|
||||||
Zhbmv(ul Uplo, n, k int, alpha complex128, a []complex128, lda int, x []complex128, incX int, beta complex128, y []complex128, incY int)
|
|
||||||
Zhpmv(ul Uplo, n int, alpha complex128, ap []complex128, x []complex128, incX int, beta complex128, y []complex128, incY int)
|
|
||||||
Zgeru(m, n int, alpha complex128, x []complex128, incX int, y []complex128, incY int, a []complex128, lda int)
|
|
||||||
Zgerc(m, n int, alpha complex128, x []complex128, incX int, y []complex128, incY int, a []complex128, lda int)
|
|
||||||
Zher(ul Uplo, n int, alpha float64, x []complex128, incX int, a []complex128, lda int)
|
|
||||||
Zhpr(ul Uplo, n int, alpha float64, x []complex128, incX int, a []complex128)
|
|
||||||
Zher2(ul Uplo, n int, alpha complex128, x []complex128, incX int, y []complex128, incY int, a []complex128, lda int)
|
|
||||||
Zhpr2(ul Uplo, n int, alpha complex128, x []complex128, incX int, y []complex128, incY int, ap []complex128)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Complex128Level3 implements the double precision complex BLAS Level 3 routines.
|
|
||||||
type Complex128Level3 interface {
|
|
||||||
Zgemm(tA, tB Transpose, m, n, k int, alpha complex128, a []complex128, lda int, b []complex128, ldb int, beta complex128, c []complex128, ldc int)
|
|
||||||
Zsymm(s Side, ul Uplo, m, n int, alpha complex128, a []complex128, lda int, b []complex128, ldb int, beta complex128, c []complex128, ldc int)
|
|
||||||
Zsyrk(ul Uplo, t Transpose, n, k int, alpha complex128, a []complex128, lda int, beta complex128, c []complex128, ldc int)
|
|
||||||
Zsyr2k(ul Uplo, t Transpose, n, k int, alpha complex128, a []complex128, lda int, b []complex128, ldb int, beta complex128, c []complex128, ldc int)
|
|
||||||
Ztrmm(s Side, ul Uplo, tA Transpose, d Diag, m, n int, alpha complex128, a []complex128, lda int, b []complex128, ldb int)
|
|
||||||
Ztrsm(s Side, ul Uplo, tA Transpose, d Diag, m, n int, alpha complex128, a []complex128, lda int, b []complex128, ldb int)
|
|
||||||
Zhemm(s Side, ul Uplo, m, n int, alpha complex128, a []complex128, lda int, b []complex128, ldb int, beta complex128, c []complex128, ldc int)
|
|
||||||
Zherk(ul Uplo, t Transpose, n, k int, alpha float64, a []complex128, lda int, beta float64, c []complex128, ldc int)
|
|
||||||
Zher2k(ul Uplo, t Transpose, n, k int, alpha complex128, a []complex128, lda int, b []complex128, ldb int, beta float64, c []complex128, ldc int)
|
|
||||||
}
|
|
||||||
472
vendor/gonum.org/v1/gonum/blas/blas64/blas64.go
generated
vendored
472
vendor/gonum.org/v1/gonum/blas/blas64/blas64.go
generated
vendored
@@ -1,472 +0,0 @@
|
|||||||
// 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 blas64
|
|
||||||
|
|
||||||
import (
|
|
||||||
"gonum.org/v1/gonum/blas"
|
|
||||||
"gonum.org/v1/gonum/blas/gonum"
|
|
||||||
)
|
|
||||||
|
|
||||||
var blas64 blas.Float64 = gonum.Implementation{}
|
|
||||||
|
|
||||||
// Use sets the BLAS float64 implementation to be used by subsequent BLAS calls.
|
|
||||||
// The default implementation is
|
|
||||||
// gonum.org/v1/gonum/blas/gonum.Implementation.
|
|
||||||
func Use(b blas.Float64) {
|
|
||||||
blas64 = b
|
|
||||||
}
|
|
||||||
|
|
||||||
// Implementation returns the current BLAS float64 implementation.
|
|
||||||
//
|
|
||||||
// Implementation allows direct calls to the current the BLAS float64 implementation
|
|
||||||
// giving finer control of parameters.
|
|
||||||
func Implementation() blas.Float64 {
|
|
||||||
return blas64
|
|
||||||
}
|
|
||||||
|
|
||||||
// Vector represents a vector with an associated element increment.
|
|
||||||
type Vector struct {
|
|
||||||
N int
|
|
||||||
Data []float64
|
|
||||||
Inc int
|
|
||||||
}
|
|
||||||
|
|
||||||
// General represents a matrix using the conventional storage scheme.
|
|
||||||
type General struct {
|
|
||||||
Rows, Cols int
|
|
||||||
Data []float64
|
|
||||||
Stride int
|
|
||||||
}
|
|
||||||
|
|
||||||
// Band represents a band matrix using the band storage scheme.
|
|
||||||
type Band struct {
|
|
||||||
Rows, Cols int
|
|
||||||
KL, KU int
|
|
||||||
Data []float64
|
|
||||||
Stride int
|
|
||||||
}
|
|
||||||
|
|
||||||
// Triangular represents a triangular matrix using the conventional storage scheme.
|
|
||||||
type Triangular struct {
|
|
||||||
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 {
|
|
||||||
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 {
|
|
||||||
Uplo blas.Uplo
|
|
||||||
Diag blas.Diag
|
|
||||||
N int
|
|
||||||
Data []float64
|
|
||||||
}
|
|
||||||
|
|
||||||
// Symmetric represents a symmetric matrix using the conventional storage scheme.
|
|
||||||
type Symmetric struct {
|
|
||||||
Uplo blas.Uplo
|
|
||||||
N int
|
|
||||||
Data []float64
|
|
||||||
Stride int
|
|
||||||
}
|
|
||||||
|
|
||||||
// SymmetricBand represents a symmetric matrix using the band storage scheme.
|
|
||||||
type SymmetricBand struct {
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
// Level 1
|
|
||||||
|
|
||||||
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].
|
|
||||||
// Dot will panic if the lengths of x and y do not match.
|
|
||||||
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(x Vector) float64 {
|
|
||||||
if x.Inc < 0 {
|
|
||||||
panic(negInc)
|
|
||||||
}
|
|
||||||
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(x Vector) float64 {
|
|
||||||
if x.Inc < 0 {
|
|
||||||
panic(negInc)
|
|
||||||
}
|
|
||||||
return blas64.Dasum(x.N, x.Data, x.Inc)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Iamax returns the index of an element of x with the largest absolute value.
|
|
||||||
// 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(x Vector) int {
|
|
||||||
if x.Inc < 0 {
|
|
||||||
panic(negInc)
|
|
||||||
}
|
|
||||||
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.
|
|
||||||
// Swap will panic if the lengths of x and y do not match.
|
|
||||||
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.
|
|
||||||
// Copy will panic if the lengths of x and y do not match.
|
|
||||||
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.
|
|
||||||
// Axpy will panic if the lengths of x and y do not match.
|
|
||||||
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
|
|
||||||
// ⎡ c s⎤ ⎡a⎤ ⎡r⎤
|
|
||||||
// ⎣-s c⎦ * ⎣b⎦ = ⎣0⎦
|
|
||||||
// where a and b are the Cartesian coordinates of a given point.
|
|
||||||
// c, s, and r are defined as
|
|
||||||
// r = ±Sqrt(a^2 + b^2),
|
|
||||||
// c = a/r, the cosine of the rotation angle,
|
|
||||||
// s = a/r, the sine of the rotation angle,
|
|
||||||
// and z is defined such that
|
|
||||||
// if |a| > |b|, z = s,
|
|
||||||
// otherwise if c != 0, z = 1/c,
|
|
||||||
// otherwise z = 1.
|
|
||||||
func Rotg(a, b float64) (c, s, r, z float64) {
|
|
||||||
return blas64.Drotg(a, b)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Rotmg computes the modified Givens rotation. See
|
|
||||||
// http://www.netlib.org/lapack/explore-html/df/deb/drotmg_8f.html
|
|
||||||
// for more details.
|
|
||||||
func Rotmg(d1, d2, b1, b2 float64) (p blas.DrotmParams, rd1, rd2, rb1 float64) {
|
|
||||||
return blas64.Drotmg(d1, d2, b1, b2)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Rot applies a plane transformation to n points represented by the vectors x
|
|
||||||
// and y:
|
|
||||||
// x[i] = c*x[i] + s*y[i],
|
|
||||||
// y[i] = -s*x[i] + c*y[i], for all i.
|
|
||||||
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(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(alpha float64, x Vector) {
|
|
||||||
if x.Inc < 0 {
|
|
||||||
panic(negInc)
|
|
||||||
}
|
|
||||||
blas64.Dscal(x.N, alpha, x.Data, x.Inc)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Level 2
|
|
||||||
|
|
||||||
// Gemv computes
|
|
||||||
// y = alpha * A * x + beta * y if t == blas.NoTrans,
|
|
||||||
// y = alpha * Aᵀ * x + beta * y if t == blas.Trans or 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 float64, a General, x Vector, beta float64, y Vector) {
|
|
||||||
blas64.Dgemv(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ᵀ * x + beta * y if t == blas.Trans or 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 float64, a Band, x Vector, beta float64, y Vector) {
|
|
||||||
blas64.Dgbmv(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ᵀ * x if t == blas.Trans or blas.ConjTrans,
|
|
||||||
// where A is an n×n triangular matrix, and x is a vector.
|
|
||||||
func Trmv(t blas.Transpose, a Triangular, x Vector) {
|
|
||||||
blas64.Dtrmv(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ᵀ * x if t == blas.Trans or 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) {
|
|
||||||
blas64.Dtbmv(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ᵀ * x if t == blas.Trans or 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) {
|
|
||||||
blas64.Dtpmv(a.Uplo, t, a.Diag, a.N, a.Data, x.Data, x.Inc)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Trsv solves
|
|
||||||
// A * x = b if t == blas.NoTrans,
|
|
||||||
// Aᵀ * x = b if t == blas.Trans or blas.ConjTrans,
|
|
||||||
// where A is an n×n triangular matrix, and x and b are vectors.
|
|
||||||
//
|
|
||||||
// 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) {
|
|
||||||
blas64.Dtrsv(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ᵀ * x = b if t == blas.Trans or blas.ConjTrans,
|
|
||||||
// where A is an n×n triangular band matrix, and x and b are vectors.
|
|
||||||
//
|
|
||||||
// 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) {
|
|
||||||
blas64.Dtbsv(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ᵀ * x = b if t == blas.Trans or blas.ConjTrans,
|
|
||||||
// where A is an n×n triangular matrix in packed format, and x and b are
|
|
||||||
// vectors.
|
|
||||||
//
|
|
||||||
// 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) {
|
|
||||||
blas64.Dtpsv(a.Uplo, t, a.Diag, a.N, a.Data, x.Data, x.Inc)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Symv computes
|
|
||||||
// y = alpha * A * x + beta * y,
|
|
||||||
// where A is an n×n symmetric matrix, x and y are vectors, and alpha and
|
|
||||||
// beta are scalars.
|
|
||||||
func Symv(alpha float64, a Symmetric, x Vector, beta float64, y Vector) {
|
|
||||||
blas64.Dsymv(a.Uplo, a.N, alpha, a.Data, a.Stride, x.Data, x.Inc, beta, y.Data, y.Inc)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sbmv performs
|
|
||||||
// y = alpha * A * x + beta * y,
|
|
||||||
// where A is an n×n symmetric band matrix, x and y are vectors, and alpha
|
|
||||||
// and beta are scalars.
|
|
||||||
func Sbmv(alpha float64, a SymmetricBand, x Vector, beta float64, y Vector) {
|
|
||||||
blas64.Dsbmv(a.Uplo, a.N, a.K, alpha, a.Data, a.Stride, x.Data, x.Inc, beta, y.Data, y.Inc)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Spmv performs
|
|
||||||
// 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 Spmv(alpha float64, a SymmetricPacked, x Vector, beta float64, y Vector) {
|
|
||||||
blas64.Dspmv(a.Uplo, a.N, alpha, a.Data, x.Data, x.Inc, beta, y.Data, y.Inc)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ger performs a rank-1 update
|
|
||||||
// A += alpha * x * yᵀ,
|
|
||||||
// where A is an m×n dense matrix, x and y are vectors, and alpha is a scalar.
|
|
||||||
func Ger(alpha float64, x, y Vector, a General) {
|
|
||||||
blas64.Dger(a.Rows, a.Cols, alpha, x.Data, x.Inc, y.Data, y.Inc, a.Data, a.Stride)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Syr performs a rank-1 update
|
|
||||||
// A += alpha * x * xᵀ,
|
|
||||||
// where A is an n×n symmetric matrix, x is a vector, and alpha is a scalar.
|
|
||||||
func Syr(alpha float64, x Vector, a Symmetric) {
|
|
||||||
blas64.Dsyr(a.Uplo, a.N, alpha, x.Data, x.Inc, a.Data, a.Stride)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Spr performs the rank-1 update
|
|
||||||
// A += alpha * x * xᵀ,
|
|
||||||
// where A is an n×n symmetric matrix in packed format, x is a vector, and
|
|
||||||
// alpha is a scalar.
|
|
||||||
func Spr(alpha float64, x Vector, a SymmetricPacked) {
|
|
||||||
blas64.Dspr(a.Uplo, a.N, alpha, x.Data, x.Inc, a.Data)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Syr2 performs a rank-2 update
|
|
||||||
// A += alpha * x * yᵀ + alpha * y * xᵀ,
|
|
||||||
// where A is a symmetric n×n matrix, x and y are vectors, and alpha is a scalar.
|
|
||||||
func Syr2(alpha float64, x, y Vector, a Symmetric) {
|
|
||||||
blas64.Dsyr2(a.Uplo, a.N, alpha, x.Data, x.Inc, y.Data, y.Inc, a.Data, a.Stride)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Spr2 performs a rank-2 update
|
|
||||||
// A += alpha * x * yᵀ + alpha * y * xᵀ,
|
|
||||||
// where A is an n×n symmetric matrix in packed format, x and y are vectors,
|
|
||||||
// and alpha is a scalar.
|
|
||||||
func Spr2(alpha float64, x, y Vector, a SymmetricPacked) {
|
|
||||||
blas64.Dspr2(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.
|
|
||||||
func Gemm(tA, tB blas.Transpose, alpha float64, a, b General, beta float64, 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
|
|
||||||
}
|
|
||||||
blas64.Dgemm(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 is a scalar.
|
|
||||||
func Symm(s blas.Side, alpha float64, a Symmetric, b General, beta float64, c General) {
|
|
||||||
var m, n int
|
|
||||||
if s == blas.Left {
|
|
||||||
m, n = a.N, b.Cols
|
|
||||||
} else {
|
|
||||||
m, n = b.Rows, a.N
|
|
||||||
}
|
|
||||||
blas64.Dsymm(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ᵀ + beta * C if t == blas.NoTrans,
|
|
||||||
// C = alpha * Aᵀ * A + beta * C if t == blas.Trans or blas.ConjTrans,
|
|
||||||
// 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 float64, a General, beta float64, c Symmetric) {
|
|
||||||
var n, k int
|
|
||||||
if t == blas.NoTrans {
|
|
||||||
n, k = a.Rows, a.Cols
|
|
||||||
} else {
|
|
||||||
n, k = a.Cols, a.Rows
|
|
||||||
}
|
|
||||||
blas64.Dsyrk(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ᵀ + alpha * B * Aᵀ + beta * C if t == blas.NoTrans,
|
|
||||||
// C = alpha * Aᵀ * B + alpha * Bᵀ * A + beta * C if t == blas.Trans or blas.ConjTrans,
|
|
||||||
// where C is an n×n symmetric matrix, A and B are n×k matrices if t == NoTrans
|
|
||||||
// and k×n matrices otherwise, and alpha and beta are scalars.
|
|
||||||
func Syr2k(t blas.Transpose, alpha float64, a, b General, beta float64, c Symmetric) {
|
|
||||||
var n, k int
|
|
||||||
if t == blas.NoTrans {
|
|
||||||
n, k = a.Rows, a.Cols
|
|
||||||
} else {
|
|
||||||
n, k = a.Cols, a.Rows
|
|
||||||
}
|
|
||||||
blas64.Dsyr2k(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ᵀ * B if tA == blas.Trans or blas.ConjTrans, and s == blas.Left,
|
|
||||||
// B = alpha * B * A if tA == blas.NoTrans and s == blas.Right,
|
|
||||||
// B = alpha * B * Aᵀ if tA == blas.Trans or 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 float64, a Triangular, b General) {
|
|
||||||
blas64.Dtrmm(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ᵀ * X = alpha * B if tA == blas.Trans or blas.ConjTrans, and s == blas.Left,
|
|
||||||
// X * A = alpha * B if tA == blas.NoTrans and s == blas.Right,
|
|
||||||
// X * Aᵀ = alpha * B if tA == blas.Trans or 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, X contains the values of B, and the result is
|
|
||||||
// stored in-place into X.
|
|
||||||
//
|
|
||||||
// No check is made that A is invertible.
|
|
||||||
func Trsm(s blas.Side, tA blas.Transpose, alpha float64, a Triangular, b General) {
|
|
||||||
blas64.Dtrsm(s, a.Uplo, tA, a.Diag, b.Rows, b.Cols, alpha, a.Data, a.Stride, b.Data, b.Stride)
|
|
||||||
}
|
|
||||||
277
vendor/gonum.org/v1/gonum/blas/blas64/conv.go
generated
vendored
277
vendor/gonum.org/v1/gonum/blas/blas64/conv.go
generated
vendored
@@ -1,277 +0,0 @@
|
|||||||
// 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 blas64
|
|
||||||
|
|
||||||
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("blas64: mismatched dimension")
|
|
||||||
}
|
|
||||||
if len(t.Data) < (t.Cols-1)*t.Stride+t.Rows {
|
|
||||||
panic("blas64: 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("blas64: mismatched dimension")
|
|
||||||
}
|
|
||||||
if len(t.Data) < (t.Rows-1)*t.Stride+t.Cols {
|
|
||||||
panic("blas64: 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("blas64: mismatched dimension")
|
|
||||||
}
|
|
||||||
if t.Uplo != a.Uplo {
|
|
||||||
panic("blas64: mismatched BLAS uplo")
|
|
||||||
}
|
|
||||||
if t.Diag != a.Diag {
|
|
||||||
panic("blas64: mismatched BLAS diag")
|
|
||||||
}
|
|
||||||
switch a.Uplo {
|
|
||||||
default:
|
|
||||||
panic("blas64: 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("blas64: mismatched dimension")
|
|
||||||
}
|
|
||||||
if t.Uplo != a.Uplo {
|
|
||||||
panic("blas64: mismatched BLAS uplo")
|
|
||||||
}
|
|
||||||
if t.Diag != a.Diag {
|
|
||||||
panic("blas64: mismatched BLAS diag")
|
|
||||||
}
|
|
||||||
switch a.Uplo {
|
|
||||||
default:
|
|
||||||
panic("blas64: 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("blas64: mismatched dimension")
|
|
||||||
}
|
|
||||||
if t.KL != a.KL || t.KU != a.KU {
|
|
||||||
panic("blas64: mismatched bandwidth")
|
|
||||||
}
|
|
||||||
if a.Stride < a.KL+a.KU+1 {
|
|
||||||
panic("blas64: short stride for source")
|
|
||||||
}
|
|
||||||
if t.Stride < t.KL+t.KU+1 {
|
|
||||||
panic("blas64: 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("blas64: mismatched dimension")
|
|
||||||
}
|
|
||||||
if t.KL != a.KL || t.KU != a.KU {
|
|
||||||
panic("blas64: mismatched bandwidth")
|
|
||||||
}
|
|
||||||
if a.Stride < a.KL+a.KU+1 {
|
|
||||||
panic("blas64: short stride for source")
|
|
||||||
}
|
|
||||||
if t.Stride < t.KL+t.KU+1 {
|
|
||||||
panic("blas64: 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 triangular 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("blas64: mismatched dimension")
|
|
||||||
}
|
|
||||||
if t.K != a.K {
|
|
||||||
panic("blas64: mismatched bandwidth")
|
|
||||||
}
|
|
||||||
if a.Stride < a.K+1 {
|
|
||||||
panic("blas64: short stride for source")
|
|
||||||
}
|
|
||||||
if t.Stride < t.K+1 {
|
|
||||||
panic("blas64: short stride for destination")
|
|
||||||
}
|
|
||||||
if t.Uplo != a.Uplo {
|
|
||||||
panic("blas64: mismatched BLAS uplo")
|
|
||||||
}
|
|
||||||
if t.Diag != a.Diag {
|
|
||||||
panic("blas64: 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("blas64: 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("blas64: mismatched dimension")
|
|
||||||
}
|
|
||||||
if t.K != a.K {
|
|
||||||
panic("blas64: mismatched bandwidth")
|
|
||||||
}
|
|
||||||
if a.Stride < a.K+1 {
|
|
||||||
panic("blas64: short stride for source")
|
|
||||||
}
|
|
||||||
if t.Stride < t.K+1 {
|
|
||||||
panic("blas64: short stride for destination")
|
|
||||||
}
|
|
||||||
if t.Uplo != a.Uplo {
|
|
||||||
panic("blas64: mismatched BLAS uplo")
|
|
||||||
}
|
|
||||||
if t.Diag != a.Diag {
|
|
||||||
panic("blas64: 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("blas64: 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
|
|
||||||
}
|
|
||||||
153
vendor/gonum.org/v1/gonum/blas/blas64/conv_symmetric.go
generated
vendored
153
vendor/gonum.org/v1/gonum/blas/blas64/conv_symmetric.go
generated
vendored
@@ -1,153 +0,0 @@
|
|||||||
// 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 blas64
|
|
||||||
|
|
||||||
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("blas64: mismatched dimension")
|
|
||||||
}
|
|
||||||
if t.Uplo != a.Uplo {
|
|
||||||
panic("blas64: mismatched BLAS uplo")
|
|
||||||
}
|
|
||||||
switch a.Uplo {
|
|
||||||
default:
|
|
||||||
panic("blas64: 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("blas64: mismatched dimension")
|
|
||||||
}
|
|
||||||
if t.Uplo != a.Uplo {
|
|
||||||
panic("blas64: mismatched BLAS uplo")
|
|
||||||
}
|
|
||||||
switch a.Uplo {
|
|
||||||
default:
|
|
||||||
panic("blas64: 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("blas64: mismatched dimension")
|
|
||||||
}
|
|
||||||
if t.K != a.K {
|
|
||||||
panic("blas64: mismatched bandwidth")
|
|
||||||
}
|
|
||||||
if a.Stride < a.K+1 {
|
|
||||||
panic("blas64: short stride for source")
|
|
||||||
}
|
|
||||||
if t.Stride < t.K+1 {
|
|
||||||
panic("blas64: short stride for destination")
|
|
||||||
}
|
|
||||||
if t.Uplo != a.Uplo {
|
|
||||||
panic("blas64: 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("blas64: 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("blas64: mismatched dimension")
|
|
||||||
}
|
|
||||||
if t.K != a.K {
|
|
||||||
panic("blas64: mismatched bandwidth")
|
|
||||||
}
|
|
||||||
if a.Stride < a.K+1 {
|
|
||||||
panic("blas64: short stride for source")
|
|
||||||
}
|
|
||||||
if t.Stride < t.K+1 {
|
|
||||||
panic("blas64: short stride for destination")
|
|
||||||
}
|
|
||||||
if t.Uplo != a.Uplo {
|
|
||||||
panic("blas64: 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("blas64: 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/blas64/doc.go
generated
vendored
6
vendor/gonum.org/v1/gonum/blas/blas64/doc.go
generated
vendored
@@ -1,6 +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 blas64 provides a simple interface to the float64 BLAS API.
|
|
||||||
package blas64 // import "gonum.org/v1/gonum/blas/blas64"
|
|
||||||
532
vendor/gonum.org/v1/gonum/blas/cblas128/cblas128.go
generated
vendored
532
vendor/gonum.org/v1/gonum/blas/cblas128/cblas128.go
generated
vendored
@@ -1,532 +0,0 @@
|
|||||||
// 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 {
|
|
||||||
N int
|
|
||||||
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"
|
|
||||||
badLength = "cblas128: vector length mismatch"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Dotu computes the dot product of the two vectors without
|
|
||||||
// complex conjugation:
|
|
||||||
// xᵀ * y.
|
|
||||||
// Dotu will panic if the lengths of x and y do not match.
|
|
||||||
func Dotu(x, y Vector) complex128 {
|
|
||||||
if x.N != y.N {
|
|
||||||
panic(badLength)
|
|
||||||
}
|
|
||||||
return cblas128.Zdotu(x.N, x.Data, x.Inc, y.Data, y.Inc)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dotc computes the dot product of the two vectors with
|
|
||||||
// complex conjugation:
|
|
||||||
// xᴴ * y.
|
|
||||||
// Dotc will panic if the lengths of x and y do not match.
|
|
||||||
func Dotc(x, y Vector) complex128 {
|
|
||||||
if x.N != y.N {
|
|
||||||
panic(badLength)
|
|
||||||
}
|
|
||||||
return cblas128.Zdotc(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(x Vector) float64 {
|
|
||||||
if x.Inc < 0 {
|
|
||||||
panic(negInc)
|
|
||||||
}
|
|
||||||
return cblas128.Dznrm2(x.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(x Vector) float64 {
|
|
||||||
if x.Inc < 0 {
|
|
||||||
panic(negInc)
|
|
||||||
}
|
|
||||||
return cblas128.Dzasum(x.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(x Vector) int {
|
|
||||||
if x.Inc < 0 {
|
|
||||||
panic(negInc)
|
|
||||||
}
|
|
||||||
return cblas128.Izamax(x.N, x.Data, x.Inc)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Swap exchanges the elements of two vectors:
|
|
||||||
// x[i], y[i] = y[i], x[i] for all i.
|
|
||||||
// Swap will panic if the lengths of x and y do not match.
|
|
||||||
func Swap(x, y Vector) {
|
|
||||||
if x.N != y.N {
|
|
||||||
panic(badLength)
|
|
||||||
}
|
|
||||||
cblas128.Zswap(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.
|
|
||||||
// Copy will panic if the lengths of x and y do not match.
|
|
||||||
func Copy(x, y Vector) {
|
|
||||||
if x.N != y.N {
|
|
||||||
panic(badLength)
|
|
||||||
}
|
|
||||||
cblas128.Zcopy(x.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.
|
|
||||||
// Axpy will panic if the lengths of x and y do not match.
|
|
||||||
func Axpy(alpha complex128, x, y Vector) {
|
|
||||||
if x.N != y.N {
|
|
||||||
panic(badLength)
|
|
||||||
}
|
|
||||||
cblas128.Zaxpy(x.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(alpha complex128, x Vector) {
|
|
||||||
if x.Inc < 0 {
|
|
||||||
panic(negInc)
|
|
||||||
}
|
|
||||||
cblas128.Zscal(x.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(alpha float64, x Vector) {
|
|
||||||
if x.Inc < 0 {
|
|
||||||
panic(negInc)
|
|
||||||
}
|
|
||||||
cblas128.Zdscal(x.N, alpha, x.Data, x.Inc)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Level 2
|
|
||||||
|
|
||||||
// Gemv computes
|
|
||||||
// y = alpha * A * x + beta * y if t == blas.NoTrans,
|
|
||||||
// y = alpha * Aᵀ * x + beta * y if t == blas.Trans,
|
|
||||||
// y = alpha * Aᴴ * 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ᵀ * x + beta * y if t == blas.Trans,
|
|
||||||
// y = alpha * Aᴴ * 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ᵀ * x if t == blas.Trans,
|
|
||||||
// x = Aᴴ * 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ᵀ * x if t == blas.Trans,
|
|
||||||
// x = Aᴴ * 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ᵀ * x if t == blas.Trans,
|
|
||||||
// x = Aᴴ * 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ᵀ * x = b if t == blas.Trans,
|
|
||||||
// Aᴴ * 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ᵀ * x = b if t == blas.Trans,
|
|
||||||
// Aᴴ * 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ᵀ * x = b if t == blas.Trans,
|
|
||||||
// Aᴴ * 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ᵀ,
|
|
||||||
// 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ᴴ,
|
|
||||||
// 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ᵀ,
|
|
||||||
// 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ᴴ,
|
|
||||||
// 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ᴴ + conj(alpha) * y * xᴴ,
|
|
||||||
// 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ᴴ + conj(alpha) * y * xᴴ,
|
|
||||||
// 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ᵀ + beta * C if t == blas.NoTrans,
|
|
||||||
// C = alpha * Aᵀ * 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ᵀ + alpha * B * Aᵀ + beta * C if t == blas.NoTrans,
|
|
||||||
// C = alpha * Aᵀ * B + alpha * Bᵀ * 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ᵀ * B if tA == blas.Trans and s == blas.Left,
|
|
||||||
// B = alpha * Aᴴ * 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ᵀ if tA == blas.Trans and s == blas.Right,
|
|
||||||
// B = alpha * B * Aᴴ 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ᵀ * X = alpha * B if tA == blas.Trans and s == blas.Left,
|
|
||||||
// Aᴴ * 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ᵀ = alpha * B if tA == blas.Trans and s == blas.Right,
|
|
||||||
// X * Aᴴ = 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ᴴ + beta*C if t == blas.NoTrans,
|
|
||||||
// C = alpha * Aᴴ * 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ᴴ + conj(alpha) * B * Aᴴ + beta * C if t == blas.NoTrans,
|
|
||||||
// C = alpha * Aᴴ * B + conj(alpha) * Bᴴ * 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
279
vendor/gonum.org/v1/gonum/blas/cblas128/conv.go
generated
vendored
@@ -1,279 +0,0 @@
|
|||||||
// 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 triangular 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
155
vendor/gonum.org/v1/gonum/blas/cblas128/conv_hermitian.go
generated
vendored
@@ -1,155 +0,0 @@
|
|||||||
// 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
155
vendor/gonum.org/v1/gonum/blas/cblas128/conv_symmetric.go
generated
vendored
@@ -1,155 +0,0 @@
|
|||||||
// 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
6
vendor/gonum.org/v1/gonum/blas/cblas128/doc.go
generated
vendored
@@ -1,6 +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 cblas128 provides a simple interface to the complex128 BLAS API.
|
|
||||||
package cblas128 // import "gonum.org/v1/gonum/blas/cblas128"
|
|
||||||
159
vendor/gonum.org/v1/gonum/blas/conversions.bash
generated
vendored
159
vendor/gonum.org/v1/gonum/blas/conversions.bash
generated
vendored
@@ -1,159 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
# 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.
|
|
||||||
|
|
||||||
# Generate code for blas32.
|
|
||||||
echo Generating blas32/conv.go
|
|
||||||
echo -e '// Code generated by "go generate gonum.org/v1/gonum/blas”; DO NOT EDIT.\n' > blas32/conv.go
|
|
||||||
cat blas64/conv.go \
|
|
||||||
| gofmt -r 'float64 -> float32' \
|
|
||||||
\
|
|
||||||
| sed -e 's/blas64/blas32/' \
|
|
||||||
\
|
|
||||||
>> blas32/conv.go
|
|
||||||
|
|
||||||
echo Generating blas32/conv_test.go
|
|
||||||
echo -e '// Code generated by "go generate gonum.org/v1/gonum/blas”; DO NOT EDIT.\n' > blas32/conv_test.go
|
|
||||||
cat blas64/conv_test.go \
|
|
||||||
| gofmt -r 'float64 -> float32' \
|
|
||||||
\
|
|
||||||
| sed -e 's/blas64/blas32/' \
|
|
||||||
-e 's_"math"_math "gonum.org/v1/gonum/internal/math32"_' \
|
|
||||||
\
|
|
||||||
>> blas32/conv_test.go
|
|
||||||
|
|
||||||
echo Generating blas32/conv_symmetric.go
|
|
||||||
echo -e '// Code generated by "go generate gonum.org/v1/gonum/blas”; DO NOT EDIT.\n' > blas32/conv_symmetric.go
|
|
||||||
cat blas64/conv_symmetric.go \
|
|
||||||
| gofmt -r 'float64 -> float32' \
|
|
||||||
\
|
|
||||||
| sed -e 's/blas64/blas32/' \
|
|
||||||
\
|
|
||||||
>> blas32/conv_symmetric.go
|
|
||||||
|
|
||||||
echo Generating blas32/conv_symmetric_test.go
|
|
||||||
echo -e '// Code generated by "go generate gonum.org/v1/gonum/blas”; DO NOT EDIT.\n' > blas32/conv_symmetric_test.go
|
|
||||||
cat blas64/conv_symmetric_test.go \
|
|
||||||
| gofmt -r 'float64 -> float32' \
|
|
||||||
\
|
|
||||||
| sed -e 's/blas64/blas32/' \
|
|
||||||
-e 's_"math"_math "gonum.org/v1/gonum/internal/math32"_' \
|
|
||||||
\
|
|
||||||
>> blas32/conv_symmetric_test.go
|
|
||||||
|
|
||||||
|
|
||||||
# Generate code for cblas128.
|
|
||||||
echo Generating cblas128/conv.go
|
|
||||||
echo -e '// Code generated by "go generate gonum.org/v1/gonum/blas”; DO NOT EDIT.\n' > cblas128/conv.go
|
|
||||||
cat blas64/conv.go \
|
|
||||||
| gofmt -r 'float64 -> complex128' \
|
|
||||||
\
|
|
||||||
| sed -e 's/blas64/cblas128/' \
|
|
||||||
\
|
|
||||||
>> cblas128/conv.go
|
|
||||||
|
|
||||||
echo Generating cblas128/conv_test.go
|
|
||||||
echo -e '// Code generated by "go generate gonum.org/v1/gonum/blas”; DO NOT EDIT.\n' > cblas128/conv_test.go
|
|
||||||
cat blas64/conv_test.go \
|
|
||||||
| gofmt -r 'float64 -> complex128' \
|
|
||||||
\
|
|
||||||
| sed -e 's/blas64/cblas128/' \
|
|
||||||
-e 's_"math"_math "math/cmplx"_' \
|
|
||||||
\
|
|
||||||
>> cblas128/conv_test.go
|
|
||||||
|
|
||||||
echo Generating cblas128/conv_symmetric.go
|
|
||||||
echo -e '// Code generated by "go generate gonum.org/v1/gonum/blas”; DO NOT EDIT.\n' > cblas128/conv_symmetric.go
|
|
||||||
cat blas64/conv_symmetric.go \
|
|
||||||
| gofmt -r 'float64 -> complex128' \
|
|
||||||
\
|
|
||||||
| sed -e 's/blas64/cblas128/' \
|
|
||||||
\
|
|
||||||
>> cblas128/conv_symmetric.go
|
|
||||||
|
|
||||||
echo Generating cblas128/conv_symmetric_test.go
|
|
||||||
echo -e '// Code generated by "go generate gonum.org/v1/gonum/blas”; DO NOT EDIT.\n' > cblas128/conv_symmetric_test.go
|
|
||||||
cat blas64/conv_symmetric_test.go \
|
|
||||||
| gofmt -r 'float64 -> complex128' \
|
|
||||||
\
|
|
||||||
| sed -e 's/blas64/cblas128/' \
|
|
||||||
-e 's_"math"_math "math/cmplx"_' \
|
|
||||||
\
|
|
||||||
>> cblas128/conv_symmetric_test.go
|
|
||||||
|
|
||||||
echo Generating cblas128/conv_hermitian.go
|
|
||||||
echo -e '// Code generated by "go generate gonum.org/v1/gonum/blas”; DO NOT EDIT.\n' > cblas128/conv_hermitian.go
|
|
||||||
cat blas64/conv_symmetric.go \
|
|
||||||
| gofmt -r 'float64 -> complex128' \
|
|
||||||
\
|
|
||||||
| sed -e 's/blas64/cblas128/' \
|
|
||||||
-e 's/Symmetric/Hermitian/g' \
|
|
||||||
-e 's/a symmetric/an Hermitian/g' \
|
|
||||||
-e 's/symmetric/hermitian/g' \
|
|
||||||
-e 's/Sym/Herm/g' \
|
|
||||||
\
|
|
||||||
>> cblas128/conv_hermitian.go
|
|
||||||
|
|
||||||
echo Generating cblas128/conv_hermitian_test.go
|
|
||||||
echo -e '// Code generated by "go generate gonum.org/v1/gonum/blas”; DO NOT EDIT.\n' > cblas128/conv_hermitian_test.go
|
|
||||||
cat blas64/conv_symmetric_test.go \
|
|
||||||
| gofmt -r 'float64 -> complex128' \
|
|
||||||
\
|
|
||||||
| sed -e 's/blas64/cblas128/' \
|
|
||||||
-e 's/Symmetric/Hermitian/g' \
|
|
||||||
-e 's/a symmetric/an Hermitian/g' \
|
|
||||||
-e 's/symmetric/hermitian/g' \
|
|
||||||
-e 's/Sym/Herm/g' \
|
|
||||||
-e 's_"math"_math "math/cmplx"_' \
|
|
||||||
\
|
|
||||||
>> cblas128/conv_hermitian_test.go
|
|
||||||
|
|
||||||
|
|
||||||
# Generate code for cblas64.
|
|
||||||
echo Generating cblas64/conv.go
|
|
||||||
echo -e '// Code generated by "go generate gonum.org/v1/gonum/blas”; DO NOT EDIT.\n' > cblas64/conv.go
|
|
||||||
cat blas64/conv.go \
|
|
||||||
| gofmt -r 'float64 -> complex64' \
|
|
||||||
\
|
|
||||||
| sed -e 's/blas64/cblas64/' \
|
|
||||||
\
|
|
||||||
>> cblas64/conv.go
|
|
||||||
|
|
||||||
echo Generating cblas64/conv_test.go
|
|
||||||
echo -e '// Code generated by "go generate gonum.org/v1/gonum/blas”; DO NOT EDIT.\n' > cblas64/conv_test.go
|
|
||||||
cat blas64/conv_test.go \
|
|
||||||
| gofmt -r 'float64 -> complex64' \
|
|
||||||
\
|
|
||||||
| sed -e 's/blas64/cblas64/' \
|
|
||||||
-e 's_"math"_math "gonum.org/v1/gonum/internal/cmplx64"_' \
|
|
||||||
\
|
|
||||||
>> cblas64/conv_test.go
|
|
||||||
|
|
||||||
echo Generating cblas64/conv_hermitian.go
|
|
||||||
echo -e '// Code generated by "go generate gonum.org/v1/gonum/blas”; DO NOT EDIT.\n' > cblas64/conv_hermitian.go
|
|
||||||
cat blas64/conv_symmetric.go \
|
|
||||||
| gofmt -r 'float64 -> complex64' \
|
|
||||||
\
|
|
||||||
| sed -e 's/blas64/cblas64/' \
|
|
||||||
-e 's/Symmetric/Hermitian/g' \
|
|
||||||
-e 's/a symmetric/an Hermitian/g' \
|
|
||||||
-e 's/symmetric/hermitian/g' \
|
|
||||||
-e 's/Sym/Herm/g' \
|
|
||||||
\
|
|
||||||
>> cblas64/conv_hermitian.go
|
|
||||||
|
|
||||||
echo Generating cblas64/conv_hermitian_test.go
|
|
||||||
echo -e '// Code generated by "go generate gonum.org/v1/gonum/blas”; DO NOT EDIT.\n' > cblas64/conv_hermitian_test.go
|
|
||||||
cat blas64/conv_symmetric_test.go \
|
|
||||||
| gofmt -r 'float64 -> complex64' \
|
|
||||||
\
|
|
||||||
| sed -e 's/blas64/cblas64/' \
|
|
||||||
-e 's/Symmetric/Hermitian/g' \
|
|
||||||
-e 's/a symmetric/an Hermitian/g' \
|
|
||||||
-e 's/symmetric/hermitian/g' \
|
|
||||||
-e 's/Sym/Herm/g' \
|
|
||||||
-e 's_"math"_math "gonum.org/v1/gonum/internal/cmplx64"_' \
|
|
||||||
\
|
|
||||||
>> cblas64/conv_hermitian_test.go
|
|
||||||
108
vendor/gonum.org/v1/gonum/blas/doc.go
generated
vendored
108
vendor/gonum.org/v1/gonum/blas/doc.go
generated
vendored
@@ -1,108 +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 blas provides interfaces for the BLAS linear algebra standard.
|
|
||||||
|
|
||||||
All methods must perform appropriate parameter checking and panic if
|
|
||||||
provided parameters that do not conform to the requirements specified
|
|
||||||
by the BLAS standard.
|
|
||||||
|
|
||||||
Quick Reference Guide to the BLAS from http://www.netlib.org/lapack/lug/node145.html
|
|
||||||
|
|
||||||
This version is modified to remove the "order" option. All matrix operations are
|
|
||||||
on row-order matrices.
|
|
||||||
|
|
||||||
Level 1 BLAS
|
|
||||||
|
|
||||||
dim scalar vector vector scalars 5-element prefixes
|
|
||||||
struct
|
|
||||||
|
|
||||||
_rotg ( a, b ) S, D
|
|
||||||
_rotmg( d1, d2, a, b ) S, D
|
|
||||||
_rot ( n, x, incX, y, incY, c, s ) S, D
|
|
||||||
_rotm ( n, x, incX, y, incY, param ) S, D
|
|
||||||
_swap ( n, x, incX, y, incY ) S, D, C, Z
|
|
||||||
_scal ( n, alpha, x, incX ) S, D, C, Z, Cs, Zd
|
|
||||||
_copy ( n, x, incX, y, incY ) S, D, C, Z
|
|
||||||
_axpy ( n, alpha, x, incX, y, incY ) S, D, C, Z
|
|
||||||
_dot ( n, x, incX, y, incY ) S, D, Ds
|
|
||||||
_dotu ( n, x, incX, y, incY ) C, Z
|
|
||||||
_dotc ( n, x, incX, y, incY ) C, Z
|
|
||||||
__dot ( n, alpha, x, incX, y, incY ) Sds
|
|
||||||
_nrm2 ( n, x, incX ) S, D, Sc, Dz
|
|
||||||
_asum ( n, x, incX ) S, D, Sc, Dz
|
|
||||||
I_amax( n, x, incX ) s, d, c, z
|
|
||||||
|
|
||||||
Level 2 BLAS
|
|
||||||
|
|
||||||
options dim b-width scalar matrix vector scalar vector prefixes
|
|
||||||
|
|
||||||
_gemv ( trans, m, n, alpha, a, lda, x, incX, beta, y, incY ) S, D, C, Z
|
|
||||||
_gbmv ( trans, m, n, kL, kU, alpha, a, lda, x, incX, beta, y, incY ) S, D, C, Z
|
|
||||||
_hemv ( uplo, n, alpha, a, lda, x, incX, beta, y, incY ) C, Z
|
|
||||||
_hbmv ( uplo, n, k, alpha, a, lda, x, incX, beta, y, incY ) C, Z
|
|
||||||
_hpmv ( uplo, n, alpha, ap, x, incX, beta, y, incY ) C, Z
|
|
||||||
_symv ( uplo, n, alpha, a, lda, x, incX, beta, y, incY ) S, D
|
|
||||||
_sbmv ( uplo, n, k, alpha, a, lda, x, incX, beta, y, incY ) S, D
|
|
||||||
_spmv ( uplo, n, alpha, ap, x, incX, beta, y, incY ) S, D
|
|
||||||
_trmv ( uplo, trans, diag, n, a, lda, x, incX ) S, D, C, Z
|
|
||||||
_tbmv ( uplo, trans, diag, n, k, a, lda, x, incX ) S, D, C, Z
|
|
||||||
_tpmv ( uplo, trans, diag, n, ap, x, incX ) S, D, C, Z
|
|
||||||
_trsv ( uplo, trans, diag, n, a, lda, x, incX ) S, D, C, Z
|
|
||||||
_tbsv ( uplo, trans, diag, n, k, a, lda, x, incX ) S, D, C, Z
|
|
||||||
_tpsv ( uplo, trans, diag, n, ap, x, incX ) S, D, C, Z
|
|
||||||
|
|
||||||
options dim scalar vector vector matrix prefixes
|
|
||||||
|
|
||||||
_ger ( m, n, alpha, x, incX, y, incY, a, lda ) S, D
|
|
||||||
_geru ( m, n, alpha, x, incX, y, incY, a, lda ) C, Z
|
|
||||||
_gerc ( m, n, alpha, x, incX, y, incY, a, lda ) C, Z
|
|
||||||
_her ( uplo, n, alpha, x, incX, a, lda ) C, Z
|
|
||||||
_hpr ( uplo, n, alpha, x, incX, ap ) C, Z
|
|
||||||
_her2 ( uplo, n, alpha, x, incX, y, incY, a, lda ) C, Z
|
|
||||||
_hpr2 ( uplo, n, alpha, x, incX, y, incY, ap ) C, Z
|
|
||||||
_syr ( uplo, n, alpha, x, incX, a, lda ) S, D
|
|
||||||
_spr ( uplo, n, alpha, x, incX, ap ) S, D
|
|
||||||
_syr2 ( uplo, n, alpha, x, incX, y, incY, a, lda ) S, D
|
|
||||||
_spr2 ( uplo, n, alpha, x, incX, y, incY, ap ) S, D
|
|
||||||
|
|
||||||
Level 3 BLAS
|
|
||||||
|
|
||||||
options dim scalar matrix matrix scalar matrix prefixes
|
|
||||||
|
|
||||||
_gemm ( transA, transB, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc ) S, D, C, Z
|
|
||||||
_symm ( side, uplo, m, n, alpha, a, lda, b, ldb, beta, c, ldc ) S, D, C, Z
|
|
||||||
_hemm ( side, uplo, m, n, alpha, a, lda, b, ldb, beta, c, ldc ) C, Z
|
|
||||||
_syrk ( uplo, trans, n, k, alpha, a, lda, beta, c, ldc ) S, D, C, Z
|
|
||||||
_herk ( uplo, trans, n, k, alpha, a, lda, beta, c, ldc ) C, Z
|
|
||||||
_syr2k( uplo, trans, n, k, alpha, a, lda, b, ldb, beta, c, ldc ) S, D, C, Z
|
|
||||||
_her2k( uplo, trans, n, k, alpha, a, lda, b, ldb, beta, c, ldc ) C, Z
|
|
||||||
_trmm ( side, uplo, transA, diag, m, n, alpha, a, lda, b, ldb ) S, D, C, Z
|
|
||||||
_trsm ( side, uplo, transA, diag, m, n, alpha, a, lda, b, ldb ) S, D, C, Z
|
|
||||||
|
|
||||||
Meaning of prefixes
|
|
||||||
|
|
||||||
S - float32 C - complex64
|
|
||||||
D - float64 Z - complex128
|
|
||||||
|
|
||||||
Matrix types
|
|
||||||
|
|
||||||
GE - GEneral GB - General Band
|
|
||||||
SY - SYmmetric SB - Symmetric Band SP - Symmetric Packed
|
|
||||||
HE - HErmitian HB - Hermitian Band HP - Hermitian Packed
|
|
||||||
TR - TRiangular TB - Triangular Band TP - Triangular Packed
|
|
||||||
|
|
||||||
Options
|
|
||||||
|
|
||||||
trans = NoTrans, Trans, ConjTrans
|
|
||||||
uplo = Upper, Lower
|
|
||||||
diag = Nonunit, Unit
|
|
||||||
side = Left, Right (A or op(A) on the left, or A or op(A) on the right)
|
|
||||||
|
|
||||||
For real matrices, Trans and ConjTrans have the same meaning.
|
|
||||||
For Hermitian matrices, trans = Trans is not allowed.
|
|
||||||
For complex symmetric matrices, trans = ConjTrans is not allowed.
|
|
||||||
*/
|
|
||||||
package blas // import "gonum.org/v1/gonum/blas"
|
|
||||||
314
vendor/gonum.org/v1/gonum/blas/gonum/dgemm.go
generated
vendored
314
vendor/gonum.org/v1/gonum/blas/gonum/dgemm.go
generated
vendored
@@ -1,314 +0,0 @@
|
|||||||
// Copyright ©2014 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 (
|
|
||||||
"runtime"
|
|
||||||
"sync"
|
|
||||||
|
|
||||||
"gonum.org/v1/gonum/blas"
|
|
||||||
"gonum.org/v1/gonum/internal/asm/f64"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Dgemm performs one of the matrix-matrix operations
|
|
||||||
// C = alpha * A * B + beta * C
|
|
||||||
// C = alpha * Aᵀ * B + beta * C
|
|
||||||
// C = alpha * A * Bᵀ + beta * C
|
|
||||||
// C = alpha * Aᵀ * Bᵀ + beta * C
|
|
||||||
// where A is an m×k or k×m dense matrix, B is an n×k or k×n dense matrix, C is
|
|
||||||
// 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) {
|
|
||||||
switch tA {
|
|
||||||
default:
|
|
||||||
panic(badTranspose)
|
|
||||||
case blas.NoTrans, blas.Trans, 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 {
|
|
||||||
if lda < max(1, m) {
|
|
||||||
panic(badLdA)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if lda < max(1, k) {
|
|
||||||
panic(badLdA)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bTrans := tB == blas.Trans || tB == blas.ConjTrans
|
|
||||||
if bTrans {
|
|
||||||
if ldb < max(1, k) {
|
|
||||||
panic(badLdB)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
// scale c
|
|
||||||
if beta != 1 {
|
|
||||||
if beta == 0 {
|
|
||||||
for i := 0; i < m; i++ {
|
|
||||||
ctmp := c[i*ldc : i*ldc+n]
|
|
||||||
for j := range ctmp {
|
|
||||||
ctmp[j] = 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for i := 0; i < m; i++ {
|
|
||||||
ctmp := c[i*ldc : i*ldc+n]
|
|
||||||
for j := range ctmp {
|
|
||||||
ctmp[j] *= beta
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dgemmParallel(aTrans, bTrans, m, n, k, a, lda, b, ldb, c, ldc, alpha)
|
|
||||||
}
|
|
||||||
|
|
||||||
func dgemmParallel(aTrans, bTrans bool, m, n, k int, a []float64, lda int, b []float64, ldb int, c []float64, ldc int, alpha float64) {
|
|
||||||
// dgemmParallel computes a parallel matrix multiplication by partitioning
|
|
||||||
// a and b into sub-blocks, and updating c with the multiplication of the sub-block
|
|
||||||
// In all cases,
|
|
||||||
// A = [ A_11 A_12 ... A_1j
|
|
||||||
// A_21 A_22 ... A_2j
|
|
||||||
// ...
|
|
||||||
// A_i1 A_i2 ... A_ij]
|
|
||||||
//
|
|
||||||
// and same for B. All of the submatrix sizes are blockSize×blockSize except
|
|
||||||
// at the edges.
|
|
||||||
//
|
|
||||||
// In all cases, there is one dimension for each matrix along which
|
|
||||||
// C must be updated sequentially.
|
|
||||||
// Cij = \sum_k Aik Bki, (A * B)
|
|
||||||
// Cij = \sum_k Aki Bkj, (Aᵀ * B)
|
|
||||||
// Cij = \sum_k Aik Bjk, (A * Bᵀ)
|
|
||||||
// Cij = \sum_k Aki Bjk, (Aᵀ * Bᵀ)
|
|
||||||
//
|
|
||||||
// This code computes one {i, j} block sequentially along the k dimension,
|
|
||||||
// and computes all of the {i, j} blocks concurrently. This
|
|
||||||
// partitioning allows Cij to be updated in-place without race-conditions.
|
|
||||||
// Instead of launching a goroutine for each possible concurrent computation,
|
|
||||||
// a number of worker goroutines are created and channels are used to pass
|
|
||||||
// available and completed cases.
|
|
||||||
//
|
|
||||||
// http://alexkr.com/docs/matrixmult.pdf is a good reference on matrix-matrix
|
|
||||||
// multiplies, though this code does not copy matrices to attempt to eliminate
|
|
||||||
// cache misses.
|
|
||||||
|
|
||||||
maxKLen := k
|
|
||||||
parBlocks := blocks(m, blockSize) * blocks(n, blockSize)
|
|
||||||
if parBlocks < minParBlock {
|
|
||||||
// The matrix multiplication is small in the dimensions where it can be
|
|
||||||
// computed concurrently. Just do it in serial.
|
|
||||||
dgemmSerial(aTrans, bTrans, m, n, k, a, lda, b, ldb, c, ldc, alpha)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
nWorkers := runtime.GOMAXPROCS(0)
|
|
||||||
if parBlocks < nWorkers {
|
|
||||||
nWorkers = parBlocks
|
|
||||||
}
|
|
||||||
// There is a tradeoff between the workers having to wait for work
|
|
||||||
// and a large buffer making operations slow.
|
|
||||||
buf := buffMul * nWorkers
|
|
||||||
if buf > parBlocks {
|
|
||||||
buf = parBlocks
|
|
||||||
}
|
|
||||||
|
|
||||||
sendChan := make(chan subMul, buf)
|
|
||||||
|
|
||||||
// Launch workers. A worker receives an {i, j} submatrix of c, and computes
|
|
||||||
// A_ik B_ki (or the transposed version) storing the result in c_ij. When the
|
|
||||||
// channel is finally closed, it signals to the waitgroup that it has finished
|
|
||||||
// computing.
|
|
||||||
var wg sync.WaitGroup
|
|
||||||
for i := 0; i < nWorkers; i++ {
|
|
||||||
wg.Add(1)
|
|
||||||
go func() {
|
|
||||||
defer wg.Done()
|
|
||||||
for sub := range sendChan {
|
|
||||||
i := sub.i
|
|
||||||
j := sub.j
|
|
||||||
leni := blockSize
|
|
||||||
if i+leni > m {
|
|
||||||
leni = m - i
|
|
||||||
}
|
|
||||||
lenj := blockSize
|
|
||||||
if j+lenj > n {
|
|
||||||
lenj = n - j
|
|
||||||
}
|
|
||||||
|
|
||||||
cSub := sliceView64(c, ldc, i, j, leni, lenj)
|
|
||||||
|
|
||||||
// Compute A_ik B_kj for all k
|
|
||||||
for k := 0; k < maxKLen; k += blockSize {
|
|
||||||
lenk := blockSize
|
|
||||||
if k+lenk > maxKLen {
|
|
||||||
lenk = maxKLen - k
|
|
||||||
}
|
|
||||||
var aSub, bSub []float64
|
|
||||||
if aTrans {
|
|
||||||
aSub = sliceView64(a, lda, k, i, lenk, leni)
|
|
||||||
} else {
|
|
||||||
aSub = sliceView64(a, lda, i, k, leni, lenk)
|
|
||||||
}
|
|
||||||
if bTrans {
|
|
||||||
bSub = sliceView64(b, ldb, j, k, lenj, lenk)
|
|
||||||
} else {
|
|
||||||
bSub = sliceView64(b, ldb, k, j, lenk, lenj)
|
|
||||||
}
|
|
||||||
dgemmSerial(aTrans, bTrans, leni, lenj, lenk, aSub, lda, bSub, ldb, cSub, ldc, alpha)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send out all of the {i, j} subblocks for computation.
|
|
||||||
for i := 0; i < m; i += blockSize {
|
|
||||||
for j := 0; j < n; j += blockSize {
|
|
||||||
sendChan <- subMul{
|
|
||||||
i: i,
|
|
||||||
j: j,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
close(sendChan)
|
|
||||||
wg.Wait()
|
|
||||||
}
|
|
||||||
|
|
||||||
// dgemmSerial is serial matrix multiply
|
|
||||||
func dgemmSerial(aTrans, bTrans bool, m, n, k int, a []float64, lda int, b []float64, ldb int, c []float64, ldc int, alpha float64) {
|
|
||||||
switch {
|
|
||||||
case !aTrans && !bTrans:
|
|
||||||
dgemmSerialNotNot(m, n, k, a, lda, b, ldb, c, ldc, alpha)
|
|
||||||
return
|
|
||||||
case aTrans && !bTrans:
|
|
||||||
dgemmSerialTransNot(m, n, k, a, lda, b, ldb, c, ldc, alpha)
|
|
||||||
return
|
|
||||||
case !aTrans && bTrans:
|
|
||||||
dgemmSerialNotTrans(m, n, k, a, lda, b, ldb, c, ldc, alpha)
|
|
||||||
return
|
|
||||||
case aTrans && bTrans:
|
|
||||||
dgemmSerialTransTrans(m, n, k, a, lda, b, ldb, c, ldc, alpha)
|
|
||||||
return
|
|
||||||
default:
|
|
||||||
panic("unreachable")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// dgemmSerial where neither a nor b are transposed
|
|
||||||
func dgemmSerialNotNot(m, n, k int, a []float64, lda int, b []float64, ldb int, c []float64, ldc int, alpha float64) {
|
|
||||||
// This style is used instead of the literal [i*stride +j]) is used because
|
|
||||||
// approximately 5 times faster as of go 1.3.
|
|
||||||
for i := 0; i < m; i++ {
|
|
||||||
ctmp := c[i*ldc : i*ldc+n]
|
|
||||||
for l, v := range a[i*lda : i*lda+k] {
|
|
||||||
tmp := alpha * v
|
|
||||||
if tmp != 0 {
|
|
||||||
f64.AxpyUnitary(tmp, b[l*ldb:l*ldb+n], ctmp)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// dgemmSerial where neither a is transposed and b is not
|
|
||||||
func dgemmSerialTransNot(m, n, k int, a []float64, lda int, b []float64, ldb int, c []float64, ldc int, alpha float64) {
|
|
||||||
// This style is used instead of the literal [i*stride +j]) is used because
|
|
||||||
// approximately 5 times faster as of go 1.3.
|
|
||||||
for l := 0; l < k; l++ {
|
|
||||||
btmp := b[l*ldb : l*ldb+n]
|
|
||||||
for i, v := range a[l*lda : l*lda+m] {
|
|
||||||
tmp := alpha * v
|
|
||||||
if tmp != 0 {
|
|
||||||
ctmp := c[i*ldc : i*ldc+n]
|
|
||||||
f64.AxpyUnitary(tmp, btmp, ctmp)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// dgemmSerial where neither a is not transposed and b is
|
|
||||||
func dgemmSerialNotTrans(m, n, k int, a []float64, lda int, b []float64, ldb int, c []float64, ldc int, alpha float64) {
|
|
||||||
// This style is used instead of the literal [i*stride +j]) is used because
|
|
||||||
// approximately 5 times faster as of go 1.3.
|
|
||||||
for i := 0; i < m; i++ {
|
|
||||||
atmp := a[i*lda : i*lda+k]
|
|
||||||
ctmp := c[i*ldc : i*ldc+n]
|
|
||||||
for j := 0; j < n; j++ {
|
|
||||||
ctmp[j] += alpha * f64.DotUnitary(atmp, b[j*ldb:j*ldb+k])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// dgemmSerial where both are transposed
|
|
||||||
func dgemmSerialTransTrans(m, n, k int, a []float64, lda int, b []float64, ldb int, c []float64, ldc int, alpha float64) {
|
|
||||||
// This style is used instead of the literal [i*stride +j]) is used because
|
|
||||||
// approximately 5 times faster as of go 1.3.
|
|
||||||
for l := 0; l < k; l++ {
|
|
||||||
for i, v := range a[l*lda : l*lda+m] {
|
|
||||||
tmp := alpha * v
|
|
||||||
if tmp != 0 {
|
|
||||||
ctmp := c[i*ldc : i*ldc+n]
|
|
||||||
f64.AxpyInc(tmp, b[l:], ctmp, uintptr(n), uintptr(ldb), 1, 0, 0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func sliceView64(a []float64, lda, i, j, r, c int) []float64 {
|
|
||||||
return a[i*lda+j : (i+r-1)*lda+j+c]
|
|
||||||
}
|
|
||||||
88
vendor/gonum.org/v1/gonum/blas/gonum/doc.go
generated
vendored
88
vendor/gonum.org/v1/gonum/blas/gonum/doc.go
generated
vendored
@@ -1,88 +0,0 @@
|
|||||||
// 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.
|
|
||||||
|
|
||||||
// Ensure changes made to blas/native are reflected in blas/cgo where relevant.
|
|
||||||
|
|
||||||
/*
|
|
||||||
Package gonum is a Go implementation of the BLAS API. This implementation
|
|
||||||
panics when the input arguments are invalid as per the standard, for example
|
|
||||||
if a vector increment is zero. Note that the treatment of NaN values
|
|
||||||
is not specified, and differs among the BLAS implementations.
|
|
||||||
gonum.org/v1/gonum/blas/blas64 provides helpful wrapper functions to the BLAS
|
|
||||||
interface. The rest of this text describes the layout of the data for the input types.
|
|
||||||
|
|
||||||
Note that in the function documentation, x[i] refers to the i^th element
|
|
||||||
of the vector, which will be different from the i^th element of the slice if
|
|
||||||
incX != 1.
|
|
||||||
|
|
||||||
See http://www.netlib.org/lapack/explore-html/d4/de1/_l_i_c_e_n_s_e_source.html
|
|
||||||
for more license information.
|
|
||||||
|
|
||||||
Vector arguments are effectively strided slices. They have two input arguments,
|
|
||||||
a number of elements, n, and an increment, incX. The increment specifies the
|
|
||||||
distance between elements of the vector. The actual Go slice may be longer
|
|
||||||
than necessary.
|
|
||||||
The increment may be positive or negative, except in functions with only
|
|
||||||
a single vector argument where the increment may only be positive. If the increment
|
|
||||||
is negative, s[0] is the last element in the slice. Note that this is not the same
|
|
||||||
as counting backward from the end of the slice, as len(s) may be longer than
|
|
||||||
necessary. So, for example, if n = 5 and incX = 3, the elements of s are
|
|
||||||
[0 * * 1 * * 2 * * 3 * * 4 * * * ...]
|
|
||||||
where ∗ elements are never accessed. If incX = -3, the same elements are
|
|
||||||
accessed, just in reverse order (4, 3, 2, 1, 0).
|
|
||||||
|
|
||||||
Dense matrices are specified by a number of rows, a number of columns, and a stride.
|
|
||||||
The stride specifies the number of entries in the slice between the first element
|
|
||||||
of successive rows. The stride must be at least as large as the number of columns
|
|
||||||
but may be longer.
|
|
||||||
[a00 ... a0n a0* ... a1stride-1 a21 ... amn am* ... amstride-1]
|
|
||||||
Thus, dense[i*ld + j] refers to the {i, j}th element of the matrix.
|
|
||||||
|
|
||||||
Symmetric and triangular matrices (non-packed) are stored identically to Dense,
|
|
||||||
except that only elements in one triangle of the matrix are accessed.
|
|
||||||
|
|
||||||
Packed symmetric and packed triangular matrices are laid out with the entries
|
|
||||||
condensed such that all of the unreferenced elements are removed. So, the upper triangular
|
|
||||||
matrix
|
|
||||||
[
|
|
||||||
1 2 3
|
|
||||||
0 4 5
|
|
||||||
0 0 6
|
|
||||||
]
|
|
||||||
and the lower-triangular matrix
|
|
||||||
[
|
|
||||||
1 0 0
|
|
||||||
2 3 0
|
|
||||||
4 5 6
|
|
||||||
]
|
|
||||||
will both be compacted as [1 2 3 4 5 6]. The (i, j) element of the original
|
|
||||||
dense matrix can be found at element i*n - (i-1)*i/2 + j for upper triangular,
|
|
||||||
and at element i * (i+1) /2 + j for lower triangular.
|
|
||||||
|
|
||||||
Banded matrices are laid out in a compact format, constructed by removing the
|
|
||||||
zeros in the rows and aligning the diagonals. For example, the matrix
|
|
||||||
[
|
|
||||||
1 2 3 0 0 0
|
|
||||||
4 5 6 7 0 0
|
|
||||||
0 8 9 10 11 0
|
|
||||||
0 0 12 13 14 15
|
|
||||||
0 0 0 16 17 18
|
|
||||||
0 0 0 0 19 20
|
|
||||||
]
|
|
||||||
|
|
||||||
implicitly becomes (∗ entries are never accessed)
|
|
||||||
[
|
|
||||||
* 1 2 3
|
|
||||||
4 5 6 7
|
|
||||||
8 9 10 11
|
|
||||||
12 13 14 15
|
|
||||||
16 17 18 *
|
|
||||||
19 20 * *
|
|
||||||
]
|
|
||||||
which is given to the BLAS routine as [∗ 1 2 3 4 ...].
|
|
||||||
|
|
||||||
See http://www.crest.iu.edu/research/mtl/reference/html/banded.html
|
|
||||||
for more information
|
|
||||||
*/
|
|
||||||
package gonum // import "gonum.org/v1/gonum/blas/gonum"
|
|
||||||
35
vendor/gonum.org/v1/gonum/blas/gonum/errors.go
generated
vendored
35
vendor/gonum.org/v1/gonum/blas/gonum/errors.go
generated
vendored
@@ -1,35 +0,0 @@
|
|||||||
// 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"
|
|
||||||
)
|
|
||||||
190
vendor/gonum.org/v1/gonum/blas/gonum/gemv.go
generated
vendored
190
vendor/gonum.org/v1/gonum/blas/gonum/gemv.go
generated
vendored
@@ -1,190 +0,0 @@
|
|||||||
// 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 gonum
|
|
||||||
|
|
||||||
import (
|
|
||||||
"gonum.org/v1/gonum/blas"
|
|
||||||
"gonum.org/v1/gonum/internal/asm/f32"
|
|
||||||
"gonum.org/v1/gonum/internal/asm/f64"
|
|
||||||
)
|
|
||||||
|
|
||||||
// TODO(Kunde21): Merge these methods back into level2double/level2single when Sgemv assembly kernels are merged into f32.
|
|
||||||
|
|
||||||
// Dgemv computes
|
|
||||||
// y = alpha * A * x + beta * y if tA = blas.NoTrans
|
|
||||||
// y = alpha * Aᵀ * x + beta * y if tA = blas.Trans or blas.ConjTrans
|
|
||||||
// where A is an m×n dense matrix, x and y are vectors, and alpha and beta are scalars.
|
|
||||||
func (Implementation) Dgemv(tA blas.Transpose, m, n int, alpha float64, a []float64, lda int, x []float64, incX int, beta float64, y []float64, incY int) {
|
|
||||||
if tA != blas.NoTrans && tA != blas.Trans && tA != blas.ConjTrans {
|
|
||||||
panic(badTranspose)
|
|
||||||
}
|
|
||||||
if 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)
|
|
||||||
}
|
|
||||||
// Set up indexes
|
|
||||||
lenX := m
|
|
||||||
lenY := n
|
|
||||||
if tA == blas.NoTrans {
|
|
||||||
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(shortX)
|
|
||||||
}
|
|
||||||
if (incY > 0 && (lenY-1)*incY >= len(y)) || (incY < 0 && (1-lenY)*incY >= len(y)) {
|
|
||||||
panic(shortY)
|
|
||||||
}
|
|
||||||
if len(a) < lda*(m-1)+n {
|
|
||||||
panic(shortA)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Quick return if possible
|
|
||||||
if alpha == 0 && beta == 1 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if alpha == 0 {
|
|
||||||
// First form y = beta * y
|
|
||||||
if incY > 0 {
|
|
||||||
Implementation{}.Dscal(lenY, beta, y, incY)
|
|
||||||
} else {
|
|
||||||
Implementation{}.Dscal(lenY, beta, y, -incY)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Form y = alpha * A * x + y
|
|
||||||
if tA == blas.NoTrans {
|
|
||||||
f64.GemvN(uintptr(m), uintptr(n), alpha, a, uintptr(lda), x, uintptr(incX), beta, y, uintptr(incY))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// Cases where a is transposed.
|
|
||||||
f64.GemvT(uintptr(m), uintptr(n), alpha, a, uintptr(lda), x, uintptr(incX), beta, y, uintptr(incY))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sgemv computes
|
|
||||||
// y = alpha * A * x + beta * y if tA = blas.NoTrans
|
|
||||||
// y = alpha * Aᵀ * x + beta * y if tA = blas.Trans or blas.ConjTrans
|
|
||||||
// where A is an m×n dense matrix, x and y are vectors, and alpha and beta are scalars.
|
|
||||||
//
|
|
||||||
// Float32 implementations are autogenerated and not directly tested.
|
|
||||||
func (Implementation) Sgemv(tA blas.Transpose, m, n int, alpha float32, a []float32, lda int, x []float32, incX int, beta float32, y []float32, incY int) {
|
|
||||||
if tA != blas.NoTrans && tA != blas.Trans && tA != blas.ConjTrans {
|
|
||||||
panic(badTranspose)
|
|
||||||
}
|
|
||||||
if 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)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Quick return if possible.
|
|
||||||
if m == 0 || n == 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set up indexes
|
|
||||||
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(shortX)
|
|
||||||
}
|
|
||||||
if (incY > 0 && (lenY-1)*incY >= len(y)) || (incY < 0 && (1-lenY)*incY >= len(y)) {
|
|
||||||
panic(shortY)
|
|
||||||
}
|
|
||||||
if len(a) < lda*(m-1)+n {
|
|
||||||
panic(shortA)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Quick return if possible.
|
|
||||||
if alpha == 0 && beta == 1 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// First form y = beta * y
|
|
||||||
if incY > 0 {
|
|
||||||
Implementation{}.Sscal(lenY, beta, y, incY)
|
|
||||||
} else {
|
|
||||||
Implementation{}.Sscal(lenY, beta, y, -incY)
|
|
||||||
}
|
|
||||||
|
|
||||||
if alpha == 0 {
|
|
||||||
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[:n])
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
iy := ky
|
|
||||||
for i := 0; i < m; i++ {
|
|
||||||
y[iy] += alpha * f32.DotInc(x, a[lda*i:lda*i+n], uintptr(n), uintptr(incX), 1, uintptr(kx), 0)
|
|
||||||
iy += incY
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// Cases where a is transposed.
|
|
||||||
if incX == 1 && incY == 1 {
|
|
||||||
for i := 0; i < m; i++ {
|
|
||||||
tmp := alpha * x[i]
|
|
||||||
if tmp != 0 {
|
|
||||||
f32.AxpyUnitaryTo(y, tmp, a[lda*i:lda*i+n], y[:n])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
ix := kx
|
|
||||||
for i := 0; i < m; i++ {
|
|
||||||
tmp := alpha * x[ix]
|
|
||||||
if tmp != 0 {
|
|
||||||
f32.AxpyInc(tmp, a[lda*i:lda*i+n], y, uintptr(n), 1, uintptr(incY), 0, uintptr(ky))
|
|
||||||
}
|
|
||||||
ix += incX
|
|
||||||
}
|
|
||||||
}
|
|
||||||
58
vendor/gonum.org/v1/gonum/blas/gonum/gonum.go
generated
vendored
58
vendor/gonum.org/v1/gonum/blas/gonum/gonum.go
generated
vendored
@@ -1,58 +0,0 @@
|
|||||||
// 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.
|
|
||||||
|
|
||||||
//go:generate ./single_precision.bash
|
|
||||||
|
|
||||||
package gonum
|
|
||||||
|
|
||||||
import (
|
|
||||||
"math"
|
|
||||||
|
|
||||||
"gonum.org/v1/gonum/internal/math32"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Implementation struct{}
|
|
||||||
|
|
||||||
// [SD]gemm behavior constants. These are kept here to keep them out of the
|
|
||||||
// way during single precision code genration.
|
|
||||||
const (
|
|
||||||
blockSize = 64 // b x b matrix
|
|
||||||
minParBlock = 4 // minimum number of blocks needed to go parallel
|
|
||||||
buffMul = 4 // how big is the buffer relative to the number of workers
|
|
||||||
)
|
|
||||||
|
|
||||||
// subMul is a common type shared by [SD]gemm.
|
|
||||||
type subMul struct {
|
|
||||||
i, j int // index of block
|
|
||||||
}
|
|
||||||
|
|
||||||
func max(a, b int) int {
|
|
||||||
if a > b {
|
|
||||||
return a
|
|
||||||
}
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
|
|
||||||
func min(a, b int) int {
|
|
||||||
if a > b {
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
return a
|
|
||||||
}
|
|
||||||
|
|
||||||
// blocks returns the number of divisions of the dimension length with the given
|
|
||||||
// block size.
|
|
||||||
func blocks(dim, bsize int) int {
|
|
||||||
return (dim + bsize - 1) / bsize
|
|
||||||
}
|
|
||||||
|
|
||||||
// dcabs1 returns |real(z)|+|imag(z)|.
|
|
||||||
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))
|
|
||||||
}
|
|
||||||
445
vendor/gonum.org/v1/gonum/blas/gonum/level1cmplx128.go
generated
vendored
445
vendor/gonum.org/v1/gonum/blas/gonum/level1cmplx128.go
generated
vendored
@@ -1,445 +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 (
|
|
||||||
"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.
|
|
||||||
func (Implementation) Dzasum(n int, x []complex128, incX int) float64 {
|
|
||||||
if n < 0 {
|
|
||||||
panic(nLT0)
|
|
||||||
}
|
|
||||||
if incX < 1 {
|
|
||||||
if incX == 0 {
|
|
||||||
panic(zeroIncX)
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
var sum float64
|
|
||||||
if incX == 1 {
|
|
||||||
if len(x) < n {
|
|
||||||
panic(shortX)
|
|
||||||
}
|
|
||||||
for _, v := range x[:n] {
|
|
||||||
sum += dcabs1(v)
|
|
||||||
}
|
|
||||||
return sum
|
|
||||||
}
|
|
||||||
if (n-1)*incX >= len(x) {
|
|
||||||
panic(shortX)
|
|
||||||
}
|
|
||||||
for i := 0; i < n; i++ {
|
|
||||||
v := x[i*incX]
|
|
||||||
sum += dcabs1(v)
|
|
||||||
}
|
|
||||||
return sum
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dznrm2 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.
|
|
||||||
func (Implementation) Dznrm2(n int, x []complex128, incX int) float64 {
|
|
||||||
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 float64
|
|
||||||
ssq float64 = 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)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Izamax returns the index of the first element of x having largest |Re(·)|+|Im(·)|.
|
|
||||||
// Izamax returns -1 if n is 0 or incX is negative.
|
|
||||||
func (Implementation) Izamax(n int, x []complex128, 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 := dcabs1(x[0])
|
|
||||||
if incX == 1 {
|
|
||||||
for i, v := range x[1:n] {
|
|
||||||
absV := dcabs1(v)
|
|
||||||
if absV > max {
|
|
||||||
max = absV
|
|
||||||
idx = i + 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return idx
|
|
||||||
}
|
|
||||||
ix := incX
|
|
||||||
for i := 1; i < n; i++ {
|
|
||||||
absV := dcabs1(x[ix])
|
|
||||||
if absV > max {
|
|
||||||
max = absV
|
|
||||||
idx = i
|
|
||||||
}
|
|
||||||
ix += incX
|
|
||||||
}
|
|
||||||
return idx
|
|
||||||
}
|
|
||||||
|
|
||||||
// Zaxpy adds alpha times x to y:
|
|
||||||
// y[i] += alpha * x[i] for all i
|
|
||||||
func (Implementation) Zaxpy(n int, alpha complex128, x []complex128, incX int, y []complex128, 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 {
|
|
||||||
c128.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
|
|
||||||
}
|
|
||||||
c128.AxpyInc(alpha, x, y, uintptr(n), uintptr(incX), uintptr(incY), uintptr(ix), uintptr(iy))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Zcopy copies the vector x to vector y.
|
|
||||||
func (Implementation) Zcopy(n int, x []complex128, incX int, y []complex128, 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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Zdotc computes the dot product
|
|
||||||
// xᴴ · y
|
|
||||||
// of two complex vectors x and y.
|
|
||||||
func (Implementation) Zdotc(n int, x []complex128, incX int, y []complex128, incY int) complex128 {
|
|
||||||
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 c128.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 c128.DotcInc(x, y, uintptr(n), uintptr(incX), uintptr(incY), uintptr(ix), uintptr(iy))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Zdotu computes the dot product
|
|
||||||
// xᵀ · y
|
|
||||||
// of two complex vectors x and y.
|
|
||||||
func (Implementation) Zdotu(n int, x []complex128, incX int, y []complex128, incY int) complex128 {
|
|
||||||
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 c128.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 c128.DotuInc(x, y, uintptr(n), uintptr(incX), uintptr(incY), uintptr(ix), uintptr(iy))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Zdscal scales the vector x by a real scalar alpha.
|
|
||||||
// Zdscal has no effect if incX < 0.
|
|
||||||
func (Implementation) Zdscal(n int, alpha float64, x []complex128, 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))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Zscal scales the vector x by a complex scalar alpha.
|
|
||||||
// Zscal has no effect if incX < 0.
|
|
||||||
func (Implementation) Zscal(n int, alpha complex128, x []complex128, 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 {
|
|
||||||
c128.ScalUnitary(alpha, x[:n])
|
|
||||||
return
|
|
||||||
}
|
|
||||||
c128.ScalInc(alpha, x, uintptr(n), uintptr(incX))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Zswap exchanges the elements of two complex vectors x and y.
|
|
||||||
func (Implementation) Zswap(n int, x []complex128, incX int, y []complex128, 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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
467
vendor/gonum.org/v1/gonum/blas/gonum/level1cmplx64.go
generated
vendored
467
vendor/gonum.org/v1/gonum/blas/gonum/level1cmplx64.go
generated
vendored
@@ -1,467 +0,0 @@
|
|||||||
// 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ᴴ · 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ᵀ · 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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
644
vendor/gonum.org/v1/gonum/blas/gonum/level1float32.go
generated
vendored
644
vendor/gonum.org/v1/gonum/blas/gonum/level1float32.go
generated
vendored
@@ -1,644 +0,0 @@
|
|||||||
// Code generated by "go generate gonum.org/v1/gonum/blas/gonum”; 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 gonum
|
|
||||||
|
|
||||||
import (
|
|
||||||
math "gonum.org/v1/gonum/internal/math32"
|
|
||||||
|
|
||||||
"gonum.org/v1/gonum/blas"
|
|
||||||
"gonum.org/v1/gonum/internal/asm/f32"
|
|
||||||
)
|
|
||||||
|
|
||||||
var _ blas.Float32Level1 = Implementation{}
|
|
||||||
|
|
||||||
// Snrm2 computes the Euclidean norm of a vector,
|
|
||||||
// sqrt(\sum_i x[i] * x[i]).
|
|
||||||
// This function returns 0 if incX is negative.
|
|
||||||
//
|
|
||||||
// Float32 implementations are autogenerated and not directly tested.
|
|
||||||
func (Implementation) Snrm2(n int, x []float32, incX int) float32 {
|
|
||||||
if incX < 1 {
|
|
||||||
if incX == 0 {
|
|
||||||
panic(zeroIncX)
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
if len(x) <= (n-1)*incX {
|
|
||||||
panic(shortX)
|
|
||||||
}
|
|
||||||
if n < 2 {
|
|
||||||
if n == 1 {
|
|
||||||
return math.Abs(x[0])
|
|
||||||
}
|
|
||||||
if n == 0 {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
panic(nLT0)
|
|
||||||
}
|
|
||||||
var (
|
|
||||||
scale float32 = 0
|
|
||||||
sumSquares float32 = 1
|
|
||||||
)
|
|
||||||
if incX == 1 {
|
|
||||||
x = x[:n]
|
|
||||||
for _, v := range x {
|
|
||||||
if v == 0 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
absxi := math.Abs(v)
|
|
||||||
if math.IsNaN(absxi) {
|
|
||||||
return math.NaN()
|
|
||||||
}
|
|
||||||
if scale < absxi {
|
|
||||||
sumSquares = 1 + sumSquares*(scale/absxi)*(scale/absxi)
|
|
||||||
scale = absxi
|
|
||||||
} else {
|
|
||||||
sumSquares = sumSquares + (absxi/scale)*(absxi/scale)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if math.IsInf(scale, 1) {
|
|
||||||
return math.Inf(1)
|
|
||||||
}
|
|
||||||
return scale * math.Sqrt(sumSquares)
|
|
||||||
}
|
|
||||||
for ix := 0; ix < n*incX; ix += incX {
|
|
||||||
val := x[ix]
|
|
||||||
if val == 0 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
absxi := math.Abs(val)
|
|
||||||
if math.IsNaN(absxi) {
|
|
||||||
return math.NaN()
|
|
||||||
}
|
|
||||||
if scale < absxi {
|
|
||||||
sumSquares = 1 + sumSquares*(scale/absxi)*(scale/absxi)
|
|
||||||
scale = absxi
|
|
||||||
} else {
|
|
||||||
sumSquares = sumSquares + (absxi/scale)*(absxi/scale)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if math.IsInf(scale, 1) {
|
|
||||||
return math.Inf(1)
|
|
||||||
}
|
|
||||||
return scale * math.Sqrt(sumSquares)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sasum computes the sum of the absolute values of the elements of x.
|
|
||||||
// \sum_i |x[i]|
|
|
||||||
// Sasum returns 0 if incX is negative.
|
|
||||||
//
|
|
||||||
// Float32 implementations are autogenerated and not directly tested.
|
|
||||||
func (Implementation) Sasum(n int, x []float32, incX int) float32 {
|
|
||||||
var sum float32
|
|
||||||
if n < 0 {
|
|
||||||
panic(nLT0)
|
|
||||||
}
|
|
||||||
if incX < 1 {
|
|
||||||
if incX == 0 {
|
|
||||||
panic(zeroIncX)
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
if len(x) <= (n-1)*incX {
|
|
||||||
panic(shortX)
|
|
||||||
}
|
|
||||||
if incX == 1 {
|
|
||||||
x = x[:n]
|
|
||||||
for _, v := range x {
|
|
||||||
sum += math.Abs(v)
|
|
||||||
}
|
|
||||||
return sum
|
|
||||||
}
|
|
||||||
for i := 0; i < n; i++ {
|
|
||||||
sum += math.Abs(x[i*incX])
|
|
||||||
}
|
|
||||||
return sum
|
|
||||||
}
|
|
||||||
|
|
||||||
// Isamax returns the index of an element of x with the largest absolute value.
|
|
||||||
// If there are multiple such indices the earliest is returned.
|
|
||||||
// Isamax returns -1 if n == 0.
|
|
||||||
//
|
|
||||||
// Float32 implementations are autogenerated and not directly tested.
|
|
||||||
func (Implementation) Isamax(n int, x []float32, incX int) int {
|
|
||||||
if incX < 1 {
|
|
||||||
if incX == 0 {
|
|
||||||
panic(zeroIncX)
|
|
||||||
}
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
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.
|
|
||||||
}
|
|
||||||
panic(nLT0)
|
|
||||||
}
|
|
||||||
idx := 0
|
|
||||||
max := math.Abs(x[0])
|
|
||||||
if incX == 1 {
|
|
||||||
for i, v := range x[:n] {
|
|
||||||
absV := math.Abs(v)
|
|
||||||
if absV > max {
|
|
||||||
max = absV
|
|
||||||
idx = i
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return idx
|
|
||||||
}
|
|
||||||
ix := incX
|
|
||||||
for i := 1; i < n; i++ {
|
|
||||||
v := x[ix]
|
|
||||||
absV := math.Abs(v)
|
|
||||||
if absV > max {
|
|
||||||
max = absV
|
|
||||||
idx = i
|
|
||||||
}
|
|
||||||
ix += incX
|
|
||||||
}
|
|
||||||
return idx
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sswap exchanges the elements of two vectors.
|
|
||||||
// x[i], y[i] = y[i], x[i] for all i
|
|
||||||
//
|
|
||||||
// Float32 implementations are autogenerated and not directly tested.
|
|
||||||
func (Implementation) Sswap(n int, x []float32, incX int, y []float32, incY int) {
|
|
||||||
if incX == 0 {
|
|
||||||
panic(zeroIncX)
|
|
||||||
}
|
|
||||||
if incY == 0 {
|
|
||||||
panic(zeroIncY)
|
|
||||||
}
|
|
||||||
if n < 1 {
|
|
||||||
if n == 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
panic(nLT0)
|
|
||||||
}
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Scopy copies the elements of x into the elements of y.
|
|
||||||
// y[i] = x[i] for all i
|
|
||||||
//
|
|
||||||
// Float32 implementations are autogenerated and not directly tested.
|
|
||||||
func (Implementation) Scopy(n int, x []float32, incX int, y []float32, incY int) {
|
|
||||||
if incX == 0 {
|
|
||||||
panic(zeroIncX)
|
|
||||||
}
|
|
||||||
if incY == 0 {
|
|
||||||
panic(zeroIncY)
|
|
||||||
}
|
|
||||||
if n < 1 {
|
|
||||||
if n == 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
panic(nLT0)
|
|
||||||
}
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Saxpy adds alpha times x to y
|
|
||||||
// y[i] += alpha * x[i] for all i
|
|
||||||
//
|
|
||||||
// Float32 implementations are autogenerated and not directly tested.
|
|
||||||
func (Implementation) Saxpy(n int, alpha float32, x []float32, incX int, y []float32, incY int) {
|
|
||||||
if incX == 0 {
|
|
||||||
panic(zeroIncX)
|
|
||||||
}
|
|
||||||
if incY == 0 {
|
|
||||||
panic(zeroIncY)
|
|
||||||
}
|
|
||||||
if n < 1 {
|
|
||||||
if n == 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
panic(nLT0)
|
|
||||||
}
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
if alpha == 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if incX == 1 && incY == 1 {
|
|
||||||
f32.AxpyUnitary(alpha, x[:n], y[:n])
|
|
||||||
return
|
|
||||||
}
|
|
||||||
var ix, iy int
|
|
||||||
if incX < 0 {
|
|
||||||
ix = (-n + 1) * incX
|
|
||||||
}
|
|
||||||
if incY < 0 {
|
|
||||||
iy = (-n + 1) * incY
|
|
||||||
}
|
|
||||||
f32.AxpyInc(alpha, x, y, uintptr(n), uintptr(incX), uintptr(incY), uintptr(ix), uintptr(iy))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Srotg computes the plane rotation
|
|
||||||
// _ _ _ _ _ _
|
|
||||||
// | c s | | a | | r |
|
|
||||||
// | -s c | * | b | = | 0 |
|
|
||||||
// ‾ ‾ ‾ ‾ ‾ ‾
|
|
||||||
// where
|
|
||||||
// r = ±√(a^2 + b^2)
|
|
||||||
// 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 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.
|
|
||||||
//
|
|
||||||
// Float32 implementations are autogenerated and not directly tested.
|
|
||||||
func (Implementation) Srotg(a, b float32) (c, s, r, z float32) {
|
|
||||||
if b == 0 && a == 0 {
|
|
||||||
return 1, 0, a, 0
|
|
||||||
}
|
|
||||||
absA := math.Abs(a)
|
|
||||||
absB := math.Abs(b)
|
|
||||||
aGTb := absA > absB
|
|
||||||
r = math.Hypot(a, b)
|
|
||||||
if aGTb {
|
|
||||||
r = math.Copysign(r, a)
|
|
||||||
} else {
|
|
||||||
r = math.Copysign(r, b)
|
|
||||||
}
|
|
||||||
c = a / r
|
|
||||||
s = b / r
|
|
||||||
if aGTb {
|
|
||||||
z = s
|
|
||||||
} else if c != 0 { // r == 0 case handled above
|
|
||||||
z = 1 / c
|
|
||||||
} else {
|
|
||||||
z = 1
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Srotmg computes the modified Givens rotation. See
|
|
||||||
// http://www.netlib.org/lapack/explore-html/df/deb/drotmg_8f.html
|
|
||||||
// for more details.
|
|
||||||
//
|
|
||||||
// Float32 implementations are autogenerated and not directly tested.
|
|
||||||
func (Implementation) Srotmg(d1, d2, x1, y1 float32) (p blas.SrotmParams, rd1, rd2, rx1 float32) {
|
|
||||||
// The implementation of Drotmg used here is taken from Hopkins 1997
|
|
||||||
// Appendix A: https://doi.org/10.1145/289251.289253
|
|
||||||
// with the exception of the gam constants below.
|
|
||||||
|
|
||||||
const (
|
|
||||||
gam = 4096.0
|
|
||||||
gamsq = gam * gam
|
|
||||||
rgamsq = 1.0 / gamsq
|
|
||||||
)
|
|
||||||
|
|
||||||
if d1 < 0 {
|
|
||||||
p.Flag = blas.Rescaling // Error state.
|
|
||||||
return p, 0, 0, 0
|
|
||||||
}
|
|
||||||
|
|
||||||
if d2 == 0 || y1 == 0 {
|
|
||||||
p.Flag = blas.Identity
|
|
||||||
return p, d1, d2, x1
|
|
||||||
}
|
|
||||||
|
|
||||||
var h11, h12, h21, h22 float32
|
|
||||||
if (d1 == 0 || x1 == 0) && d2 > 0 {
|
|
||||||
p.Flag = blas.Diagonal
|
|
||||||
h12 = 1
|
|
||||||
h21 = -1
|
|
||||||
x1 = y1
|
|
||||||
d1, d2 = d2, d1
|
|
||||||
} else {
|
|
||||||
p2 := d2 * y1
|
|
||||||
p1 := d1 * x1
|
|
||||||
q2 := p2 * y1
|
|
||||||
q1 := p1 * x1
|
|
||||||
if math.Abs(q1) > math.Abs(q2) {
|
|
||||||
p.Flag = blas.OffDiagonal
|
|
||||||
h11 = 1
|
|
||||||
h22 = 1
|
|
||||||
h21 = -y1 / x1
|
|
||||||
h12 = p2 / p1
|
|
||||||
u := 1 - h12*h21
|
|
||||||
if u <= 0 {
|
|
||||||
p.Flag = blas.Rescaling // Error state.
|
|
||||||
return p, 0, 0, 0
|
|
||||||
}
|
|
||||||
|
|
||||||
d1 /= u
|
|
||||||
d2 /= u
|
|
||||||
x1 *= u
|
|
||||||
} else {
|
|
||||||
if q2 < 0 {
|
|
||||||
p.Flag = blas.Rescaling // Error state.
|
|
||||||
return p, 0, 0, 0
|
|
||||||
}
|
|
||||||
|
|
||||||
p.Flag = blas.Diagonal
|
|
||||||
h21 = -1
|
|
||||||
h12 = 1
|
|
||||||
h11 = p1 / p2
|
|
||||||
h22 = x1 / y1
|
|
||||||
u := 1 + h11*h22
|
|
||||||
d1, d2 = d2/u, d1/u
|
|
||||||
x1 = y1 * u
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for d1 <= rgamsq && d1 != 0 {
|
|
||||||
p.Flag = blas.Rescaling
|
|
||||||
d1 = (d1 * gam) * gam
|
|
||||||
x1 /= gam
|
|
||||||
h11 /= gam
|
|
||||||
h12 /= gam
|
|
||||||
}
|
|
||||||
for d1 > gamsq {
|
|
||||||
p.Flag = blas.Rescaling
|
|
||||||
d1 = (d1 / gam) / gam
|
|
||||||
x1 *= gam
|
|
||||||
h11 *= gam
|
|
||||||
h12 *= gam
|
|
||||||
}
|
|
||||||
|
|
||||||
for math.Abs(d2) <= rgamsq && d2 != 0 {
|
|
||||||
p.Flag = blas.Rescaling
|
|
||||||
d2 = (d2 * gam) * gam
|
|
||||||
h21 /= gam
|
|
||||||
h22 /= gam
|
|
||||||
}
|
|
||||||
for math.Abs(d2) > gamsq {
|
|
||||||
p.Flag = blas.Rescaling
|
|
||||||
d2 = (d2 / gam) / gam
|
|
||||||
h21 *= gam
|
|
||||||
h22 *= gam
|
|
||||||
}
|
|
||||||
|
|
||||||
switch p.Flag {
|
|
||||||
case blas.Diagonal:
|
|
||||||
p.H = [4]float32{0: h11, 3: h22}
|
|
||||||
case blas.OffDiagonal:
|
|
||||||
p.H = [4]float32{1: h21, 2: h12}
|
|
||||||
case blas.Rescaling:
|
|
||||||
p.H = [4]float32{h11, h21, h12, h22}
|
|
||||||
default:
|
|
||||||
panic(badFlag)
|
|
||||||
}
|
|
||||||
|
|
||||||
return p, d1, d2, x1
|
|
||||||
}
|
|
||||||
|
|
||||||
// Srot applies a plane transformation.
|
|
||||||
// x[i] = c * x[i] + s * y[i]
|
|
||||||
// y[i] = c * y[i] - s * x[i]
|
|
||||||
//
|
|
||||||
// Float32 implementations are autogenerated and not directly tested.
|
|
||||||
func (Implementation) Srot(n int, x []float32, incX int, y []float32, incY int, c float32, s float32) {
|
|
||||||
if incX == 0 {
|
|
||||||
panic(zeroIncX)
|
|
||||||
}
|
|
||||||
if incY == 0 {
|
|
||||||
panic(zeroIncY)
|
|
||||||
}
|
|
||||||
if n < 1 {
|
|
||||||
if n == 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
panic(nLT0)
|
|
||||||
}
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
if incX == 1 && incY == 1 {
|
|
||||||
x = x[:n]
|
|
||||||
for i, vx := range x {
|
|
||||||
vy := y[i]
|
|
||||||
x[i], y[i] = c*vx+s*vy, c*vy-s*vx
|
|
||||||
}
|
|
||||||
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++ {
|
|
||||||
vx := x[ix]
|
|
||||||
vy := y[iy]
|
|
||||||
x[ix], y[iy] = c*vx+s*vy, c*vy-s*vx
|
|
||||||
ix += incX
|
|
||||||
iy += incY
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Srotm applies the modified Givens rotation to the 2×n matrix.
|
|
||||||
//
|
|
||||||
// Float32 implementations are autogenerated and not directly tested.
|
|
||||||
func (Implementation) Srotm(n int, x []float32, incX int, y []float32, incY int, p blas.SrotmParams) {
|
|
||||||
if incX == 0 {
|
|
||||||
panic(zeroIncX)
|
|
||||||
}
|
|
||||||
if incY == 0 {
|
|
||||||
panic(zeroIncY)
|
|
||||||
}
|
|
||||||
if n <= 0 {
|
|
||||||
if n == 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
panic(nLT0)
|
|
||||||
}
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
|
|
||||||
if p.Flag == blas.Identity {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
switch p.Flag {
|
|
||||||
case blas.Rescaling:
|
|
||||||
h11 := p.H[0]
|
|
||||||
h12 := p.H[2]
|
|
||||||
h21 := p.H[1]
|
|
||||||
h22 := p.H[3]
|
|
||||||
if incX == 1 && incY == 1 {
|
|
||||||
x = x[:n]
|
|
||||||
for i, vx := range x {
|
|
||||||
vy := y[i]
|
|
||||||
x[i], y[i] = vx*h11+vy*h12, vx*h21+vy*h22
|
|
||||||
}
|
|
||||||
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++ {
|
|
||||||
vx := x[ix]
|
|
||||||
vy := y[iy]
|
|
||||||
x[ix], y[iy] = vx*h11+vy*h12, vx*h21+vy*h22
|
|
||||||
ix += incX
|
|
||||||
iy += incY
|
|
||||||
}
|
|
||||||
case blas.OffDiagonal:
|
|
||||||
h12 := p.H[2]
|
|
||||||
h21 := p.H[1]
|
|
||||||
if incX == 1 && incY == 1 {
|
|
||||||
x = x[:n]
|
|
||||||
for i, vx := range x {
|
|
||||||
vy := y[i]
|
|
||||||
x[i], y[i] = vx+vy*h12, vx*h21+vy
|
|
||||||
}
|
|
||||||
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++ {
|
|
||||||
vx := x[ix]
|
|
||||||
vy := y[iy]
|
|
||||||
x[ix], y[iy] = vx+vy*h12, vx*h21+vy
|
|
||||||
ix += incX
|
|
||||||
iy += incY
|
|
||||||
}
|
|
||||||
case blas.Diagonal:
|
|
||||||
h11 := p.H[0]
|
|
||||||
h22 := p.H[3]
|
|
||||||
if incX == 1 && incY == 1 {
|
|
||||||
x = x[:n]
|
|
||||||
for i, vx := range x {
|
|
||||||
vy := y[i]
|
|
||||||
x[i], y[i] = vx*h11+vy, -vx+vy*h22
|
|
||||||
}
|
|
||||||
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++ {
|
|
||||||
vx := x[ix]
|
|
||||||
vy := y[iy]
|
|
||||||
x[ix], y[iy] = vx*h11+vy, -vx+vy*h22
|
|
||||||
ix += incX
|
|
||||||
iy += incY
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sscal scales x by alpha.
|
|
||||||
// x[i] *= alpha
|
|
||||||
// Sscal has no effect if incX < 0.
|
|
||||||
//
|
|
||||||
// Float32 implementations are autogenerated and not directly tested.
|
|
||||||
func (Implementation) Sscal(n int, alpha float32, x []float32, incX int) {
|
|
||||||
if incX < 1 {
|
|
||||||
if incX == 0 {
|
|
||||||
panic(zeroIncX)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
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]
|
|
||||||
for i := range x {
|
|
||||||
x[i] = 0
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for ix := 0; ix < n*incX; ix += incX {
|
|
||||||
x[ix] = 0
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if incX == 1 {
|
|
||||||
f32.ScalUnitary(alpha, x[:n])
|
|
||||||
return
|
|
||||||
}
|
|
||||||
f32.ScalInc(alpha, x, uintptr(n), uintptr(incX))
|
|
||||||
}
|
|
||||||
53
vendor/gonum.org/v1/gonum/blas/gonum/level1float32_dsdot.go
generated
vendored
53
vendor/gonum.org/v1/gonum/blas/gonum/level1float32_dsdot.go
generated
vendored
@@ -1,53 +0,0 @@
|
|||||||
// Code generated by "go generate gonum.org/v1/gonum/blas/gonum”; 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 gonum
|
|
||||||
|
|
||||||
import (
|
|
||||||
"gonum.org/v1/gonum/internal/asm/f32"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Dsdot computes the dot product of the two vectors
|
|
||||||
// \sum_i x[i]*y[i]
|
|
||||||
//
|
|
||||||
// Float32 implementations are autogenerated and not directly tested.
|
|
||||||
func (Implementation) Dsdot(n int, x []float32, incX int, y []float32, incY int) float64 {
|
|
||||||
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 f32.DdotUnitary(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) || ix+(n-1)*incX >= len(x) {
|
|
||||||
panic(shortX)
|
|
||||||
}
|
|
||||||
if iy >= len(y) || iy+(n-1)*incY >= len(y) {
|
|
||||||
panic(shortY)
|
|
||||||
}
|
|
||||||
return f32.DdotInc(x, y, uintptr(n), uintptr(incX), uintptr(incY), uintptr(ix), uintptr(iy))
|
|
||||||
}
|
|
||||||
53
vendor/gonum.org/v1/gonum/blas/gonum/level1float32_sdot.go
generated
vendored
53
vendor/gonum.org/v1/gonum/blas/gonum/level1float32_sdot.go
generated
vendored
@@ -1,53 +0,0 @@
|
|||||||
// Code generated by "go generate gonum.org/v1/gonum/blas/gonum”; 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 gonum
|
|
||||||
|
|
||||||
import (
|
|
||||||
"gonum.org/v1/gonum/internal/asm/f32"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Sdot computes the dot product of the two vectors
|
|
||||||
// \sum_i x[i]*y[i]
|
|
||||||
//
|
|
||||||
// Float32 implementations are autogenerated and not directly tested.
|
|
||||||
func (Implementation) Sdot(n int, x []float32, incX int, y []float32, incY int) float32 {
|
|
||||||
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 f32.DotUnitary(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) || ix+(n-1)*incX >= len(x) {
|
|
||||||
panic(shortX)
|
|
||||||
}
|
|
||||||
if iy >= len(y) || iy+(n-1)*incY >= len(y) {
|
|
||||||
panic(shortY)
|
|
||||||
}
|
|
||||||
return f32.DotInc(x, y, uintptr(n), uintptr(incX), uintptr(incY), uintptr(ix), uintptr(iy))
|
|
||||||
}
|
|
||||||
53
vendor/gonum.org/v1/gonum/blas/gonum/level1float32_sdsdot.go
generated
vendored
53
vendor/gonum.org/v1/gonum/blas/gonum/level1float32_sdsdot.go
generated
vendored
@@ -1,53 +0,0 @@
|
|||||||
// Code generated by "go generate gonum.org/v1/gonum/blas/gonum”; 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 gonum
|
|
||||||
|
|
||||||
import (
|
|
||||||
"gonum.org/v1/gonum/internal/asm/f32"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Sdsdot computes the dot product of the two vectors plus a constant
|
|
||||||
// alpha + \sum_i x[i]*y[i]
|
|
||||||
//
|
|
||||||
// Float32 implementations are autogenerated and not directly tested.
|
|
||||||
func (Implementation) Sdsdot(n int, alpha float32, x []float32, incX int, y []float32, incY int) float32 {
|
|
||||||
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 alpha + float32(f32.DdotUnitary(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) || ix+(n-1)*incX >= len(x) {
|
|
||||||
panic(shortX)
|
|
||||||
}
|
|
||||||
if iy >= len(y) || iy+(n-1)*incY >= len(y) {
|
|
||||||
panic(shortY)
|
|
||||||
}
|
|
||||||
return alpha + float32(f32.DdotInc(x, y, uintptr(n), uintptr(incX), uintptr(incY), uintptr(ix), uintptr(iy)))
|
|
||||||
}
|
|
||||||
620
vendor/gonum.org/v1/gonum/blas/gonum/level1float64.go
generated
vendored
620
vendor/gonum.org/v1/gonum/blas/gonum/level1float64.go
generated
vendored
@@ -1,620 +0,0 @@
|
|||||||
// 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
|
|
||||||
|
|
||||||
import (
|
|
||||||
"math"
|
|
||||||
|
|
||||||
"gonum.org/v1/gonum/blas"
|
|
||||||
"gonum.org/v1/gonum/internal/asm/f64"
|
|
||||||
)
|
|
||||||
|
|
||||||
var _ blas.Float64Level1 = Implementation{}
|
|
||||||
|
|
||||||
// Dnrm2 computes the Euclidean norm of a vector,
|
|
||||||
// sqrt(\sum_i x[i] * x[i]).
|
|
||||||
// This function returns 0 if incX is negative.
|
|
||||||
func (Implementation) Dnrm2(n int, x []float64, incX int) float64 {
|
|
||||||
if incX < 1 {
|
|
||||||
if incX == 0 {
|
|
||||||
panic(zeroIncX)
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
if len(x) <= (n-1)*incX {
|
|
||||||
panic(shortX)
|
|
||||||
}
|
|
||||||
if n < 2 {
|
|
||||||
if n == 1 {
|
|
||||||
return math.Abs(x[0])
|
|
||||||
}
|
|
||||||
if n == 0 {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
panic(nLT0)
|
|
||||||
}
|
|
||||||
var (
|
|
||||||
scale float64 = 0
|
|
||||||
sumSquares float64 = 1
|
|
||||||
)
|
|
||||||
if incX == 1 {
|
|
||||||
x = x[:n]
|
|
||||||
for _, v := range x {
|
|
||||||
if v == 0 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
absxi := math.Abs(v)
|
|
||||||
if math.IsNaN(absxi) {
|
|
||||||
return math.NaN()
|
|
||||||
}
|
|
||||||
if scale < absxi {
|
|
||||||
sumSquares = 1 + sumSquares*(scale/absxi)*(scale/absxi)
|
|
||||||
scale = absxi
|
|
||||||
} else {
|
|
||||||
sumSquares = sumSquares + (absxi/scale)*(absxi/scale)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if math.IsInf(scale, 1) {
|
|
||||||
return math.Inf(1)
|
|
||||||
}
|
|
||||||
return scale * math.Sqrt(sumSquares)
|
|
||||||
}
|
|
||||||
for ix := 0; ix < n*incX; ix += incX {
|
|
||||||
val := x[ix]
|
|
||||||
if val == 0 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
absxi := math.Abs(val)
|
|
||||||
if math.IsNaN(absxi) {
|
|
||||||
return math.NaN()
|
|
||||||
}
|
|
||||||
if scale < absxi {
|
|
||||||
sumSquares = 1 + sumSquares*(scale/absxi)*(scale/absxi)
|
|
||||||
scale = absxi
|
|
||||||
} else {
|
|
||||||
sumSquares = sumSquares + (absxi/scale)*(absxi/scale)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if math.IsInf(scale, 1) {
|
|
||||||
return math.Inf(1)
|
|
||||||
}
|
|
||||||
return scale * math.Sqrt(sumSquares)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dasum computes the sum of the absolute values of the elements of x.
|
|
||||||
// \sum_i |x[i]|
|
|
||||||
// Dasum returns 0 if incX is negative.
|
|
||||||
func (Implementation) Dasum(n int, x []float64, incX int) float64 {
|
|
||||||
var sum float64
|
|
||||||
if n < 0 {
|
|
||||||
panic(nLT0)
|
|
||||||
}
|
|
||||||
if incX < 1 {
|
|
||||||
if incX == 0 {
|
|
||||||
panic(zeroIncX)
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
if len(x) <= (n-1)*incX {
|
|
||||||
panic(shortX)
|
|
||||||
}
|
|
||||||
if incX == 1 {
|
|
||||||
x = x[:n]
|
|
||||||
for _, v := range x {
|
|
||||||
sum += math.Abs(v)
|
|
||||||
}
|
|
||||||
return sum
|
|
||||||
}
|
|
||||||
for i := 0; i < n; i++ {
|
|
||||||
sum += math.Abs(x[i*incX])
|
|
||||||
}
|
|
||||||
return sum
|
|
||||||
}
|
|
||||||
|
|
||||||
// Idamax returns the index of an element of x with the largest absolute value.
|
|
||||||
// If there are multiple such indices the earliest is returned.
|
|
||||||
// Idamax returns -1 if n == 0.
|
|
||||||
func (Implementation) Idamax(n int, x []float64, incX int) int {
|
|
||||||
if incX < 1 {
|
|
||||||
if incX == 0 {
|
|
||||||
panic(zeroIncX)
|
|
||||||
}
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
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.
|
|
||||||
}
|
|
||||||
panic(nLT0)
|
|
||||||
}
|
|
||||||
idx := 0
|
|
||||||
max := math.Abs(x[0])
|
|
||||||
if incX == 1 {
|
|
||||||
for i, v := range x[:n] {
|
|
||||||
absV := math.Abs(v)
|
|
||||||
if absV > max {
|
|
||||||
max = absV
|
|
||||||
idx = i
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return idx
|
|
||||||
}
|
|
||||||
ix := incX
|
|
||||||
for i := 1; i < n; i++ {
|
|
||||||
v := x[ix]
|
|
||||||
absV := math.Abs(v)
|
|
||||||
if absV > max {
|
|
||||||
max = absV
|
|
||||||
idx = i
|
|
||||||
}
|
|
||||||
ix += incX
|
|
||||||
}
|
|
||||||
return idx
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dswap exchanges the elements of two vectors.
|
|
||||||
// x[i], y[i] = y[i], x[i] for all i
|
|
||||||
func (Implementation) Dswap(n int, x []float64, incX int, y []float64, incY int) {
|
|
||||||
if incX == 0 {
|
|
||||||
panic(zeroIncX)
|
|
||||||
}
|
|
||||||
if incY == 0 {
|
|
||||||
panic(zeroIncY)
|
|
||||||
}
|
|
||||||
if n < 1 {
|
|
||||||
if n == 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
panic(nLT0)
|
|
||||||
}
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dcopy copies the elements of x into the elements of y.
|
|
||||||
// y[i] = x[i] for all i
|
|
||||||
func (Implementation) Dcopy(n int, x []float64, incX int, y []float64, incY int) {
|
|
||||||
if incX == 0 {
|
|
||||||
panic(zeroIncX)
|
|
||||||
}
|
|
||||||
if incY == 0 {
|
|
||||||
panic(zeroIncY)
|
|
||||||
}
|
|
||||||
if n < 1 {
|
|
||||||
if n == 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
panic(nLT0)
|
|
||||||
}
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Daxpy adds alpha times x to y
|
|
||||||
// y[i] += alpha * x[i] for all i
|
|
||||||
func (Implementation) Daxpy(n int, alpha float64, x []float64, incX int, y []float64, incY int) {
|
|
||||||
if incX == 0 {
|
|
||||||
panic(zeroIncX)
|
|
||||||
}
|
|
||||||
if incY == 0 {
|
|
||||||
panic(zeroIncY)
|
|
||||||
}
|
|
||||||
if n < 1 {
|
|
||||||
if n == 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
panic(nLT0)
|
|
||||||
}
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
if alpha == 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if incX == 1 && incY == 1 {
|
|
||||||
f64.AxpyUnitary(alpha, x[:n], y[:n])
|
|
||||||
return
|
|
||||||
}
|
|
||||||
var ix, iy int
|
|
||||||
if incX < 0 {
|
|
||||||
ix = (-n + 1) * incX
|
|
||||||
}
|
|
||||||
if incY < 0 {
|
|
||||||
iy = (-n + 1) * incY
|
|
||||||
}
|
|
||||||
f64.AxpyInc(alpha, x, y, uintptr(n), uintptr(incX), uintptr(incY), uintptr(ix), uintptr(iy))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Drotg computes the plane rotation
|
|
||||||
// _ _ _ _ _ _
|
|
||||||
// | c s | | a | | r |
|
|
||||||
// | -s c | * | b | = | 0 |
|
|
||||||
// ‾ ‾ ‾ ‾ ‾ ‾
|
|
||||||
// where
|
|
||||||
// r = ±√(a^2 + b^2)
|
|
||||||
// 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 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.
|
|
||||||
func (Implementation) Drotg(a, b float64) (c, s, r, z float64) {
|
|
||||||
if b == 0 && a == 0 {
|
|
||||||
return 1, 0, a, 0
|
|
||||||
}
|
|
||||||
absA := math.Abs(a)
|
|
||||||
absB := math.Abs(b)
|
|
||||||
aGTb := absA > absB
|
|
||||||
r = math.Hypot(a, b)
|
|
||||||
if aGTb {
|
|
||||||
r = math.Copysign(r, a)
|
|
||||||
} else {
|
|
||||||
r = math.Copysign(r, b)
|
|
||||||
}
|
|
||||||
c = a / r
|
|
||||||
s = b / r
|
|
||||||
if aGTb {
|
|
||||||
z = s
|
|
||||||
} else if c != 0 { // r == 0 case handled above
|
|
||||||
z = 1 / c
|
|
||||||
} else {
|
|
||||||
z = 1
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Drotmg computes the modified Givens rotation. See
|
|
||||||
// http://www.netlib.org/lapack/explore-html/df/deb/drotmg_8f.html
|
|
||||||
// for more details.
|
|
||||||
func (Implementation) Drotmg(d1, d2, x1, y1 float64) (p blas.DrotmParams, rd1, rd2, rx1 float64) {
|
|
||||||
// The implementation of Drotmg used here is taken from Hopkins 1997
|
|
||||||
// Appendix A: https://doi.org/10.1145/289251.289253
|
|
||||||
// with the exception of the gam constants below.
|
|
||||||
|
|
||||||
const (
|
|
||||||
gam = 4096.0
|
|
||||||
gamsq = gam * gam
|
|
||||||
rgamsq = 1.0 / gamsq
|
|
||||||
)
|
|
||||||
|
|
||||||
if d1 < 0 {
|
|
||||||
p.Flag = blas.Rescaling // Error state.
|
|
||||||
return p, 0, 0, 0
|
|
||||||
}
|
|
||||||
|
|
||||||
if d2 == 0 || y1 == 0 {
|
|
||||||
p.Flag = blas.Identity
|
|
||||||
return p, d1, d2, x1
|
|
||||||
}
|
|
||||||
|
|
||||||
var h11, h12, h21, h22 float64
|
|
||||||
if (d1 == 0 || x1 == 0) && d2 > 0 {
|
|
||||||
p.Flag = blas.Diagonal
|
|
||||||
h12 = 1
|
|
||||||
h21 = -1
|
|
||||||
x1 = y1
|
|
||||||
d1, d2 = d2, d1
|
|
||||||
} else {
|
|
||||||
p2 := d2 * y1
|
|
||||||
p1 := d1 * x1
|
|
||||||
q2 := p2 * y1
|
|
||||||
q1 := p1 * x1
|
|
||||||
if math.Abs(q1) > math.Abs(q2) {
|
|
||||||
p.Flag = blas.OffDiagonal
|
|
||||||
h11 = 1
|
|
||||||
h22 = 1
|
|
||||||
h21 = -y1 / x1
|
|
||||||
h12 = p2 / p1
|
|
||||||
u := 1 - h12*h21
|
|
||||||
if u <= 0 {
|
|
||||||
p.Flag = blas.Rescaling // Error state.
|
|
||||||
return p, 0, 0, 0
|
|
||||||
}
|
|
||||||
|
|
||||||
d1 /= u
|
|
||||||
d2 /= u
|
|
||||||
x1 *= u
|
|
||||||
} else {
|
|
||||||
if q2 < 0 {
|
|
||||||
p.Flag = blas.Rescaling // Error state.
|
|
||||||
return p, 0, 0, 0
|
|
||||||
}
|
|
||||||
|
|
||||||
p.Flag = blas.Diagonal
|
|
||||||
h21 = -1
|
|
||||||
h12 = 1
|
|
||||||
h11 = p1 / p2
|
|
||||||
h22 = x1 / y1
|
|
||||||
u := 1 + h11*h22
|
|
||||||
d1, d2 = d2/u, d1/u
|
|
||||||
x1 = y1 * u
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for d1 <= rgamsq && d1 != 0 {
|
|
||||||
p.Flag = blas.Rescaling
|
|
||||||
d1 = (d1 * gam) * gam
|
|
||||||
x1 /= gam
|
|
||||||
h11 /= gam
|
|
||||||
h12 /= gam
|
|
||||||
}
|
|
||||||
for d1 > gamsq {
|
|
||||||
p.Flag = blas.Rescaling
|
|
||||||
d1 = (d1 / gam) / gam
|
|
||||||
x1 *= gam
|
|
||||||
h11 *= gam
|
|
||||||
h12 *= gam
|
|
||||||
}
|
|
||||||
|
|
||||||
for math.Abs(d2) <= rgamsq && d2 != 0 {
|
|
||||||
p.Flag = blas.Rescaling
|
|
||||||
d2 = (d2 * gam) * gam
|
|
||||||
h21 /= gam
|
|
||||||
h22 /= gam
|
|
||||||
}
|
|
||||||
for math.Abs(d2) > gamsq {
|
|
||||||
p.Flag = blas.Rescaling
|
|
||||||
d2 = (d2 / gam) / gam
|
|
||||||
h21 *= gam
|
|
||||||
h22 *= gam
|
|
||||||
}
|
|
||||||
|
|
||||||
switch p.Flag {
|
|
||||||
case blas.Diagonal:
|
|
||||||
p.H = [4]float64{0: h11, 3: h22}
|
|
||||||
case blas.OffDiagonal:
|
|
||||||
p.H = [4]float64{1: h21, 2: h12}
|
|
||||||
case blas.Rescaling:
|
|
||||||
p.H = [4]float64{h11, h21, h12, h22}
|
|
||||||
default:
|
|
||||||
panic(badFlag)
|
|
||||||
}
|
|
||||||
|
|
||||||
return p, d1, d2, x1
|
|
||||||
}
|
|
||||||
|
|
||||||
// Drot applies a plane transformation.
|
|
||||||
// x[i] = c * x[i] + s * y[i]
|
|
||||||
// y[i] = c * y[i] - s * x[i]
|
|
||||||
func (Implementation) Drot(n int, x []float64, incX int, y []float64, incY int, c float64, s float64) {
|
|
||||||
if incX == 0 {
|
|
||||||
panic(zeroIncX)
|
|
||||||
}
|
|
||||||
if incY == 0 {
|
|
||||||
panic(zeroIncY)
|
|
||||||
}
|
|
||||||
if n < 1 {
|
|
||||||
if n == 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
panic(nLT0)
|
|
||||||
}
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
if incX == 1 && incY == 1 {
|
|
||||||
x = x[:n]
|
|
||||||
for i, vx := range x {
|
|
||||||
vy := y[i]
|
|
||||||
x[i], y[i] = c*vx+s*vy, c*vy-s*vx
|
|
||||||
}
|
|
||||||
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++ {
|
|
||||||
vx := x[ix]
|
|
||||||
vy := y[iy]
|
|
||||||
x[ix], y[iy] = c*vx+s*vy, c*vy-s*vx
|
|
||||||
ix += incX
|
|
||||||
iy += incY
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Drotm applies the modified Givens rotation to the 2×n matrix.
|
|
||||||
func (Implementation) Drotm(n int, x []float64, incX int, y []float64, incY int, p blas.DrotmParams) {
|
|
||||||
if incX == 0 {
|
|
||||||
panic(zeroIncX)
|
|
||||||
}
|
|
||||||
if incY == 0 {
|
|
||||||
panic(zeroIncY)
|
|
||||||
}
|
|
||||||
if n <= 0 {
|
|
||||||
if n == 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
panic(nLT0)
|
|
||||||
}
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
|
|
||||||
if p.Flag == blas.Identity {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
switch p.Flag {
|
|
||||||
case blas.Rescaling:
|
|
||||||
h11 := p.H[0]
|
|
||||||
h12 := p.H[2]
|
|
||||||
h21 := p.H[1]
|
|
||||||
h22 := p.H[3]
|
|
||||||
if incX == 1 && incY == 1 {
|
|
||||||
x = x[:n]
|
|
||||||
for i, vx := range x {
|
|
||||||
vy := y[i]
|
|
||||||
x[i], y[i] = vx*h11+vy*h12, vx*h21+vy*h22
|
|
||||||
}
|
|
||||||
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++ {
|
|
||||||
vx := x[ix]
|
|
||||||
vy := y[iy]
|
|
||||||
x[ix], y[iy] = vx*h11+vy*h12, vx*h21+vy*h22
|
|
||||||
ix += incX
|
|
||||||
iy += incY
|
|
||||||
}
|
|
||||||
case blas.OffDiagonal:
|
|
||||||
h12 := p.H[2]
|
|
||||||
h21 := p.H[1]
|
|
||||||
if incX == 1 && incY == 1 {
|
|
||||||
x = x[:n]
|
|
||||||
for i, vx := range x {
|
|
||||||
vy := y[i]
|
|
||||||
x[i], y[i] = vx+vy*h12, vx*h21+vy
|
|
||||||
}
|
|
||||||
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++ {
|
|
||||||
vx := x[ix]
|
|
||||||
vy := y[iy]
|
|
||||||
x[ix], y[iy] = vx+vy*h12, vx*h21+vy
|
|
||||||
ix += incX
|
|
||||||
iy += incY
|
|
||||||
}
|
|
||||||
case blas.Diagonal:
|
|
||||||
h11 := p.H[0]
|
|
||||||
h22 := p.H[3]
|
|
||||||
if incX == 1 && incY == 1 {
|
|
||||||
x = x[:n]
|
|
||||||
for i, vx := range x {
|
|
||||||
vy := y[i]
|
|
||||||
x[i], y[i] = vx*h11+vy, -vx+vy*h22
|
|
||||||
}
|
|
||||||
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++ {
|
|
||||||
vx := x[ix]
|
|
||||||
vy := y[iy]
|
|
||||||
x[ix], y[iy] = vx*h11+vy, -vx+vy*h22
|
|
||||||
ix += incX
|
|
||||||
iy += incY
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dscal scales x by alpha.
|
|
||||||
// x[i] *= alpha
|
|
||||||
// Dscal has no effect if incX < 0.
|
|
||||||
func (Implementation) Dscal(n int, alpha float64, x []float64, incX int) {
|
|
||||||
if incX < 1 {
|
|
||||||
if incX == 0 {
|
|
||||||
panic(zeroIncX)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
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]
|
|
||||||
for i := range x {
|
|
||||||
x[i] = 0
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for ix := 0; ix < n*incX; ix += incX {
|
|
||||||
x[ix] = 0
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if incX == 1 {
|
|
||||||
f64.ScalUnitary(alpha, x[:n])
|
|
||||||
return
|
|
||||||
}
|
|
||||||
f64.ScalInc(alpha, x, uintptr(n), uintptr(incX))
|
|
||||||
}
|
|
||||||
49
vendor/gonum.org/v1/gonum/blas/gonum/level1float64_ddot.go
generated
vendored
49
vendor/gonum.org/v1/gonum/blas/gonum/level1float64_ddot.go
generated
vendored
@@ -1,49 +0,0 @@
|
|||||||
// 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
|
|
||||||
|
|
||||||
import (
|
|
||||||
"gonum.org/v1/gonum/internal/asm/f64"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Ddot computes the dot product of the two vectors
|
|
||||||
// \sum_i x[i]*y[i]
|
|
||||||
func (Implementation) Ddot(n int, x []float64, incX int, y []float64, incY int) float64 {
|
|
||||||
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 f64.DotUnitary(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) || ix+(n-1)*incX >= len(x) {
|
|
||||||
panic(shortX)
|
|
||||||
}
|
|
||||||
if iy >= len(y) || iy+(n-1)*incY >= len(y) {
|
|
||||||
panic(shortY)
|
|
||||||
}
|
|
||||||
return f64.DotInc(x, y, uintptr(n), uintptr(incX), uintptr(incY), uintptr(ix), uintptr(iy))
|
|
||||||
}
|
|
||||||
2906
vendor/gonum.org/v1/gonum/blas/gonum/level2cmplx128.go
generated
vendored
2906
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
2942
vendor/gonum.org/v1/gonum/blas/gonum/level2cmplx64.go
generated
vendored
File diff suppressed because it is too large
Load Diff
2296
vendor/gonum.org/v1/gonum/blas/gonum/level2float32.go
generated
vendored
2296
vendor/gonum.org/v1/gonum/blas/gonum/level2float32.go
generated
vendored
File diff suppressed because it is too large
Load Diff
2264
vendor/gonum.org/v1/gonum/blas/gonum/level2float64.go
generated
vendored
2264
vendor/gonum.org/v1/gonum/blas/gonum/level2float64.go
generated
vendored
File diff suppressed because it is too large
Load Diff
1715
vendor/gonum.org/v1/gonum/blas/gonum/level3cmplx128.go
generated
vendored
1715
vendor/gonum.org/v1/gonum/blas/gonum/level3cmplx128.go
generated
vendored
File diff suppressed because it is too large
Load Diff
1735
vendor/gonum.org/v1/gonum/blas/gonum/level3cmplx64.go
generated
vendored
1735
vendor/gonum.org/v1/gonum/blas/gonum/level3cmplx64.go
generated
vendored
File diff suppressed because it is too large
Load Diff
876
vendor/gonum.org/v1/gonum/blas/gonum/level3float32.go
generated
vendored
876
vendor/gonum.org/v1/gonum/blas/gonum/level3float32.go
generated
vendored
@@ -1,876 +0,0 @@
|
|||||||
// Code generated by "go generate gonum.org/v1/gonum/blas/gonum”; DO NOT EDIT.
|
|
||||||
|
|
||||||
// Copyright ©2014 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"
|
|
||||||
"gonum.org/v1/gonum/internal/asm/f32"
|
|
||||||
)
|
|
||||||
|
|
||||||
var _ blas.Float32Level3 = Implementation{}
|
|
||||||
|
|
||||||
// Strsm solves one of the matrix equations
|
|
||||||
// A * X = alpha * B if tA == blas.NoTrans and side == blas.Left
|
|
||||||
// Aᵀ * X = alpha * B if tA == blas.Trans or blas.ConjTrans, and side == blas.Left
|
|
||||||
// X * A = alpha * B if tA == blas.NoTrans and side == blas.Right
|
|
||||||
// X * Aᵀ = alpha * B if tA == blas.Trans or blas.ConjTrans, and side == 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, X contains the values of B, and the result is
|
|
||||||
// stored in-place into X.
|
|
||||||
//
|
|
||||||
// No check is made that A is invertible.
|
|
||||||
//
|
|
||||||
// Float32 implementations are autogenerated and not directly tested.
|
|
||||||
func (Implementation) Strsm(s blas.Side, ul blas.Uplo, tA blas.Transpose, d blas.Diag, m, n int, alpha float32, a []float32, lda int, b []float32, ldb int) {
|
|
||||||
if s != blas.Left && s != blas.Right {
|
|
||||||
panic(badSide)
|
|
||||||
}
|
|
||||||
if ul != blas.Lower && ul != blas.Upper {
|
|
||||||
panic(badUplo)
|
|
||||||
}
|
|
||||||
if tA != blas.NoTrans && tA != blas.Trans && tA != blas.ConjTrans {
|
|
||||||
panic(badTranspose)
|
|
||||||
}
|
|
||||||
if d != blas.NonUnit && d != blas.Unit {
|
|
||||||
panic(badDiag)
|
|
||||||
}
|
|
||||||
if m < 0 {
|
|
||||||
panic(mLT0)
|
|
||||||
}
|
|
||||||
if n < 0 {
|
|
||||||
panic(nLT0)
|
|
||||||
}
|
|
||||||
k := n
|
|
||||||
if s == blas.Left {
|
|
||||||
k = m
|
|
||||||
}
|
|
||||||
if lda < max(1, k) {
|
|
||||||
panic(badLdA)
|
|
||||||
}
|
|
||||||
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]
|
|
||||||
for j := range btmp {
|
|
||||||
btmp[j] = 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
nonUnit := d == blas.NonUnit
|
|
||||||
if s == blas.Left {
|
|
||||||
if tA == blas.NoTrans {
|
|
||||||
if ul == blas.Upper {
|
|
||||||
for i := m - 1; i >= 0; i-- {
|
|
||||||
btmp := b[i*ldb : i*ldb+n]
|
|
||||||
if alpha != 1 {
|
|
||||||
f32.ScalUnitary(alpha, btmp)
|
|
||||||
}
|
|
||||||
for ka, va := range a[i*lda+i+1 : i*lda+m] {
|
|
||||||
if va != 0 {
|
|
||||||
k := ka + i + 1
|
|
||||||
f32.AxpyUnitary(-va, b[k*ldb:k*ldb+n], btmp)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if nonUnit {
|
|
||||||
tmp := 1 / a[i*lda+i]
|
|
||||||
f32.ScalUnitary(tmp, btmp)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for i := 0; i < m; i++ {
|
|
||||||
btmp := b[i*ldb : i*ldb+n]
|
|
||||||
if alpha != 1 {
|
|
||||||
f32.ScalUnitary(alpha, btmp)
|
|
||||||
}
|
|
||||||
for k, va := range a[i*lda : i*lda+i] {
|
|
||||||
if va != 0 {
|
|
||||||
f32.AxpyUnitary(-va, b[k*ldb:k*ldb+n], btmp)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if nonUnit {
|
|
||||||
tmp := 1 / a[i*lda+i]
|
|
||||||
f32.ScalUnitary(tmp, btmp)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// Cases where a is transposed
|
|
||||||
if ul == blas.Upper {
|
|
||||||
for k := 0; k < m; k++ {
|
|
||||||
btmpk := b[k*ldb : k*ldb+n]
|
|
||||||
if nonUnit {
|
|
||||||
tmp := 1 / a[k*lda+k]
|
|
||||||
f32.ScalUnitary(tmp, btmpk)
|
|
||||||
}
|
|
||||||
for ia, va := range a[k*lda+k+1 : k*lda+m] {
|
|
||||||
if va != 0 {
|
|
||||||
i := ia + k + 1
|
|
||||||
f32.AxpyUnitary(-va, btmpk, b[i*ldb:i*ldb+n])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if alpha != 1 {
|
|
||||||
f32.ScalUnitary(alpha, btmpk)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for k := m - 1; k >= 0; k-- {
|
|
||||||
btmpk := b[k*ldb : k*ldb+n]
|
|
||||||
if nonUnit {
|
|
||||||
tmp := 1 / a[k*lda+k]
|
|
||||||
f32.ScalUnitary(tmp, btmpk)
|
|
||||||
}
|
|
||||||
for i, va := range a[k*lda : k*lda+k] {
|
|
||||||
if va != 0 {
|
|
||||||
f32.AxpyUnitary(-va, btmpk, b[i*ldb:i*ldb+n])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if alpha != 1 {
|
|
||||||
f32.ScalUnitary(alpha, btmpk)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// Cases where a is to the right of X.
|
|
||||||
if tA == blas.NoTrans {
|
|
||||||
if ul == blas.Upper {
|
|
||||||
for i := 0; i < m; i++ {
|
|
||||||
btmp := b[i*ldb : i*ldb+n]
|
|
||||||
if alpha != 1 {
|
|
||||||
f32.ScalUnitary(alpha, btmp)
|
|
||||||
}
|
|
||||||
for k, vb := range btmp {
|
|
||||||
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*ldb : i*ldb+n]
|
|
||||||
if alpha != 1 {
|
|
||||||
f32.ScalUnitary(alpha, btmp)
|
|
||||||
}
|
|
||||||
for k := n - 1; k >= 0; k-- {
|
|
||||||
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
|
|
||||||
}
|
|
||||||
// Cases where a is transposed.
|
|
||||||
if ul == blas.Upper {
|
|
||||||
for i := 0; i < m; i++ {
|
|
||||||
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 {
|
|
||||||
tmp /= a[j*lda+j]
|
|
||||||
}
|
|
||||||
btmp[j] = tmp
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for i := 0; i < m; i++ {
|
|
||||||
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[:j])
|
|
||||||
if nonUnit {
|
|
||||||
tmp /= a[j*lda+j]
|
|
||||||
}
|
|
||||||
btmp[j] = tmp
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ssymm performs one of the matrix-matrix operations
|
|
||||||
// C = alpha * A * B + beta * C if side == blas.Left
|
|
||||||
// C = alpha * B * A + beta * C if side == blas.Right
|
|
||||||
// where A is an n×n or m×m symmetric matrix, B and C are m×n matrices, and alpha
|
|
||||||
// is a scalar.
|
|
||||||
//
|
|
||||||
// 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(badSide)
|
|
||||||
}
|
|
||||||
if ul != blas.Lower && ul != blas.Upper {
|
|
||||||
panic(badUplo)
|
|
||||||
}
|
|
||||||
if m < 0 {
|
|
||||||
panic(mLT0)
|
|
||||||
}
|
|
||||||
if n < 0 {
|
|
||||||
panic(nLT0)
|
|
||||||
}
|
|
||||||
k := n
|
|
||||||
if s == blas.Left {
|
|
||||||
k = m
|
|
||||||
}
|
|
||||||
if lda < max(1, k) {
|
|
||||||
panic(badLdA)
|
|
||||||
}
|
|
||||||
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 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++ {
|
|
||||||
ctmp := c[i*ldc : i*ldc+n]
|
|
||||||
for j := range ctmp {
|
|
||||||
ctmp[j] = 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for i := 0; i < m; i++ {
|
|
||||||
ctmp := c[i*ldc : i*ldc+n]
|
|
||||||
for j := 0; j < n; j++ {
|
|
||||||
ctmp[j] *= beta
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
isUpper := ul == blas.Upper
|
|
||||||
if s == blas.Left {
|
|
||||||
for i := 0; i < m; i++ {
|
|
||||||
atmp := alpha * a[i*lda+i]
|
|
||||||
btmp := b[i*ldb : i*ldb+n]
|
|
||||||
ctmp := c[i*ldc : i*ldc+n]
|
|
||||||
for j, v := range btmp {
|
|
||||||
ctmp[j] *= beta
|
|
||||||
ctmp[j] += atmp * v
|
|
||||||
}
|
|
||||||
|
|
||||||
for k := 0; k < i; k++ {
|
|
||||||
var atmp float32
|
|
||||||
if isUpper {
|
|
||||||
atmp = a[k*lda+i]
|
|
||||||
} else {
|
|
||||||
atmp = a[i*lda+k]
|
|
||||||
}
|
|
||||||
atmp *= alpha
|
|
||||||
f32.AxpyUnitary(atmp, b[k*ldb:k*ldb+n], ctmp)
|
|
||||||
}
|
|
||||||
for k := i + 1; k < m; k++ {
|
|
||||||
var atmp float32
|
|
||||||
if isUpper {
|
|
||||||
atmp = a[i*lda+k]
|
|
||||||
} else {
|
|
||||||
atmp = a[k*lda+i]
|
|
||||||
}
|
|
||||||
atmp *= alpha
|
|
||||||
f32.AxpyUnitary(atmp, b[k*ldb:k*ldb+n], ctmp)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if isUpper {
|
|
||||||
for i := 0; i < m; i++ {
|
|
||||||
for j := n - 1; j >= 0; j-- {
|
|
||||||
tmp := alpha * b[i*ldb+j]
|
|
||||||
var tmp2 float32
|
|
||||||
atmp := a[j*lda+j+1 : j*lda+n]
|
|
||||||
btmp := b[i*ldb+j+1 : i*ldb+n]
|
|
||||||
ctmp := c[i*ldc+j+1 : i*ldc+n]
|
|
||||||
for k, v := range atmp {
|
|
||||||
ctmp[k] += tmp * v
|
|
||||||
tmp2 += btmp[k] * v
|
|
||||||
}
|
|
||||||
c[i*ldc+j] *= beta
|
|
||||||
c[i*ldc+j] += tmp*a[j*lda+j] + alpha*tmp2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for i := 0; i < m; i++ {
|
|
||||||
for j := 0; j < n; j++ {
|
|
||||||
tmp := alpha * b[i*ldb+j]
|
|
||||||
var tmp2 float32
|
|
||||||
atmp := a[j*lda : j*lda+j]
|
|
||||||
btmp := b[i*ldb : i*ldb+j]
|
|
||||||
ctmp := c[i*ldc : i*ldc+j]
|
|
||||||
for k, v := range atmp {
|
|
||||||
ctmp[k] += tmp * v
|
|
||||||
tmp2 += btmp[k] * v
|
|
||||||
}
|
|
||||||
c[i*ldc+j] *= beta
|
|
||||||
c[i*ldc+j] += tmp*a[j*lda+j] + alpha*tmp2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ssyrk performs one of the symmetric rank-k operations
|
|
||||||
// C = alpha * A * Aᵀ + beta * C if tA == blas.NoTrans
|
|
||||||
// C = alpha * Aᵀ * A + beta * C if tA == blas.Trans or tA == blas.ConjTrans
|
|
||||||
// where A is an n×k or k×n matrix, C is an n×n symmetric matrix, and alpha and
|
|
||||||
// beta are scalars.
|
|
||||||
//
|
|
||||||
// Float32 implementations are autogenerated and not directly tested.
|
|
||||||
func (Implementation) Ssyrk(ul blas.Uplo, tA blas.Transpose, n, k int, alpha float32, a []float32, lda int, beta float32, c []float32, ldc int) {
|
|
||||||
if ul != blas.Lower && ul != blas.Upper {
|
|
||||||
panic(badUplo)
|
|
||||||
}
|
|
||||||
if tA != blas.Trans && tA != blas.NoTrans && tA != blas.ConjTrans {
|
|
||||||
panic(badTranspose)
|
|
||||||
}
|
|
||||||
if n < 0 {
|
|
||||||
panic(nLT0)
|
|
||||||
}
|
|
||||||
if k < 0 {
|
|
||||||
panic(kLT0)
|
|
||||||
}
|
|
||||||
row, col := k, n
|
|
||||||
if tA == blas.NoTrans {
|
|
||||||
row, col = n, k
|
|
||||||
}
|
|
||||||
if lda < max(1, col) {
|
|
||||||
panic(badLdA)
|
|
||||||
}
|
|
||||||
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 {
|
|
||||||
for i := 0; i < n; i++ {
|
|
||||||
ctmp := c[i*ldc+i : i*ldc+n]
|
|
||||||
for j := range ctmp {
|
|
||||||
ctmp[j] = 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for i := 0; i < n; i++ {
|
|
||||||
ctmp := c[i*ldc : i*ldc+i+1]
|
|
||||||
for j := range ctmp {
|
|
||||||
ctmp[j] = 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if ul == blas.Upper {
|
|
||||||
for i := 0; i < n; i++ {
|
|
||||||
ctmp := c[i*ldc+i : i*ldc+n]
|
|
||||||
for j := range ctmp {
|
|
||||||
ctmp[j] *= beta
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for i := 0; i < n; i++ {
|
|
||||||
ctmp := c[i*ldc : i*ldc+i+1]
|
|
||||||
for j := range ctmp {
|
|
||||||
ctmp[j] *= beta
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if tA == blas.NoTrans {
|
|
||||||
if ul == blas.Upper {
|
|
||||||
for i := 0; i < n; i++ {
|
|
||||||
ctmp := c[i*ldc+i : i*ldc+n]
|
|
||||||
atmp := a[i*lda : i*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]
|
|
||||||
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
|
|
||||||
}
|
|
||||||
// Cases where a is transposed.
|
|
||||||
if ul == blas.Upper {
|
|
||||||
for i := 0; i < n; i++ {
|
|
||||||
ctmp := c[i*ldc+i : i*ldc+n]
|
|
||||||
if beta == 0 {
|
|
||||||
for j := range ctmp {
|
|
||||||
ctmp[j] = 0
|
|
||||||
}
|
|
||||||
} else if beta != 1 {
|
|
||||||
for j := range ctmp {
|
|
||||||
ctmp[j] *= beta
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for l := 0; l < k; l++ {
|
|
||||||
tmp := alpha * a[l*lda+i]
|
|
||||||
if tmp != 0 {
|
|
||||||
f32.AxpyUnitary(tmp, a[l*lda+i:l*lda+n], ctmp)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for i := 0; i < n; i++ {
|
|
||||||
ctmp := c[i*ldc : i*ldc+i+1]
|
|
||||||
if beta != 1 {
|
|
||||||
for j := range ctmp {
|
|
||||||
ctmp[j] *= beta
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for l := 0; l < k; l++ {
|
|
||||||
tmp := alpha * a[l*lda+i]
|
|
||||||
if tmp != 0 {
|
|
||||||
f32.AxpyUnitary(tmp, a[l*lda:l*lda+i+1], ctmp)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ssyr2k performs one of the symmetric rank 2k operations
|
|
||||||
// C = alpha * A * Bᵀ + alpha * B * Aᵀ + beta * C if tA == blas.NoTrans
|
|
||||||
// C = alpha * Aᵀ * B + alpha * Bᵀ * A + beta * C if tA == blas.Trans or tA == blas.ConjTrans
|
|
||||||
// where A and B are n×k or k×n matrices, C is an n×n symmetric matrix, and
|
|
||||||
// alpha and beta are scalars.
|
|
||||||
//
|
|
||||||
// Float32 implementations are autogenerated and not directly tested.
|
|
||||||
func (Implementation) Ssyr2k(ul blas.Uplo, tA blas.Transpose, n, k int, alpha float32, a []float32, lda int, b []float32, ldb int, beta float32, c []float32, ldc int) {
|
|
||||||
if ul != blas.Lower && ul != blas.Upper {
|
|
||||||
panic(badUplo)
|
|
||||||
}
|
|
||||||
if tA != blas.Trans && tA != blas.NoTrans && tA != blas.ConjTrans {
|
|
||||||
panic(badTranspose)
|
|
||||||
}
|
|
||||||
if n < 0 {
|
|
||||||
panic(nLT0)
|
|
||||||
}
|
|
||||||
if k < 0 {
|
|
||||||
panic(kLT0)
|
|
||||||
}
|
|
||||||
row, col := k, n
|
|
||||||
if tA == blas.NoTrans {
|
|
||||||
row, col = n, k
|
|
||||||
}
|
|
||||||
if lda < max(1, col) {
|
|
||||||
panic(badLdA)
|
|
||||||
}
|
|
||||||
if ldb < max(1, col) {
|
|
||||||
panic(badLdB)
|
|
||||||
}
|
|
||||||
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 {
|
|
||||||
for i := 0; i < n; i++ {
|
|
||||||
ctmp := c[i*ldc+i : i*ldc+n]
|
|
||||||
for j := range ctmp {
|
|
||||||
ctmp[j] = 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for i := 0; i < n; i++ {
|
|
||||||
ctmp := c[i*ldc : i*ldc+i+1]
|
|
||||||
for j := range ctmp {
|
|
||||||
ctmp[j] = 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if ul == blas.Upper {
|
|
||||||
for i := 0; i < n; i++ {
|
|
||||||
ctmp := c[i*ldc+i : i*ldc+n]
|
|
||||||
for j := range ctmp {
|
|
||||||
ctmp[j] *= beta
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for i := 0; i < n; i++ {
|
|
||||||
ctmp := c[i*ldc : i*ldc+i+1]
|
|
||||||
for j := range ctmp {
|
|
||||||
ctmp[j] *= beta
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if tA == blas.NoTrans {
|
|
||||||
if ul == blas.Upper {
|
|
||||||
for i := 0; i < n; i++ {
|
|
||||||
atmp := a[i*lda : i*lda+k]
|
|
||||||
btmp := b[i*ldb : i*ldb+k]
|
|
||||||
ctmp := c[i*ldc+i : i*ldc+n]
|
|
||||||
for jc := range ctmp {
|
|
||||||
j := i + jc
|
|
||||||
var tmp1, tmp2 float32
|
|
||||||
binner := b[j*ldb : j*ldb+k]
|
|
||||||
for l, v := range a[j*lda : j*lda+k] {
|
|
||||||
tmp1 += v * btmp[l]
|
|
||||||
tmp2 += atmp[l] * binner[l]
|
|
||||||
}
|
|
||||||
ctmp[jc] *= beta
|
|
||||||
ctmp[jc] += alpha * (tmp1 + tmp2)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for i := 0; i < n; i++ {
|
|
||||||
atmp := a[i*lda : i*lda+k]
|
|
||||||
btmp := b[i*ldb : i*ldb+k]
|
|
||||||
ctmp := c[i*ldc : i*ldc+i+1]
|
|
||||||
for j := 0; j <= i; j++ {
|
|
||||||
var tmp1, tmp2 float32
|
|
||||||
binner := b[j*ldb : j*ldb+k]
|
|
||||||
for l, v := range a[j*lda : j*lda+k] {
|
|
||||||
tmp1 += v * btmp[l]
|
|
||||||
tmp2 += atmp[l] * binner[l]
|
|
||||||
}
|
|
||||||
ctmp[j] *= beta
|
|
||||||
ctmp[j] += alpha * (tmp1 + tmp2)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if ul == blas.Upper {
|
|
||||||
for i := 0; i < n; i++ {
|
|
||||||
ctmp := c[i*ldc+i : i*ldc+n]
|
|
||||||
if beta != 1 {
|
|
||||||
for j := range ctmp {
|
|
||||||
ctmp[j] *= beta
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for l := 0; l < k; l++ {
|
|
||||||
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 {
|
|
||||||
for j, v := range a[l*lda+i : l*lda+n] {
|
|
||||||
ctmp[j] += v*tmp1 + btmp[j]*tmp2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for i := 0; i < n; i++ {
|
|
||||||
ctmp := c[i*ldc : i*ldc+i+1]
|
|
||||||
if beta != 1 {
|
|
||||||
for j := range ctmp {
|
|
||||||
ctmp[j] *= beta
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for l := 0; l < k; l++ {
|
|
||||||
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 {
|
|
||||||
for j, v := range a[l*lda : l*lda+i+1] {
|
|
||||||
ctmp[j] += v*tmp1 + btmp[j]*tmp2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Strmm performs one of the matrix-matrix operations
|
|
||||||
// B = alpha * A * B if tA == blas.NoTrans and side == blas.Left
|
|
||||||
// B = alpha * Aᵀ * B if tA == blas.Trans or blas.ConjTrans, and side == blas.Left
|
|
||||||
// B = alpha * B * A if tA == blas.NoTrans and side == blas.Right
|
|
||||||
// B = alpha * B * Aᵀ if tA == blas.Trans or blas.ConjTrans, and side == blas.Right
|
|
||||||
// where A is an n×n or m×m triangular matrix, B is an m×n matrix, and alpha is a scalar.
|
|
||||||
//
|
|
||||||
// Float32 implementations are autogenerated and not directly tested.
|
|
||||||
func (Implementation) Strmm(s blas.Side, ul blas.Uplo, tA blas.Transpose, d blas.Diag, m, n int, alpha float32, a []float32, lda int, b []float32, ldb int) {
|
|
||||||
if s != blas.Left && s != blas.Right {
|
|
||||||
panic(badSide)
|
|
||||||
}
|
|
||||||
if ul != blas.Lower && ul != blas.Upper {
|
|
||||||
panic(badUplo)
|
|
||||||
}
|
|
||||||
if tA != blas.NoTrans && tA != blas.Trans && tA != blas.ConjTrans {
|
|
||||||
panic(badTranspose)
|
|
||||||
}
|
|
||||||
if d != blas.NonUnit && d != blas.Unit {
|
|
||||||
panic(badDiag)
|
|
||||||
}
|
|
||||||
if m < 0 {
|
|
||||||
panic(mLT0)
|
|
||||||
}
|
|
||||||
if n < 0 {
|
|
||||||
panic(nLT0)
|
|
||||||
}
|
|
||||||
k := n
|
|
||||||
if s == blas.Left {
|
|
||||||
k = m
|
|
||||||
}
|
|
||||||
if lda < max(1, k) {
|
|
||||||
panic(badLdA)
|
|
||||||
}
|
|
||||||
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]
|
|
||||||
for j := range btmp {
|
|
||||||
btmp[j] = 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
nonUnit := d == blas.NonUnit
|
|
||||||
if s == blas.Left {
|
|
||||||
if tA == blas.NoTrans {
|
|
||||||
if ul == blas.Upper {
|
|
||||||
for i := 0; i < m; i++ {
|
|
||||||
tmp := alpha
|
|
||||||
if nonUnit {
|
|
||||||
tmp *= a[i*lda+i]
|
|
||||||
}
|
|
||||||
btmp := b[i*ldb : i*ldb+n]
|
|
||||||
f32.ScalUnitary(tmp, btmp)
|
|
||||||
for ka, va := range a[i*lda+i+1 : i*lda+m] {
|
|
||||||
k := ka + i + 1
|
|
||||||
if va != 0 {
|
|
||||||
f32.AxpyUnitary(alpha*va, b[k*ldb:k*ldb+n], btmp)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for i := m - 1; i >= 0; i-- {
|
|
||||||
tmp := alpha
|
|
||||||
if nonUnit {
|
|
||||||
tmp *= a[i*lda+i]
|
|
||||||
}
|
|
||||||
btmp := b[i*ldb : i*ldb+n]
|
|
||||||
f32.ScalUnitary(tmp, btmp)
|
|
||||||
for k, va := range a[i*lda : i*lda+i] {
|
|
||||||
if va != 0 {
|
|
||||||
f32.AxpyUnitary(alpha*va, b[k*ldb:k*ldb+n], btmp)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// Cases where a is transposed.
|
|
||||||
if ul == blas.Upper {
|
|
||||||
for k := m - 1; k >= 0; k-- {
|
|
||||||
btmpk := b[k*ldb : k*ldb+n]
|
|
||||||
for ia, va := range a[k*lda+k+1 : k*lda+m] {
|
|
||||||
i := ia + k + 1
|
|
||||||
btmp := b[i*ldb : i*ldb+n]
|
|
||||||
if va != 0 {
|
|
||||||
f32.AxpyUnitary(alpha*va, btmpk, btmp)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tmp := alpha
|
|
||||||
if nonUnit {
|
|
||||||
tmp *= a[k*lda+k]
|
|
||||||
}
|
|
||||||
if tmp != 1 {
|
|
||||||
f32.ScalUnitary(tmp, btmpk)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for k := 0; k < m; k++ {
|
|
||||||
btmpk := b[k*ldb : k*ldb+n]
|
|
||||||
for i, va := range a[k*lda : k*lda+k] {
|
|
||||||
btmp := b[i*ldb : i*ldb+n]
|
|
||||||
if va != 0 {
|
|
||||||
f32.AxpyUnitary(alpha*va, btmpk, btmp)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tmp := alpha
|
|
||||||
if nonUnit {
|
|
||||||
tmp *= a[k*lda+k]
|
|
||||||
}
|
|
||||||
if tmp != 1 {
|
|
||||||
f32.ScalUnitary(tmp, btmpk)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// Cases where a is on the right
|
|
||||||
if tA == blas.NoTrans {
|
|
||||||
if ul == blas.Upper {
|
|
||||||
for i := 0; i < m; i++ {
|
|
||||||
btmp := b[i*ldb : i*ldb+n]
|
|
||||||
for k := n - 1; k >= 0; k-- {
|
|
||||||
tmp := alpha * btmp[k]
|
|
||||||
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
|
|
||||||
}
|
|
||||||
for i := 0; i < m; i++ {
|
|
||||||
btmp := b[i*ldb : i*ldb+n]
|
|
||||||
for k := 0; k < n; k++ {
|
|
||||||
tmp := alpha * btmp[k]
|
|
||||||
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
|
|
||||||
}
|
|
||||||
// Cases where a is transposed.
|
|
||||||
if ul == blas.Upper {
|
|
||||||
for i := 0; i < m; i++ {
|
|
||||||
btmp := b[i*ldb : i*ldb+n]
|
|
||||||
for j, vb := range btmp {
|
|
||||||
tmp := vb
|
|
||||||
if nonUnit {
|
|
||||||
tmp *= a[j*lda+j]
|
|
||||||
}
|
|
||||||
tmp += f32.DotUnitary(a[j*lda+j+1:j*lda+n], btmp[j+1:n])
|
|
||||||
btmp[j] = alpha * tmp
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for i := 0; i < m; i++ {
|
|
||||||
btmp := b[i*ldb : i*ldb+n]
|
|
||||||
for j := n - 1; j >= 0; j-- {
|
|
||||||
tmp := btmp[j]
|
|
||||||
if nonUnit {
|
|
||||||
tmp *= a[j*lda+j]
|
|
||||||
}
|
|
||||||
tmp += f32.DotUnitary(a[j*lda:j*lda+j], btmp[:j])
|
|
||||||
btmp[j] = alpha * tmp
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
864
vendor/gonum.org/v1/gonum/blas/gonum/level3float64.go
generated
vendored
864
vendor/gonum.org/v1/gonum/blas/gonum/level3float64.go
generated
vendored
@@ -1,864 +0,0 @@
|
|||||||
// Copyright ©2014 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"
|
|
||||||
"gonum.org/v1/gonum/internal/asm/f64"
|
|
||||||
)
|
|
||||||
|
|
||||||
var _ blas.Float64Level3 = Implementation{}
|
|
||||||
|
|
||||||
// Dtrsm solves one of the matrix equations
|
|
||||||
// A * X = alpha * B if tA == blas.NoTrans and side == blas.Left
|
|
||||||
// Aᵀ * X = alpha * B if tA == blas.Trans or blas.ConjTrans, and side == blas.Left
|
|
||||||
// X * A = alpha * B if tA == blas.NoTrans and side == blas.Right
|
|
||||||
// X * Aᵀ = alpha * B if tA == blas.Trans or blas.ConjTrans, and side == 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, X contains the values of B, and the result is
|
|
||||||
// stored in-place into X.
|
|
||||||
//
|
|
||||||
// No check is made that A is invertible.
|
|
||||||
func (Implementation) Dtrsm(s blas.Side, ul blas.Uplo, tA blas.Transpose, d blas.Diag, m, n int, alpha float64, a []float64, lda int, b []float64, ldb int) {
|
|
||||||
if s != blas.Left && s != blas.Right {
|
|
||||||
panic(badSide)
|
|
||||||
}
|
|
||||||
if ul != blas.Lower && ul != blas.Upper {
|
|
||||||
panic(badUplo)
|
|
||||||
}
|
|
||||||
if tA != blas.NoTrans && tA != blas.Trans && tA != blas.ConjTrans {
|
|
||||||
panic(badTranspose)
|
|
||||||
}
|
|
||||||
if d != blas.NonUnit && d != blas.Unit {
|
|
||||||
panic(badDiag)
|
|
||||||
}
|
|
||||||
if m < 0 {
|
|
||||||
panic(mLT0)
|
|
||||||
}
|
|
||||||
if n < 0 {
|
|
||||||
panic(nLT0)
|
|
||||||
}
|
|
||||||
k := n
|
|
||||||
if s == blas.Left {
|
|
||||||
k = m
|
|
||||||
}
|
|
||||||
if lda < max(1, k) {
|
|
||||||
panic(badLdA)
|
|
||||||
}
|
|
||||||
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]
|
|
||||||
for j := range btmp {
|
|
||||||
btmp[j] = 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
nonUnit := d == blas.NonUnit
|
|
||||||
if s == blas.Left {
|
|
||||||
if tA == blas.NoTrans {
|
|
||||||
if ul == blas.Upper {
|
|
||||||
for i := m - 1; i >= 0; i-- {
|
|
||||||
btmp := b[i*ldb : i*ldb+n]
|
|
||||||
if alpha != 1 {
|
|
||||||
f64.ScalUnitary(alpha, btmp)
|
|
||||||
}
|
|
||||||
for ka, va := range a[i*lda+i+1 : i*lda+m] {
|
|
||||||
if va != 0 {
|
|
||||||
k := ka + i + 1
|
|
||||||
f64.AxpyUnitary(-va, b[k*ldb:k*ldb+n], btmp)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if nonUnit {
|
|
||||||
tmp := 1 / a[i*lda+i]
|
|
||||||
f64.ScalUnitary(tmp, btmp)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for i := 0; i < m; i++ {
|
|
||||||
btmp := b[i*ldb : i*ldb+n]
|
|
||||||
if alpha != 1 {
|
|
||||||
f64.ScalUnitary(alpha, btmp)
|
|
||||||
}
|
|
||||||
for k, va := range a[i*lda : i*lda+i] {
|
|
||||||
if va != 0 {
|
|
||||||
f64.AxpyUnitary(-va, b[k*ldb:k*ldb+n], btmp)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if nonUnit {
|
|
||||||
tmp := 1 / a[i*lda+i]
|
|
||||||
f64.ScalUnitary(tmp, btmp)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// Cases where a is transposed
|
|
||||||
if ul == blas.Upper {
|
|
||||||
for k := 0; k < m; k++ {
|
|
||||||
btmpk := b[k*ldb : k*ldb+n]
|
|
||||||
if nonUnit {
|
|
||||||
tmp := 1 / a[k*lda+k]
|
|
||||||
f64.ScalUnitary(tmp, btmpk)
|
|
||||||
}
|
|
||||||
for ia, va := range a[k*lda+k+1 : k*lda+m] {
|
|
||||||
if va != 0 {
|
|
||||||
i := ia + k + 1
|
|
||||||
f64.AxpyUnitary(-va, btmpk, b[i*ldb:i*ldb+n])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if alpha != 1 {
|
|
||||||
f64.ScalUnitary(alpha, btmpk)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for k := m - 1; k >= 0; k-- {
|
|
||||||
btmpk := b[k*ldb : k*ldb+n]
|
|
||||||
if nonUnit {
|
|
||||||
tmp := 1 / a[k*lda+k]
|
|
||||||
f64.ScalUnitary(tmp, btmpk)
|
|
||||||
}
|
|
||||||
for i, va := range a[k*lda : k*lda+k] {
|
|
||||||
if va != 0 {
|
|
||||||
f64.AxpyUnitary(-va, btmpk, b[i*ldb:i*ldb+n])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if alpha != 1 {
|
|
||||||
f64.ScalUnitary(alpha, btmpk)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// Cases where a is to the right of X.
|
|
||||||
if tA == blas.NoTrans {
|
|
||||||
if ul == blas.Upper {
|
|
||||||
for i := 0; i < m; i++ {
|
|
||||||
btmp := b[i*ldb : i*ldb+n]
|
|
||||||
if alpha != 1 {
|
|
||||||
f64.ScalUnitary(alpha, btmp)
|
|
||||||
}
|
|
||||||
for k, vb := range btmp {
|
|
||||||
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*ldb : i*ldb+n]
|
|
||||||
if alpha != 1 {
|
|
||||||
f64.ScalUnitary(alpha, btmp)
|
|
||||||
}
|
|
||||||
for k := n - 1; k >= 0; k-- {
|
|
||||||
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
|
|
||||||
}
|
|
||||||
// Cases where a is transposed.
|
|
||||||
if ul == blas.Upper {
|
|
||||||
for i := 0; i < m; i++ {
|
|
||||||
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 {
|
|
||||||
tmp /= a[j*lda+j]
|
|
||||||
}
|
|
||||||
btmp[j] = tmp
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for i := 0; i < m; i++ {
|
|
||||||
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[:j])
|
|
||||||
if nonUnit {
|
|
||||||
tmp /= a[j*lda+j]
|
|
||||||
}
|
|
||||||
btmp[j] = tmp
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dsymm performs one of the matrix-matrix operations
|
|
||||||
// C = alpha * A * B + beta * C if side == blas.Left
|
|
||||||
// C = alpha * B * A + beta * C if side == blas.Right
|
|
||||||
// where A is an n×n or m×m symmetric matrix, B and C are m×n matrices, and alpha
|
|
||||||
// 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(badSide)
|
|
||||||
}
|
|
||||||
if ul != blas.Lower && ul != blas.Upper {
|
|
||||||
panic(badUplo)
|
|
||||||
}
|
|
||||||
if m < 0 {
|
|
||||||
panic(mLT0)
|
|
||||||
}
|
|
||||||
if n < 0 {
|
|
||||||
panic(nLT0)
|
|
||||||
}
|
|
||||||
k := n
|
|
||||||
if s == blas.Left {
|
|
||||||
k = m
|
|
||||||
}
|
|
||||||
if lda < max(1, k) {
|
|
||||||
panic(badLdA)
|
|
||||||
}
|
|
||||||
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 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++ {
|
|
||||||
ctmp := c[i*ldc : i*ldc+n]
|
|
||||||
for j := range ctmp {
|
|
||||||
ctmp[j] = 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for i := 0; i < m; i++ {
|
|
||||||
ctmp := c[i*ldc : i*ldc+n]
|
|
||||||
for j := 0; j < n; j++ {
|
|
||||||
ctmp[j] *= beta
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
isUpper := ul == blas.Upper
|
|
||||||
if s == blas.Left {
|
|
||||||
for i := 0; i < m; i++ {
|
|
||||||
atmp := alpha * a[i*lda+i]
|
|
||||||
btmp := b[i*ldb : i*ldb+n]
|
|
||||||
ctmp := c[i*ldc : i*ldc+n]
|
|
||||||
for j, v := range btmp {
|
|
||||||
ctmp[j] *= beta
|
|
||||||
ctmp[j] += atmp * v
|
|
||||||
}
|
|
||||||
|
|
||||||
for k := 0; k < i; k++ {
|
|
||||||
var atmp float64
|
|
||||||
if isUpper {
|
|
||||||
atmp = a[k*lda+i]
|
|
||||||
} else {
|
|
||||||
atmp = a[i*lda+k]
|
|
||||||
}
|
|
||||||
atmp *= alpha
|
|
||||||
f64.AxpyUnitary(atmp, b[k*ldb:k*ldb+n], ctmp)
|
|
||||||
}
|
|
||||||
for k := i + 1; k < m; k++ {
|
|
||||||
var atmp float64
|
|
||||||
if isUpper {
|
|
||||||
atmp = a[i*lda+k]
|
|
||||||
} else {
|
|
||||||
atmp = a[k*lda+i]
|
|
||||||
}
|
|
||||||
atmp *= alpha
|
|
||||||
f64.AxpyUnitary(atmp, b[k*ldb:k*ldb+n], ctmp)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if isUpper {
|
|
||||||
for i := 0; i < m; i++ {
|
|
||||||
for j := n - 1; j >= 0; j-- {
|
|
||||||
tmp := alpha * b[i*ldb+j]
|
|
||||||
var tmp2 float64
|
|
||||||
atmp := a[j*lda+j+1 : j*lda+n]
|
|
||||||
btmp := b[i*ldb+j+1 : i*ldb+n]
|
|
||||||
ctmp := c[i*ldc+j+1 : i*ldc+n]
|
|
||||||
for k, v := range atmp {
|
|
||||||
ctmp[k] += tmp * v
|
|
||||||
tmp2 += btmp[k] * v
|
|
||||||
}
|
|
||||||
c[i*ldc+j] *= beta
|
|
||||||
c[i*ldc+j] += tmp*a[j*lda+j] + alpha*tmp2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for i := 0; i < m; i++ {
|
|
||||||
for j := 0; j < n; j++ {
|
|
||||||
tmp := alpha * b[i*ldb+j]
|
|
||||||
var tmp2 float64
|
|
||||||
atmp := a[j*lda : j*lda+j]
|
|
||||||
btmp := b[i*ldb : i*ldb+j]
|
|
||||||
ctmp := c[i*ldc : i*ldc+j]
|
|
||||||
for k, v := range atmp {
|
|
||||||
ctmp[k] += tmp * v
|
|
||||||
tmp2 += btmp[k] * v
|
|
||||||
}
|
|
||||||
c[i*ldc+j] *= beta
|
|
||||||
c[i*ldc+j] += tmp*a[j*lda+j] + alpha*tmp2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dsyrk performs one of the symmetric rank-k operations
|
|
||||||
// C = alpha * A * Aᵀ + beta * C if tA == blas.NoTrans
|
|
||||||
// C = alpha * Aᵀ * A + beta * C if tA == blas.Trans or tA == blas.ConjTrans
|
|
||||||
// where A is an n×k or k×n matrix, C is an n×n symmetric matrix, and alpha and
|
|
||||||
// beta are scalars.
|
|
||||||
func (Implementation) Dsyrk(ul blas.Uplo, tA blas.Transpose, n, k int, alpha float64, a []float64, lda int, beta float64, c []float64, ldc int) {
|
|
||||||
if ul != blas.Lower && ul != blas.Upper {
|
|
||||||
panic(badUplo)
|
|
||||||
}
|
|
||||||
if tA != blas.Trans && tA != blas.NoTrans && tA != blas.ConjTrans {
|
|
||||||
panic(badTranspose)
|
|
||||||
}
|
|
||||||
if n < 0 {
|
|
||||||
panic(nLT0)
|
|
||||||
}
|
|
||||||
if k < 0 {
|
|
||||||
panic(kLT0)
|
|
||||||
}
|
|
||||||
row, col := k, n
|
|
||||||
if tA == blas.NoTrans {
|
|
||||||
row, col = n, k
|
|
||||||
}
|
|
||||||
if lda < max(1, col) {
|
|
||||||
panic(badLdA)
|
|
||||||
}
|
|
||||||
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 {
|
|
||||||
for i := 0; i < n; i++ {
|
|
||||||
ctmp := c[i*ldc+i : i*ldc+n]
|
|
||||||
for j := range ctmp {
|
|
||||||
ctmp[j] = 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for i := 0; i < n; i++ {
|
|
||||||
ctmp := c[i*ldc : i*ldc+i+1]
|
|
||||||
for j := range ctmp {
|
|
||||||
ctmp[j] = 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if ul == blas.Upper {
|
|
||||||
for i := 0; i < n; i++ {
|
|
||||||
ctmp := c[i*ldc+i : i*ldc+n]
|
|
||||||
for j := range ctmp {
|
|
||||||
ctmp[j] *= beta
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for i := 0; i < n; i++ {
|
|
||||||
ctmp := c[i*ldc : i*ldc+i+1]
|
|
||||||
for j := range ctmp {
|
|
||||||
ctmp[j] *= beta
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if tA == blas.NoTrans {
|
|
||||||
if ul == blas.Upper {
|
|
||||||
for i := 0; i < n; i++ {
|
|
||||||
ctmp := c[i*ldc+i : i*ldc+n]
|
|
||||||
atmp := a[i*lda : i*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]
|
|
||||||
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
|
|
||||||
}
|
|
||||||
// Cases where a is transposed.
|
|
||||||
if ul == blas.Upper {
|
|
||||||
for i := 0; i < n; i++ {
|
|
||||||
ctmp := c[i*ldc+i : i*ldc+n]
|
|
||||||
if beta == 0 {
|
|
||||||
for j := range ctmp {
|
|
||||||
ctmp[j] = 0
|
|
||||||
}
|
|
||||||
} else if beta != 1 {
|
|
||||||
for j := range ctmp {
|
|
||||||
ctmp[j] *= beta
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for l := 0; l < k; l++ {
|
|
||||||
tmp := alpha * a[l*lda+i]
|
|
||||||
if tmp != 0 {
|
|
||||||
f64.AxpyUnitary(tmp, a[l*lda+i:l*lda+n], ctmp)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for i := 0; i < n; i++ {
|
|
||||||
ctmp := c[i*ldc : i*ldc+i+1]
|
|
||||||
if beta != 1 {
|
|
||||||
for j := range ctmp {
|
|
||||||
ctmp[j] *= beta
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for l := 0; l < k; l++ {
|
|
||||||
tmp := alpha * a[l*lda+i]
|
|
||||||
if tmp != 0 {
|
|
||||||
f64.AxpyUnitary(tmp, a[l*lda:l*lda+i+1], ctmp)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dsyr2k performs one of the symmetric rank 2k operations
|
|
||||||
// C = alpha * A * Bᵀ + alpha * B * Aᵀ + beta * C if tA == blas.NoTrans
|
|
||||||
// C = alpha * Aᵀ * B + alpha * Bᵀ * A + beta * C if tA == blas.Trans or tA == blas.ConjTrans
|
|
||||||
// where A and B are n×k or k×n matrices, C is an n×n symmetric matrix, and
|
|
||||||
// alpha and beta are scalars.
|
|
||||||
func (Implementation) Dsyr2k(ul blas.Uplo, tA blas.Transpose, n, k int, alpha float64, a []float64, lda int, b []float64, ldb int, beta float64, c []float64, ldc int) {
|
|
||||||
if ul != blas.Lower && ul != blas.Upper {
|
|
||||||
panic(badUplo)
|
|
||||||
}
|
|
||||||
if tA != blas.Trans && tA != blas.NoTrans && tA != blas.ConjTrans {
|
|
||||||
panic(badTranspose)
|
|
||||||
}
|
|
||||||
if n < 0 {
|
|
||||||
panic(nLT0)
|
|
||||||
}
|
|
||||||
if k < 0 {
|
|
||||||
panic(kLT0)
|
|
||||||
}
|
|
||||||
row, col := k, n
|
|
||||||
if tA == blas.NoTrans {
|
|
||||||
row, col = n, k
|
|
||||||
}
|
|
||||||
if lda < max(1, col) {
|
|
||||||
panic(badLdA)
|
|
||||||
}
|
|
||||||
if ldb < max(1, col) {
|
|
||||||
panic(badLdB)
|
|
||||||
}
|
|
||||||
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 {
|
|
||||||
for i := 0; i < n; i++ {
|
|
||||||
ctmp := c[i*ldc+i : i*ldc+n]
|
|
||||||
for j := range ctmp {
|
|
||||||
ctmp[j] = 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for i := 0; i < n; i++ {
|
|
||||||
ctmp := c[i*ldc : i*ldc+i+1]
|
|
||||||
for j := range ctmp {
|
|
||||||
ctmp[j] = 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if ul == blas.Upper {
|
|
||||||
for i := 0; i < n; i++ {
|
|
||||||
ctmp := c[i*ldc+i : i*ldc+n]
|
|
||||||
for j := range ctmp {
|
|
||||||
ctmp[j] *= beta
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for i := 0; i < n; i++ {
|
|
||||||
ctmp := c[i*ldc : i*ldc+i+1]
|
|
||||||
for j := range ctmp {
|
|
||||||
ctmp[j] *= beta
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if tA == blas.NoTrans {
|
|
||||||
if ul == blas.Upper {
|
|
||||||
for i := 0; i < n; i++ {
|
|
||||||
atmp := a[i*lda : i*lda+k]
|
|
||||||
btmp := b[i*ldb : i*ldb+k]
|
|
||||||
ctmp := c[i*ldc+i : i*ldc+n]
|
|
||||||
for jc := range ctmp {
|
|
||||||
j := i + jc
|
|
||||||
var tmp1, tmp2 float64
|
|
||||||
binner := b[j*ldb : j*ldb+k]
|
|
||||||
for l, v := range a[j*lda : j*lda+k] {
|
|
||||||
tmp1 += v * btmp[l]
|
|
||||||
tmp2 += atmp[l] * binner[l]
|
|
||||||
}
|
|
||||||
ctmp[jc] *= beta
|
|
||||||
ctmp[jc] += alpha * (tmp1 + tmp2)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for i := 0; i < n; i++ {
|
|
||||||
atmp := a[i*lda : i*lda+k]
|
|
||||||
btmp := b[i*ldb : i*ldb+k]
|
|
||||||
ctmp := c[i*ldc : i*ldc+i+1]
|
|
||||||
for j := 0; j <= i; j++ {
|
|
||||||
var tmp1, tmp2 float64
|
|
||||||
binner := b[j*ldb : j*ldb+k]
|
|
||||||
for l, v := range a[j*lda : j*lda+k] {
|
|
||||||
tmp1 += v * btmp[l]
|
|
||||||
tmp2 += atmp[l] * binner[l]
|
|
||||||
}
|
|
||||||
ctmp[j] *= beta
|
|
||||||
ctmp[j] += alpha * (tmp1 + tmp2)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if ul == blas.Upper {
|
|
||||||
for i := 0; i < n; i++ {
|
|
||||||
ctmp := c[i*ldc+i : i*ldc+n]
|
|
||||||
if beta != 1 {
|
|
||||||
for j := range ctmp {
|
|
||||||
ctmp[j] *= beta
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for l := 0; l < k; l++ {
|
|
||||||
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 {
|
|
||||||
for j, v := range a[l*lda+i : l*lda+n] {
|
|
||||||
ctmp[j] += v*tmp1 + btmp[j]*tmp2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for i := 0; i < n; i++ {
|
|
||||||
ctmp := c[i*ldc : i*ldc+i+1]
|
|
||||||
if beta != 1 {
|
|
||||||
for j := range ctmp {
|
|
||||||
ctmp[j] *= beta
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for l := 0; l < k; l++ {
|
|
||||||
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 {
|
|
||||||
for j, v := range a[l*lda : l*lda+i+1] {
|
|
||||||
ctmp[j] += v*tmp1 + btmp[j]*tmp2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dtrmm performs one of the matrix-matrix operations
|
|
||||||
// B = alpha * A * B if tA == blas.NoTrans and side == blas.Left
|
|
||||||
// B = alpha * Aᵀ * B if tA == blas.Trans or blas.ConjTrans, and side == blas.Left
|
|
||||||
// B = alpha * B * A if tA == blas.NoTrans and side == blas.Right
|
|
||||||
// B = alpha * B * Aᵀ if tA == blas.Trans or blas.ConjTrans, and side == 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 (Implementation) Dtrmm(s blas.Side, ul blas.Uplo, tA blas.Transpose, d blas.Diag, m, n int, alpha float64, a []float64, lda int, b []float64, ldb int) {
|
|
||||||
if s != blas.Left && s != blas.Right {
|
|
||||||
panic(badSide)
|
|
||||||
}
|
|
||||||
if ul != blas.Lower && ul != blas.Upper {
|
|
||||||
panic(badUplo)
|
|
||||||
}
|
|
||||||
if tA != blas.NoTrans && tA != blas.Trans && tA != blas.ConjTrans {
|
|
||||||
panic(badTranspose)
|
|
||||||
}
|
|
||||||
if d != blas.NonUnit && d != blas.Unit {
|
|
||||||
panic(badDiag)
|
|
||||||
}
|
|
||||||
if m < 0 {
|
|
||||||
panic(mLT0)
|
|
||||||
}
|
|
||||||
if n < 0 {
|
|
||||||
panic(nLT0)
|
|
||||||
}
|
|
||||||
k := n
|
|
||||||
if s == blas.Left {
|
|
||||||
k = m
|
|
||||||
}
|
|
||||||
if lda < max(1, k) {
|
|
||||||
panic(badLdA)
|
|
||||||
}
|
|
||||||
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]
|
|
||||||
for j := range btmp {
|
|
||||||
btmp[j] = 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
nonUnit := d == blas.NonUnit
|
|
||||||
if s == blas.Left {
|
|
||||||
if tA == blas.NoTrans {
|
|
||||||
if ul == blas.Upper {
|
|
||||||
for i := 0; i < m; i++ {
|
|
||||||
tmp := alpha
|
|
||||||
if nonUnit {
|
|
||||||
tmp *= a[i*lda+i]
|
|
||||||
}
|
|
||||||
btmp := b[i*ldb : i*ldb+n]
|
|
||||||
f64.ScalUnitary(tmp, btmp)
|
|
||||||
for ka, va := range a[i*lda+i+1 : i*lda+m] {
|
|
||||||
k := ka + i + 1
|
|
||||||
if va != 0 {
|
|
||||||
f64.AxpyUnitary(alpha*va, b[k*ldb:k*ldb+n], btmp)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for i := m - 1; i >= 0; i-- {
|
|
||||||
tmp := alpha
|
|
||||||
if nonUnit {
|
|
||||||
tmp *= a[i*lda+i]
|
|
||||||
}
|
|
||||||
btmp := b[i*ldb : i*ldb+n]
|
|
||||||
f64.ScalUnitary(tmp, btmp)
|
|
||||||
for k, va := range a[i*lda : i*lda+i] {
|
|
||||||
if va != 0 {
|
|
||||||
f64.AxpyUnitary(alpha*va, b[k*ldb:k*ldb+n], btmp)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// Cases where a is transposed.
|
|
||||||
if ul == blas.Upper {
|
|
||||||
for k := m - 1; k >= 0; k-- {
|
|
||||||
btmpk := b[k*ldb : k*ldb+n]
|
|
||||||
for ia, va := range a[k*lda+k+1 : k*lda+m] {
|
|
||||||
i := ia + k + 1
|
|
||||||
btmp := b[i*ldb : i*ldb+n]
|
|
||||||
if va != 0 {
|
|
||||||
f64.AxpyUnitary(alpha*va, btmpk, btmp)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tmp := alpha
|
|
||||||
if nonUnit {
|
|
||||||
tmp *= a[k*lda+k]
|
|
||||||
}
|
|
||||||
if tmp != 1 {
|
|
||||||
f64.ScalUnitary(tmp, btmpk)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for k := 0; k < m; k++ {
|
|
||||||
btmpk := b[k*ldb : k*ldb+n]
|
|
||||||
for i, va := range a[k*lda : k*lda+k] {
|
|
||||||
btmp := b[i*ldb : i*ldb+n]
|
|
||||||
if va != 0 {
|
|
||||||
f64.AxpyUnitary(alpha*va, btmpk, btmp)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tmp := alpha
|
|
||||||
if nonUnit {
|
|
||||||
tmp *= a[k*lda+k]
|
|
||||||
}
|
|
||||||
if tmp != 1 {
|
|
||||||
f64.ScalUnitary(tmp, btmpk)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// Cases where a is on the right
|
|
||||||
if tA == blas.NoTrans {
|
|
||||||
if ul == blas.Upper {
|
|
||||||
for i := 0; i < m; i++ {
|
|
||||||
btmp := b[i*ldb : i*ldb+n]
|
|
||||||
for k := n - 1; k >= 0; k-- {
|
|
||||||
tmp := alpha * btmp[k]
|
|
||||||
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
|
|
||||||
}
|
|
||||||
for i := 0; i < m; i++ {
|
|
||||||
btmp := b[i*ldb : i*ldb+n]
|
|
||||||
for k := 0; k < n; k++ {
|
|
||||||
tmp := alpha * btmp[k]
|
|
||||||
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
|
|
||||||
}
|
|
||||||
// Cases where a is transposed.
|
|
||||||
if ul == blas.Upper {
|
|
||||||
for i := 0; i < m; i++ {
|
|
||||||
btmp := b[i*ldb : i*ldb+n]
|
|
||||||
for j, vb := range btmp {
|
|
||||||
tmp := vb
|
|
||||||
if nonUnit {
|
|
||||||
tmp *= a[j*lda+j]
|
|
||||||
}
|
|
||||||
tmp += f64.DotUnitary(a[j*lda+j+1:j*lda+n], btmp[j+1:n])
|
|
||||||
btmp[j] = alpha * tmp
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for i := 0; i < m; i++ {
|
|
||||||
btmp := b[i*ldb : i*ldb+n]
|
|
||||||
for j := n - 1; j >= 0; j-- {
|
|
||||||
tmp := btmp[j]
|
|
||||||
if nonUnit {
|
|
||||||
tmp *= a[j*lda+j]
|
|
||||||
}
|
|
||||||
tmp += f64.DotUnitary(a[j*lda:j*lda+j], btmp[:j])
|
|
||||||
btmp[j] = alpha * tmp
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
318
vendor/gonum.org/v1/gonum/blas/gonum/sgemm.go
generated
vendored
318
vendor/gonum.org/v1/gonum/blas/gonum/sgemm.go
generated
vendored
@@ -1,318 +0,0 @@
|
|||||||
// Code generated by "go generate gonum.org/v1/gonum/blas/gonum”; DO NOT EDIT.
|
|
||||||
|
|
||||||
// Copyright ©2014 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 (
|
|
||||||
"runtime"
|
|
||||||
"sync"
|
|
||||||
|
|
||||||
"gonum.org/v1/gonum/blas"
|
|
||||||
"gonum.org/v1/gonum/internal/asm/f32"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Sgemm performs one of the matrix-matrix operations
|
|
||||||
// C = alpha * A * B + beta * C
|
|
||||||
// C = alpha * Aᵀ * B + beta * C
|
|
||||||
// C = alpha * A * Bᵀ + beta * C
|
|
||||||
// C = alpha * Aᵀ * Bᵀ + beta * C
|
|
||||||
// where A is an m×k or k×m dense matrix, B is an n×k or k×n dense matrix, C is
|
|
||||||
// an m×n matrix, and alpha and beta are scalars. tA and tB specify whether A or
|
|
||||||
// B are transposed.
|
|
||||||
//
|
|
||||||
// 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) {
|
|
||||||
switch tA {
|
|
||||||
default:
|
|
||||||
panic(badTranspose)
|
|
||||||
case blas.NoTrans, blas.Trans, 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 {
|
|
||||||
if lda < max(1, m) {
|
|
||||||
panic(badLdA)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if lda < max(1, k) {
|
|
||||||
panic(badLdA)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bTrans := tB == blas.Trans || tB == blas.ConjTrans
|
|
||||||
if bTrans {
|
|
||||||
if ldb < max(1, k) {
|
|
||||||
panic(badLdB)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
// scale c
|
|
||||||
if beta != 1 {
|
|
||||||
if beta == 0 {
|
|
||||||
for i := 0; i < m; i++ {
|
|
||||||
ctmp := c[i*ldc : i*ldc+n]
|
|
||||||
for j := range ctmp {
|
|
||||||
ctmp[j] = 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for i := 0; i < m; i++ {
|
|
||||||
ctmp := c[i*ldc : i*ldc+n]
|
|
||||||
for j := range ctmp {
|
|
||||||
ctmp[j] *= beta
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sgemmParallel(aTrans, bTrans, m, n, k, a, lda, b, ldb, c, ldc, alpha)
|
|
||||||
}
|
|
||||||
|
|
||||||
func sgemmParallel(aTrans, bTrans bool, m, n, k int, a []float32, lda int, b []float32, ldb int, c []float32, ldc int, alpha float32) {
|
|
||||||
// dgemmParallel computes a parallel matrix multiplication by partitioning
|
|
||||||
// a and b into sub-blocks, and updating c with the multiplication of the sub-block
|
|
||||||
// In all cases,
|
|
||||||
// A = [ A_11 A_12 ... A_1j
|
|
||||||
// A_21 A_22 ... A_2j
|
|
||||||
// ...
|
|
||||||
// A_i1 A_i2 ... A_ij]
|
|
||||||
//
|
|
||||||
// and same for B. All of the submatrix sizes are blockSize×blockSize except
|
|
||||||
// at the edges.
|
|
||||||
//
|
|
||||||
// In all cases, there is one dimension for each matrix along which
|
|
||||||
// C must be updated sequentially.
|
|
||||||
// Cij = \sum_k Aik Bki, (A * B)
|
|
||||||
// Cij = \sum_k Aki Bkj, (Aᵀ * B)
|
|
||||||
// Cij = \sum_k Aik Bjk, (A * Bᵀ)
|
|
||||||
// Cij = \sum_k Aki Bjk, (Aᵀ * Bᵀ)
|
|
||||||
//
|
|
||||||
// This code computes one {i, j} block sequentially along the k dimension,
|
|
||||||
// and computes all of the {i, j} blocks concurrently. This
|
|
||||||
// partitioning allows Cij to be updated in-place without race-conditions.
|
|
||||||
// Instead of launching a goroutine for each possible concurrent computation,
|
|
||||||
// a number of worker goroutines are created and channels are used to pass
|
|
||||||
// available and completed cases.
|
|
||||||
//
|
|
||||||
// http://alexkr.com/docs/matrixmult.pdf is a good reference on matrix-matrix
|
|
||||||
// multiplies, though this code does not copy matrices to attempt to eliminate
|
|
||||||
// cache misses.
|
|
||||||
|
|
||||||
maxKLen := k
|
|
||||||
parBlocks := blocks(m, blockSize) * blocks(n, blockSize)
|
|
||||||
if parBlocks < minParBlock {
|
|
||||||
// The matrix multiplication is small in the dimensions where it can be
|
|
||||||
// computed concurrently. Just do it in serial.
|
|
||||||
sgemmSerial(aTrans, bTrans, m, n, k, a, lda, b, ldb, c, ldc, alpha)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
nWorkers := runtime.GOMAXPROCS(0)
|
|
||||||
if parBlocks < nWorkers {
|
|
||||||
nWorkers = parBlocks
|
|
||||||
}
|
|
||||||
// There is a tradeoff between the workers having to wait for work
|
|
||||||
// and a large buffer making operations slow.
|
|
||||||
buf := buffMul * nWorkers
|
|
||||||
if buf > parBlocks {
|
|
||||||
buf = parBlocks
|
|
||||||
}
|
|
||||||
|
|
||||||
sendChan := make(chan subMul, buf)
|
|
||||||
|
|
||||||
// Launch workers. A worker receives an {i, j} submatrix of c, and computes
|
|
||||||
// A_ik B_ki (or the transposed version) storing the result in c_ij. When the
|
|
||||||
// channel is finally closed, it signals to the waitgroup that it has finished
|
|
||||||
// computing.
|
|
||||||
var wg sync.WaitGroup
|
|
||||||
for i := 0; i < nWorkers; i++ {
|
|
||||||
wg.Add(1)
|
|
||||||
go func() {
|
|
||||||
defer wg.Done()
|
|
||||||
for sub := range sendChan {
|
|
||||||
i := sub.i
|
|
||||||
j := sub.j
|
|
||||||
leni := blockSize
|
|
||||||
if i+leni > m {
|
|
||||||
leni = m - i
|
|
||||||
}
|
|
||||||
lenj := blockSize
|
|
||||||
if j+lenj > n {
|
|
||||||
lenj = n - j
|
|
||||||
}
|
|
||||||
|
|
||||||
cSub := sliceView32(c, ldc, i, j, leni, lenj)
|
|
||||||
|
|
||||||
// Compute A_ik B_kj for all k
|
|
||||||
for k := 0; k < maxKLen; k += blockSize {
|
|
||||||
lenk := blockSize
|
|
||||||
if k+lenk > maxKLen {
|
|
||||||
lenk = maxKLen - k
|
|
||||||
}
|
|
||||||
var aSub, bSub []float32
|
|
||||||
if aTrans {
|
|
||||||
aSub = sliceView32(a, lda, k, i, lenk, leni)
|
|
||||||
} else {
|
|
||||||
aSub = sliceView32(a, lda, i, k, leni, lenk)
|
|
||||||
}
|
|
||||||
if bTrans {
|
|
||||||
bSub = sliceView32(b, ldb, j, k, lenj, lenk)
|
|
||||||
} else {
|
|
||||||
bSub = sliceView32(b, ldb, k, j, lenk, lenj)
|
|
||||||
}
|
|
||||||
sgemmSerial(aTrans, bTrans, leni, lenj, lenk, aSub, lda, bSub, ldb, cSub, ldc, alpha)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send out all of the {i, j} subblocks for computation.
|
|
||||||
for i := 0; i < m; i += blockSize {
|
|
||||||
for j := 0; j < n; j += blockSize {
|
|
||||||
sendChan <- subMul{
|
|
||||||
i: i,
|
|
||||||
j: j,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
close(sendChan)
|
|
||||||
wg.Wait()
|
|
||||||
}
|
|
||||||
|
|
||||||
// sgemmSerial is serial matrix multiply
|
|
||||||
func sgemmSerial(aTrans, bTrans bool, m, n, k int, a []float32, lda int, b []float32, ldb int, c []float32, ldc int, alpha float32) {
|
|
||||||
switch {
|
|
||||||
case !aTrans && !bTrans:
|
|
||||||
sgemmSerialNotNot(m, n, k, a, lda, b, ldb, c, ldc, alpha)
|
|
||||||
return
|
|
||||||
case aTrans && !bTrans:
|
|
||||||
sgemmSerialTransNot(m, n, k, a, lda, b, ldb, c, ldc, alpha)
|
|
||||||
return
|
|
||||||
case !aTrans && bTrans:
|
|
||||||
sgemmSerialNotTrans(m, n, k, a, lda, b, ldb, c, ldc, alpha)
|
|
||||||
return
|
|
||||||
case aTrans && bTrans:
|
|
||||||
sgemmSerialTransTrans(m, n, k, a, lda, b, ldb, c, ldc, alpha)
|
|
||||||
return
|
|
||||||
default:
|
|
||||||
panic("unreachable")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// sgemmSerial where neither a nor b are transposed
|
|
||||||
func sgemmSerialNotNot(m, n, k int, a []float32, lda int, b []float32, ldb int, c []float32, ldc int, alpha float32) {
|
|
||||||
// This style is used instead of the literal [i*stride +j]) is used because
|
|
||||||
// approximately 5 times faster as of go 1.3.
|
|
||||||
for i := 0; i < m; i++ {
|
|
||||||
ctmp := c[i*ldc : i*ldc+n]
|
|
||||||
for l, v := range a[i*lda : i*lda+k] {
|
|
||||||
tmp := alpha * v
|
|
||||||
if tmp != 0 {
|
|
||||||
f32.AxpyUnitary(tmp, b[l*ldb:l*ldb+n], ctmp)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// sgemmSerial where neither a is transposed and b is not
|
|
||||||
func sgemmSerialTransNot(m, n, k int, a []float32, lda int, b []float32, ldb int, c []float32, ldc int, alpha float32) {
|
|
||||||
// This style is used instead of the literal [i*stride +j]) is used because
|
|
||||||
// approximately 5 times faster as of go 1.3.
|
|
||||||
for l := 0; l < k; l++ {
|
|
||||||
btmp := b[l*ldb : l*ldb+n]
|
|
||||||
for i, v := range a[l*lda : l*lda+m] {
|
|
||||||
tmp := alpha * v
|
|
||||||
if tmp != 0 {
|
|
||||||
ctmp := c[i*ldc : i*ldc+n]
|
|
||||||
f32.AxpyUnitary(tmp, btmp, ctmp)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// sgemmSerial where neither a is not transposed and b is
|
|
||||||
func sgemmSerialNotTrans(m, n, k int, a []float32, lda int, b []float32, ldb int, c []float32, ldc int, alpha float32) {
|
|
||||||
// This style is used instead of the literal [i*stride +j]) is used because
|
|
||||||
// approximately 5 times faster as of go 1.3.
|
|
||||||
for i := 0; i < m; i++ {
|
|
||||||
atmp := a[i*lda : i*lda+k]
|
|
||||||
ctmp := c[i*ldc : i*ldc+n]
|
|
||||||
for j := 0; j < n; j++ {
|
|
||||||
ctmp[j] += alpha * f32.DotUnitary(atmp, b[j*ldb:j*ldb+k])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// sgemmSerial where both are transposed
|
|
||||||
func sgemmSerialTransTrans(m, n, k int, a []float32, lda int, b []float32, ldb int, c []float32, ldc int, alpha float32) {
|
|
||||||
// This style is used instead of the literal [i*stride +j]) is used because
|
|
||||||
// approximately 5 times faster as of go 1.3.
|
|
||||||
for l := 0; l < k; l++ {
|
|
||||||
for i, v := range a[l*lda : l*lda+m] {
|
|
||||||
tmp := alpha * v
|
|
||||||
if tmp != 0 {
|
|
||||||
ctmp := c[i*ldc : i*ldc+n]
|
|
||||||
f32.AxpyInc(tmp, b[l:], ctmp, uintptr(n), uintptr(ldb), 1, 0, 0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func sliceView32(a []float32, lda, i, j, r, c int) []float32 {
|
|
||||||
return a[i*lda+j : (i+r-1)*lda+j+c]
|
|
||||||
}
|
|
||||||
218
vendor/gonum.org/v1/gonum/blas/gonum/single_precision.bash
generated
vendored
218
vendor/gonum.org/v1/gonum/blas/gonum/single_precision.bash
generated
vendored
@@ -1,218 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
# 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.
|
|
||||||
|
|
||||||
WARNINGF32='//\
|
|
||||||
// Float32 implementations are autogenerated and not directly tested.\
|
|
||||||
'
|
|
||||||
WARNINGC64='//\
|
|
||||||
// Complex64 implementations are autogenerated and not directly tested.\
|
|
||||||
'
|
|
||||||
|
|
||||||
# Level1 routines.
|
|
||||||
|
|
||||||
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.AxpyUnitary -> f32.AxpyUnitary' \
|
|
||||||
| gofmt -r 'f64.DotUnitary -> f32.DotUnitary' \
|
|
||||||
| gofmt -r 'f64.ScalInc -> f32.ScalInc' \
|
|
||||||
| gofmt -r 'f64.ScalUnitary -> f32.ScalUnitary' \
|
|
||||||
\
|
|
||||||
| sed -e "s_^\(func (Implementation) \)D\(.*\)\$_$WARNINGF32\1S\2_" \
|
|
||||||
-e 's_^// D_// S_' \
|
|
||||||
-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"_' \
|
|
||||||
>> level1float32.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\(.*\)\$_$WARNINGF32\1S\2_" \
|
|
||||||
-e 's_^// D_// S_' \
|
|
||||||
-e 's_"gonum.org/v1/gonum/internal/asm/f64"_"gonum.org/v1/gonum/internal/asm/f32"_' \
|
|
||||||
>> level1float32_sdot.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\(.*\)\$_$WARNINGF32\1Ds\2_" \
|
|
||||||
-e 's_^// D_// Ds_' \
|
|
||||||
-e 's_"gonum.org/v1/gonum/internal/asm/f64"_"gonum.org/v1/gonum/internal/asm/f32"_' \
|
|
||||||
>> level1float32_dsdot.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\(.*\)\$_$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"_' \
|
|
||||||
>> level1float32_sdsdot.go
|
|
||||||
|
|
||||||
|
|
||||||
# Level2 routines.
|
|
||||||
|
|
||||||
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 '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\(.*\)\$_$WARNINGF32\1S\2_" \
|
|
||||||
-e 's_^// D_// S_' \
|
|
||||||
-e 's_"gonum.org/v1/gonum/internal/asm/f64"_"gonum.org/v1/gonum/internal/asm/f32"_' \
|
|
||||||
>> 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 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\(.*\)\$_$WARNINGF32\1S\2_" \
|
|
||||||
-e 's_^// D_// S_' \
|
|
||||||
-e 's_"gonum.org/v1/gonum/internal/asm/f64"_"gonum.org/v1/gonum/internal/asm/f32"_' \
|
|
||||||
>> 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 'dgemmParallel -> sgemmParallel' \
|
|
||||||
| gofmt -r 'computeNumBlocks64 -> computeNumBlocks32' \
|
|
||||||
| gofmt -r 'dgemmSerial -> sgemmSerial' \
|
|
||||||
| gofmt -r 'dgemmSerialNotNot -> sgemmSerialNotNot' \
|
|
||||||
| gofmt -r 'dgemmSerialTransNot -> sgemmSerialTransNot' \
|
|
||||||
| gofmt -r 'dgemmSerialNotTrans -> sgemmSerialNotTrans' \
|
|
||||||
| gofmt -r 'dgemmSerialTransTrans -> sgemmSerialTransTrans' \
|
|
||||||
\
|
|
||||||
| gofmt -r 'f64.AxpyInc -> f32.AxpyInc' \
|
|
||||||
| gofmt -r 'f64.AxpyUnitary -> f32.AxpyUnitary' \
|
|
||||||
| gofmt -r 'f64.DotUnitary -> f32.DotUnitary' \
|
|
||||||
\
|
|
||||||
| 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
|
|
||||||
4
vendor/gonum.org/v1/gonum/floats/README.md
generated
vendored
4
vendor/gonum.org/v1/gonum/floats/README.md
generated
vendored
@@ -1,4 +0,0 @@
|
|||||||
# Gonum floats [](https://godoc.org/gonum.org/v1/gonum/floats)
|
|
||||||
|
|
||||||
Package floats provides a set of helper routines for dealing with slices of float64.
|
|
||||||
The functions avoid allocations to allow for use within tight loops without garbage collection overhead.
|
|
||||||
11
vendor/gonum.org/v1/gonum/floats/doc.go
generated
vendored
11
vendor/gonum.org/v1/gonum/floats/doc.go
generated
vendored
@@ -1,11 +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 floats provides a set of helper routines for dealing with slices
|
|
||||||
// of float64. The functions avoid allocations to allow for use within tight
|
|
||||||
// loops without garbage collection overhead.
|
|
||||||
//
|
|
||||||
// The convention used is that when a slice is being modified in place, it has
|
|
||||||
// the name dst.
|
|
||||||
package floats // import "gonum.org/v1/gonum/floats"
|
|
||||||
933
vendor/gonum.org/v1/gonum/floats/floats.go
generated
vendored
933
vendor/gonum.org/v1/gonum/floats/floats.go
generated
vendored
@@ -1,933 +0,0 @@
|
|||||||
// 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
|
|
||||||
|
|
||||||
package floats
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"math"
|
|
||||||
"sort"
|
|
||||||
"strconv"
|
|
||||||
|
|
||||||
"gonum.org/v1/gonum/internal/asm/f64"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Add adds, element-wise, the elements of s and dst, and stores in dst.
|
|
||||||
// Panics if the lengths of dst and s do not match.
|
|
||||||
func Add(dst, s []float64) {
|
|
||||||
if len(dst) != len(s) {
|
|
||||||
panic("floats: length of the slices do not match")
|
|
||||||
}
|
|
||||||
f64.AxpyUnitaryTo(dst, 1, s, dst)
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddTo adds, element-wise, the elements of s and t and
|
|
||||||
// stores the result in dst. Panics if the lengths of s, t and dst do not match.
|
|
||||||
func AddTo(dst, s, t []float64) []float64 {
|
|
||||||
if len(s) != len(t) {
|
|
||||||
panic("floats: length of adders do not match")
|
|
||||||
}
|
|
||||||
if len(dst) != len(s) {
|
|
||||||
panic("floats: length of destination does not match length of adder")
|
|
||||||
}
|
|
||||||
f64.AxpyUnitaryTo(dst, 1, s, t)
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddConst adds the scalar c to all of the values in dst.
|
|
||||||
func AddConst(c float64, dst []float64) {
|
|
||||||
f64.AddConst(c, dst)
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddScaled performs dst = dst + alpha * s.
|
|
||||||
// It panics if the lengths of dst and s are not equal.
|
|
||||||
func AddScaled(dst []float64, alpha float64, s []float64) {
|
|
||||||
if len(dst) != len(s) {
|
|
||||||
panic("floats: length of destination and source to not match")
|
|
||||||
}
|
|
||||||
f64.AxpyUnitaryTo(dst, alpha, s, dst)
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddScaledTo performs dst = y + alpha * s, where alpha is a scalar,
|
|
||||||
// and dst, y and s are all slices.
|
|
||||||
// It panics if the lengths of dst, y, and s are not equal.
|
|
||||||
//
|
|
||||||
// At the return of the function, dst[i] = y[i] + alpha * s[i]
|
|
||||||
func AddScaledTo(dst, y []float64, alpha float64, s []float64) []float64 {
|
|
||||||
if len(dst) != len(s) || len(dst) != len(y) {
|
|
||||||
panic("floats: lengths of slices do not match")
|
|
||||||
}
|
|
||||||
f64.AxpyUnitaryTo(dst, alpha, s, y)
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// argsort is a helper that implements sort.Interface, as used by
|
|
||||||
// Argsort.
|
|
||||||
type argsort struct {
|
|
||||||
s []float64
|
|
||||||
inds []int
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a argsort) Len() int {
|
|
||||||
return len(a.s)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a argsort) Less(i, j int) bool {
|
|
||||||
return a.s[i] < a.s[j]
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a argsort) Swap(i, j int) {
|
|
||||||
a.s[i], a.s[j] = a.s[j], a.s[i]
|
|
||||||
a.inds[i], a.inds[j] = a.inds[j], a.inds[i]
|
|
||||||
}
|
|
||||||
|
|
||||||
// Argsort sorts the elements of dst while tracking their original order.
|
|
||||||
// At the conclusion of Argsort, dst will contain the original elements of dst
|
|
||||||
// but sorted in increasing order, and inds will contain the original position
|
|
||||||
// of the elements in the slice such that dst[i] = origDst[inds[i]].
|
|
||||||
// It panics if the lengths of dst and inds do not match.
|
|
||||||
func Argsort(dst []float64, inds []int) {
|
|
||||||
if len(dst) != len(inds) {
|
|
||||||
panic("floats: length of inds does not match length of slice")
|
|
||||||
}
|
|
||||||
for i := range dst {
|
|
||||||
inds[i] = i
|
|
||||||
}
|
|
||||||
|
|
||||||
a := argsort{s: dst, inds: inds}
|
|
||||||
sort.Sort(a)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Count applies the function f to every element of s and returns the number
|
|
||||||
// of times the function returned true.
|
|
||||||
func Count(f func(float64) bool, s []float64) int {
|
|
||||||
var n int
|
|
||||||
for _, val := range s {
|
|
||||||
if f(val) {
|
|
||||||
n++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return n
|
|
||||||
}
|
|
||||||
|
|
||||||
// CumProd finds the cumulative product of the first i elements in
|
|
||||||
// s and puts them in place into the ith element of the
|
|
||||||
// destination dst. A panic will occur if the lengths of arguments
|
|
||||||
// do not match.
|
|
||||||
//
|
|
||||||
// At the return of the function, dst[i] = s[i] * s[i-1] * s[i-2] * ...
|
|
||||||
func CumProd(dst, s []float64) []float64 {
|
|
||||||
if len(dst) != len(s) {
|
|
||||||
panic("floats: length of destination does not match length of the source")
|
|
||||||
}
|
|
||||||
if len(dst) == 0 {
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
return f64.CumProd(dst, s)
|
|
||||||
}
|
|
||||||
|
|
||||||
// CumSum finds the cumulative sum of the first i elements in
|
|
||||||
// s and puts them in place into the ith element of the
|
|
||||||
// destination dst. A panic will occur if the lengths of arguments
|
|
||||||
// do not match.
|
|
||||||
//
|
|
||||||
// At the return of the function, dst[i] = s[i] + s[i-1] + s[i-2] + ...
|
|
||||||
func CumSum(dst, s []float64) []float64 {
|
|
||||||
if len(dst) != len(s) {
|
|
||||||
panic("floats: length of destination does not match length of the source")
|
|
||||||
}
|
|
||||||
if len(dst) == 0 {
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
return f64.CumSum(dst, s)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Distance computes the L-norm of s - t. See Norm for special cases.
|
|
||||||
// A panic will occur if the lengths of s and t do not match.
|
|
||||||
func Distance(s, t []float64, L float64) float64 {
|
|
||||||
if len(s) != len(t) {
|
|
||||||
panic("floats: slice lengths do not match")
|
|
||||||
}
|
|
||||||
if len(s) == 0 {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
var norm float64
|
|
||||||
if L == 2 {
|
|
||||||
for i, v := range s {
|
|
||||||
diff := t[i] - v
|
|
||||||
norm = math.Hypot(norm, diff)
|
|
||||||
}
|
|
||||||
return norm
|
|
||||||
}
|
|
||||||
if L == 1 {
|
|
||||||
for i, v := range s {
|
|
||||||
norm += math.Abs(t[i] - v)
|
|
||||||
}
|
|
||||||
return norm
|
|
||||||
}
|
|
||||||
if math.IsInf(L, 1) {
|
|
||||||
for i, v := range s {
|
|
||||||
absDiff := math.Abs(t[i] - v)
|
|
||||||
if absDiff > norm {
|
|
||||||
norm = absDiff
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return norm
|
|
||||||
}
|
|
||||||
for i, v := range s {
|
|
||||||
norm += math.Pow(math.Abs(t[i]-v), L)
|
|
||||||
}
|
|
||||||
return math.Pow(norm, 1/L)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Div performs element-wise division dst / s
|
|
||||||
// and stores the value in dst. It panics if the
|
|
||||||
// lengths of s and t are not equal.
|
|
||||||
func Div(dst, s []float64) {
|
|
||||||
if len(dst) != len(s) {
|
|
||||||
panic("floats: slice lengths do not match")
|
|
||||||
}
|
|
||||||
f64.Div(dst, s)
|
|
||||||
}
|
|
||||||
|
|
||||||
// DivTo performs element-wise division s / t
|
|
||||||
// and stores the value in dst. It panics if the
|
|
||||||
// lengths of s, t, and dst are not equal.
|
|
||||||
func DivTo(dst, s, t []float64) []float64 {
|
|
||||||
if len(s) != len(t) || len(dst) != len(t) {
|
|
||||||
panic("floats: slice lengths do not match")
|
|
||||||
}
|
|
||||||
return f64.DivTo(dst, s, t)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dot computes the dot product of s1 and s2, i.e.
|
|
||||||
// sum_{i = 1}^N s1[i]*s2[i].
|
|
||||||
// A panic will occur if lengths of arguments do not match.
|
|
||||||
func Dot(s1, s2 []float64) float64 {
|
|
||||||
if len(s1) != len(s2) {
|
|
||||||
panic("floats: lengths of the slices do not match")
|
|
||||||
}
|
|
||||||
return f64.DotUnitary(s1, s2)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Equal returns true if the slices have equal lengths and
|
|
||||||
// all elements are numerically identical.
|
|
||||||
func Equal(s1, s2 []float64) bool {
|
|
||||||
if len(s1) != len(s2) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
for i, val := range s1 {
|
|
||||||
if s2[i] != val {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// EqualApprox returns true if the slices have equal lengths and
|
|
||||||
// all element pairs have an absolute tolerance less than tol or a
|
|
||||||
// relative tolerance less than tol.
|
|
||||||
func EqualApprox(s1, s2 []float64, tol float64) bool {
|
|
||||||
if len(s1) != len(s2) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
for i, a := range s1 {
|
|
||||||
if !EqualWithinAbsOrRel(a, s2[i], tol, tol) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// EqualFunc returns true if the slices have the same lengths
|
|
||||||
// and the function returns true for all element pairs.
|
|
||||||
func EqualFunc(s1, s2 []float64, f func(float64, float64) bool) bool {
|
|
||||||
if len(s1) != len(s2) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
for i, val := range s1 {
|
|
||||||
if !f(val, s2[i]) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// EqualWithinAbs returns true if a and b have an absolute
|
|
||||||
// difference of less than tol.
|
|
||||||
func EqualWithinAbs(a, b, tol float64) bool {
|
|
||||||
return a == b || math.Abs(a-b) <= tol
|
|
||||||
}
|
|
||||||
|
|
||||||
const minNormalFloat64 = 2.2250738585072014e-308
|
|
||||||
|
|
||||||
// EqualWithinRel returns true if the difference between a and b
|
|
||||||
// is not greater than tol times the greater value.
|
|
||||||
func EqualWithinRel(a, b, tol float64) bool {
|
|
||||||
if a == b {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
delta := math.Abs(a - b)
|
|
||||||
if delta <= minNormalFloat64 {
|
|
||||||
return delta <= tol*minNormalFloat64
|
|
||||||
}
|
|
||||||
// We depend on the division in this relationship to identify
|
|
||||||
// infinities (we rely on the NaN to fail the test) otherwise
|
|
||||||
// we compare Infs of the same sign and evaluate Infs as equal
|
|
||||||
// independent of sign.
|
|
||||||
return delta/math.Max(math.Abs(a), math.Abs(b)) <= tol
|
|
||||||
}
|
|
||||||
|
|
||||||
// EqualWithinAbsOrRel returns true if a and b are equal to within
|
|
||||||
// the absolute tolerance.
|
|
||||||
func EqualWithinAbsOrRel(a, b, absTol, relTol float64) bool {
|
|
||||||
if EqualWithinAbs(a, b, absTol) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return EqualWithinRel(a, b, relTol)
|
|
||||||
}
|
|
||||||
|
|
||||||
// EqualWithinULP returns true if a and b are equal to within
|
|
||||||
// the specified number of floating point units in the last place.
|
|
||||||
func EqualWithinULP(a, b float64, ulp uint) bool {
|
|
||||||
if a == b {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
if math.IsNaN(a) || math.IsNaN(b) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if math.Signbit(a) != math.Signbit(b) {
|
|
||||||
return math.Float64bits(math.Abs(a))+math.Float64bits(math.Abs(b)) <= uint64(ulp)
|
|
||||||
}
|
|
||||||
return ulpDiff(math.Float64bits(a), math.Float64bits(b)) <= uint64(ulp)
|
|
||||||
}
|
|
||||||
|
|
||||||
func ulpDiff(a, b uint64) uint64 {
|
|
||||||
if a > b {
|
|
||||||
return a - b
|
|
||||||
}
|
|
||||||
return b - a
|
|
||||||
}
|
|
||||||
|
|
||||||
// EqualLengths returns true if all of the slices have equal length,
|
|
||||||
// and false otherwise. Returns true if there are no input slices.
|
|
||||||
func EqualLengths(slices ...[]float64) bool {
|
|
||||||
// This length check is needed: http://play.golang.org/p/sdty6YiLhM
|
|
||||||
if len(slices) == 0 {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
l := len(slices[0])
|
|
||||||
for i := 1; i < len(slices); i++ {
|
|
||||||
if len(slices[i]) != l {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find applies f to every element of s and returns the indices of the first
|
|
||||||
// k elements for which the f returns true, or all such elements
|
|
||||||
// if k < 0.
|
|
||||||
// Find will reslice inds to have 0 length, and will append
|
|
||||||
// found indices to inds.
|
|
||||||
// If k > 0 and there are fewer than k elements in s satisfying f,
|
|
||||||
// all of the found elements will be returned along with an error.
|
|
||||||
// At the return of the function, the input inds will be in an undetermined state.
|
|
||||||
func Find(inds []int, f func(float64) bool, s []float64, k int) ([]int, error) {
|
|
||||||
// inds is also returned to allow for calling with nil
|
|
||||||
|
|
||||||
// Reslice inds to have zero length
|
|
||||||
inds = inds[:0]
|
|
||||||
|
|
||||||
// If zero elements requested, can just return
|
|
||||||
if k == 0 {
|
|
||||||
return inds, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// If k < 0, return all of the found indices
|
|
||||||
if k < 0 {
|
|
||||||
for i, val := range s {
|
|
||||||
if f(val) {
|
|
||||||
inds = append(inds, i)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return inds, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise, find the first k elements
|
|
||||||
nFound := 0
|
|
||||||
for i, val := range s {
|
|
||||||
if f(val) {
|
|
||||||
inds = append(inds, i)
|
|
||||||
nFound++
|
|
||||||
if nFound == k {
|
|
||||||
return inds, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Finished iterating over the loop, which means k elements were not found
|
|
||||||
return inds, errors.New("floats: insufficient elements found")
|
|
||||||
}
|
|
||||||
|
|
||||||
// HasNaN returns true if the slice s has any values that are NaN and false
|
|
||||||
// otherwise.
|
|
||||||
func HasNaN(s []float64) bool {
|
|
||||||
for _, v := range s {
|
|
||||||
if math.IsNaN(v) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// LogSpan returns a set of n equally spaced points in log space between,
|
|
||||||
// l and u where N is equal to len(dst). The first element of the
|
|
||||||
// resulting dst will be l and the final element of dst will be u.
|
|
||||||
// Panics if len(dst) < 2
|
|
||||||
// Note that this call will return NaNs if either l or u are negative, and
|
|
||||||
// will return all zeros if l or u is zero.
|
|
||||||
// Also returns the mutated slice dst, so that it can be used in range, like:
|
|
||||||
//
|
|
||||||
// for i, x := range LogSpan(dst, l, u) { ... }
|
|
||||||
func LogSpan(dst []float64, l, u float64) []float64 {
|
|
||||||
Span(dst, math.Log(l), math.Log(u))
|
|
||||||
for i := range dst {
|
|
||||||
dst[i] = math.Exp(dst[i])
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// LogSumExp returns the log of the sum of the exponentials of the values in s.
|
|
||||||
// Panics if s is an empty slice.
|
|
||||||
func LogSumExp(s []float64) float64 {
|
|
||||||
// Want to do this in a numerically stable way which avoids
|
|
||||||
// overflow and underflow
|
|
||||||
// First, find the maximum value in the slice.
|
|
||||||
maxval := Max(s)
|
|
||||||
if math.IsInf(maxval, 0) {
|
|
||||||
// If it's infinity either way, the logsumexp will be infinity as well
|
|
||||||
// returning now avoids NaNs
|
|
||||||
return maxval
|
|
||||||
}
|
|
||||||
var lse float64
|
|
||||||
// Compute the sumexp part
|
|
||||||
for _, val := range s {
|
|
||||||
lse += math.Exp(val - maxval)
|
|
||||||
}
|
|
||||||
// Take the log and add back on the constant taken out
|
|
||||||
return math.Log(lse) + maxval
|
|
||||||
}
|
|
||||||
|
|
||||||
// Max returns the maximum value in the input slice. If the slice is empty, Max will panic.
|
|
||||||
func Max(s []float64) float64 {
|
|
||||||
return s[MaxIdx(s)]
|
|
||||||
}
|
|
||||||
|
|
||||||
// MaxIdx returns the index of the maximum value in the input slice. If several
|
|
||||||
// entries have the maximum value, the first such index is returned. If the slice
|
|
||||||
// is empty, MaxIdx will panic.
|
|
||||||
func MaxIdx(s []float64) int {
|
|
||||||
if len(s) == 0 {
|
|
||||||
panic("floats: zero slice length")
|
|
||||||
}
|
|
||||||
max := math.NaN()
|
|
||||||
var ind int
|
|
||||||
for i, v := range s {
|
|
||||||
if math.IsNaN(v) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if v > max || math.IsNaN(max) {
|
|
||||||
max = v
|
|
||||||
ind = i
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ind
|
|
||||||
}
|
|
||||||
|
|
||||||
// Min returns the maximum value in the input slice. If the slice is empty, Min will panic.
|
|
||||||
func Min(s []float64) float64 {
|
|
||||||
return s[MinIdx(s)]
|
|
||||||
}
|
|
||||||
|
|
||||||
// MinIdx returns the index of the minimum value in the input slice. If several
|
|
||||||
// entries have the maximum value, the first such index is returned. If the slice
|
|
||||||
// is empty, MinIdx will panic.
|
|
||||||
func MinIdx(s []float64) int {
|
|
||||||
if len(s) == 0 {
|
|
||||||
panic("floats: zero slice length")
|
|
||||||
}
|
|
||||||
min := math.NaN()
|
|
||||||
var ind int
|
|
||||||
for i, v := range s {
|
|
||||||
if math.IsNaN(v) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if v < min || math.IsNaN(min) {
|
|
||||||
min = v
|
|
||||||
ind = i
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ind
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mul performs element-wise multiplication between dst
|
|
||||||
// and s and stores the value in dst. Panics if the
|
|
||||||
// lengths of s and t are not equal.
|
|
||||||
func Mul(dst, s []float64) {
|
|
||||||
if len(dst) != len(s) {
|
|
||||||
panic("floats: slice lengths do not match")
|
|
||||||
}
|
|
||||||
for i, val := range s {
|
|
||||||
dst[i] *= val
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MulTo performs element-wise multiplication between s
|
|
||||||
// and t and stores the value in dst. Panics if the
|
|
||||||
// lengths of s, t, and dst are not equal.
|
|
||||||
func MulTo(dst, s, t []float64) []float64 {
|
|
||||||
if len(s) != len(t) || len(dst) != len(t) {
|
|
||||||
panic("floats: slice lengths do not match")
|
|
||||||
}
|
|
||||||
for i, val := range t {
|
|
||||||
dst[i] = val * s[i]
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
nanBits = 0x7ff8000000000000
|
|
||||||
nanMask = 0xfff8000000000000
|
|
||||||
)
|
|
||||||
|
|
||||||
// NaNWith returns an IEEE 754 "quiet not-a-number" value with the
|
|
||||||
// payload specified in the low 51 bits of payload.
|
|
||||||
// The NaN returned by math.NaN has a bit pattern equal to NaNWith(1).
|
|
||||||
func NaNWith(payload uint64) float64 {
|
|
||||||
return math.Float64frombits(nanBits | (payload &^ nanMask))
|
|
||||||
}
|
|
||||||
|
|
||||||
// NaNPayload returns the lowest 51 bits payload of an IEEE 754 "quiet
|
|
||||||
// not-a-number". For values of f other than quiet-NaN, NaNPayload
|
|
||||||
// returns zero and false.
|
|
||||||
func NaNPayload(f float64) (payload uint64, ok bool) {
|
|
||||||
b := math.Float64bits(f)
|
|
||||||
if b&nanBits != nanBits {
|
|
||||||
return 0, false
|
|
||||||
}
|
|
||||||
return b &^ nanMask, true
|
|
||||||
}
|
|
||||||
|
|
||||||
// NearestIdx returns the index of the element in s
|
|
||||||
// whose value is nearest to v. If several such
|
|
||||||
// elements exist, the lowest index is returned.
|
|
||||||
// NearestIdx panics if len(s) == 0.
|
|
||||||
func NearestIdx(s []float64, v float64) int {
|
|
||||||
if len(s) == 0 {
|
|
||||||
panic("floats: zero length slice")
|
|
||||||
}
|
|
||||||
switch {
|
|
||||||
case math.IsNaN(v):
|
|
||||||
return 0
|
|
||||||
case math.IsInf(v, 1):
|
|
||||||
return MaxIdx(s)
|
|
||||||
case math.IsInf(v, -1):
|
|
||||||
return MinIdx(s)
|
|
||||||
}
|
|
||||||
var ind int
|
|
||||||
dist := math.NaN()
|
|
||||||
for i, val := range s {
|
|
||||||
newDist := math.Abs(v - val)
|
|
||||||
// A NaN distance will not be closer.
|
|
||||||
if math.IsNaN(newDist) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if newDist < dist || math.IsNaN(dist) {
|
|
||||||
dist = newDist
|
|
||||||
ind = i
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ind
|
|
||||||
}
|
|
||||||
|
|
||||||
// NearestIdxForSpan return the index of a hypothetical vector created
|
|
||||||
// by Span with length n and bounds l and u whose value is closest
|
|
||||||
// to v. That is, NearestIdxForSpan(n, l, u, v) is equivalent to
|
|
||||||
// Nearest(Span(make([]float64, n),l,u),v) without an allocation.
|
|
||||||
// NearestIdxForSpan panics if n is less than two.
|
|
||||||
func NearestIdxForSpan(n int, l, u float64, v float64) int {
|
|
||||||
if n <= 1 {
|
|
||||||
panic("floats: span must have length >1")
|
|
||||||
}
|
|
||||||
if math.IsNaN(v) {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// Special cases for Inf and NaN.
|
|
||||||
switch {
|
|
||||||
case math.IsNaN(l) && !math.IsNaN(u):
|
|
||||||
return n - 1
|
|
||||||
case math.IsNaN(u):
|
|
||||||
return 0
|
|
||||||
case math.IsInf(l, 0) && math.IsInf(u, 0):
|
|
||||||
if l == u {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
if n%2 == 1 {
|
|
||||||
if !math.IsInf(v, 0) {
|
|
||||||
return n / 2
|
|
||||||
}
|
|
||||||
if math.Copysign(1, v) == math.Copysign(1, l) {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
return n/2 + 1
|
|
||||||
}
|
|
||||||
if math.Copysign(1, v) == math.Copysign(1, l) {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
return n / 2
|
|
||||||
case math.IsInf(l, 0):
|
|
||||||
if v == l {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
return n - 1
|
|
||||||
case math.IsInf(u, 0):
|
|
||||||
if v == u {
|
|
||||||
return n - 1
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
case math.IsInf(v, -1):
|
|
||||||
if l <= u {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
return n - 1
|
|
||||||
case math.IsInf(v, 1):
|
|
||||||
if u <= l {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
return n - 1
|
|
||||||
}
|
|
||||||
|
|
||||||
// Special cases for v outside (l, u) and (u, l).
|
|
||||||
switch {
|
|
||||||
case l < u:
|
|
||||||
if v <= l {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
if v >= u {
|
|
||||||
return n - 1
|
|
||||||
}
|
|
||||||
case l > u:
|
|
||||||
if v >= l {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
if v <= u {
|
|
||||||
return n - 1
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// Can't guarantee anything about exactly halfway between
|
|
||||||
// because of floating point weirdness.
|
|
||||||
return int((float64(n)-1)/(u-l)*(v-l) + 0.5)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Norm returns the L norm of the slice S, defined as
|
|
||||||
// (sum_{i=1}^N s[i]^L)^{1/L}
|
|
||||||
// Special cases:
|
|
||||||
// L = math.Inf(1) gives the maximum absolute value.
|
|
||||||
// Does not correctly compute the zero norm (use Count).
|
|
||||||
func Norm(s []float64, L float64) float64 {
|
|
||||||
// Should this complain if L is not positive?
|
|
||||||
// Should this be done in log space for better numerical stability?
|
|
||||||
// would be more cost
|
|
||||||
// maybe only if L is high?
|
|
||||||
if len(s) == 0 {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
if L == 2 {
|
|
||||||
twoNorm := math.Abs(s[0])
|
|
||||||
for i := 1; i < len(s); i++ {
|
|
||||||
twoNorm = math.Hypot(twoNorm, s[i])
|
|
||||||
}
|
|
||||||
return twoNorm
|
|
||||||
}
|
|
||||||
var norm float64
|
|
||||||
if L == 1 {
|
|
||||||
for _, val := range s {
|
|
||||||
norm += math.Abs(val)
|
|
||||||
}
|
|
||||||
return norm
|
|
||||||
}
|
|
||||||
if math.IsInf(L, 1) {
|
|
||||||
for _, val := range s {
|
|
||||||
norm = math.Max(norm, math.Abs(val))
|
|
||||||
}
|
|
||||||
return norm
|
|
||||||
}
|
|
||||||
for _, val := range s {
|
|
||||||
norm += math.Pow(math.Abs(val), L)
|
|
||||||
}
|
|
||||||
return math.Pow(norm, 1/L)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ParseWithNA converts the string s to a float64 in v.
|
|
||||||
// If s equals missing, w is returned as 0, otherwise 1.
|
|
||||||
func ParseWithNA(s, missing string) (v, w float64, err error) {
|
|
||||||
if s == missing {
|
|
||||||
return 0, 0, nil
|
|
||||||
}
|
|
||||||
v, err = strconv.ParseFloat(s, 64)
|
|
||||||
if err == nil {
|
|
||||||
w = 1
|
|
||||||
}
|
|
||||||
return v, w, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prod returns the product of the elements of the slice.
|
|
||||||
// Returns 1 if len(s) = 0.
|
|
||||||
func Prod(s []float64) float64 {
|
|
||||||
prod := 1.0
|
|
||||||
for _, val := range s {
|
|
||||||
prod *= val
|
|
||||||
}
|
|
||||||
return prod
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reverse reverses the order of elements in the slice.
|
|
||||||
func Reverse(s []float64) {
|
|
||||||
for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 {
|
|
||||||
s[i], s[j] = s[j], s[i]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Round returns the half away from zero rounded value of x with prec precision.
|
|
||||||
//
|
|
||||||
// Special cases are:
|
|
||||||
// Round(±0) = +0
|
|
||||||
// Round(±Inf) = ±Inf
|
|
||||||
// Round(NaN) = NaN
|
|
||||||
func Round(x float64, prec int) float64 {
|
|
||||||
if x == 0 {
|
|
||||||
// Make sure zero is returned
|
|
||||||
// without the negative bit set.
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
// Fast path for positive precision on integers.
|
|
||||||
if prec >= 0 && x == math.Trunc(x) {
|
|
||||||
return x
|
|
||||||
}
|
|
||||||
pow := math.Pow10(prec)
|
|
||||||
intermed := x * pow
|
|
||||||
if math.IsInf(intermed, 0) {
|
|
||||||
return x
|
|
||||||
}
|
|
||||||
if x < 0 {
|
|
||||||
x = math.Ceil(intermed - 0.5)
|
|
||||||
} else {
|
|
||||||
x = math.Floor(intermed + 0.5)
|
|
||||||
}
|
|
||||||
|
|
||||||
if x == 0 {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
return x / pow
|
|
||||||
}
|
|
||||||
|
|
||||||
// RoundEven returns the half even rounded value of x with prec precision.
|
|
||||||
//
|
|
||||||
// Special cases are:
|
|
||||||
// RoundEven(±0) = +0
|
|
||||||
// RoundEven(±Inf) = ±Inf
|
|
||||||
// RoundEven(NaN) = NaN
|
|
||||||
func RoundEven(x float64, prec int) float64 {
|
|
||||||
if x == 0 {
|
|
||||||
// Make sure zero is returned
|
|
||||||
// without the negative bit set.
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
// Fast path for positive precision on integers.
|
|
||||||
if prec >= 0 && x == math.Trunc(x) {
|
|
||||||
return x
|
|
||||||
}
|
|
||||||
pow := math.Pow10(prec)
|
|
||||||
intermed := x * pow
|
|
||||||
if math.IsInf(intermed, 0) {
|
|
||||||
return x
|
|
||||||
}
|
|
||||||
if isHalfway(intermed) {
|
|
||||||
correction, _ := math.Modf(math.Mod(intermed, 2))
|
|
||||||
intermed += correction
|
|
||||||
if intermed > 0 {
|
|
||||||
x = math.Floor(intermed)
|
|
||||||
} else {
|
|
||||||
x = math.Ceil(intermed)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if x < 0 {
|
|
||||||
x = math.Ceil(intermed - 0.5)
|
|
||||||
} else {
|
|
||||||
x = math.Floor(intermed + 0.5)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if x == 0 {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
return x / pow
|
|
||||||
}
|
|
||||||
|
|
||||||
func isHalfway(x float64) bool {
|
|
||||||
_, frac := math.Modf(x)
|
|
||||||
frac = math.Abs(frac)
|
|
||||||
return frac == 0.5 || (math.Nextafter(frac, math.Inf(-1)) < 0.5 && math.Nextafter(frac, math.Inf(1)) > 0.5)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Same returns true if the input slices have the same length and the all elements
|
|
||||||
// have the same value with NaN treated as the same.
|
|
||||||
func Same(s, t []float64) bool {
|
|
||||||
if len(s) != len(t) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
for i, v := range s {
|
|
||||||
w := t[i]
|
|
||||||
if v != w && !(math.IsNaN(v) && math.IsNaN(w)) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// Scale multiplies every element in dst by the scalar c.
|
|
||||||
func Scale(c float64, dst []float64) {
|
|
||||||
if len(dst) > 0 {
|
|
||||||
f64.ScalUnitary(c, dst)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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.
|
|
||||||
//
|
|
||||||
// Panics if len(dst) < 2.
|
|
||||||
//
|
|
||||||
// Span also returns the mutated slice dst, so that it can be used in range expressions,
|
|
||||||
// like:
|
|
||||||
//
|
|
||||||
// for i, x := range Span(dst, l, u) { ... }
|
|
||||||
func Span(dst []float64, l, u float64) []float64 {
|
|
||||||
n := len(dst)
|
|
||||||
if n < 2 {
|
|
||||||
panic("floats: destination must have length >1")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Special cases for Inf and NaN.
|
|
||||||
switch {
|
|
||||||
case math.IsNaN(l):
|
|
||||||
for i := range dst[:len(dst)-1] {
|
|
||||||
dst[i] = math.NaN()
|
|
||||||
}
|
|
||||||
dst[len(dst)-1] = u
|
|
||||||
return dst
|
|
||||||
case math.IsNaN(u):
|
|
||||||
for i := range dst[1:] {
|
|
||||||
dst[i+1] = math.NaN()
|
|
||||||
}
|
|
||||||
dst[0] = l
|
|
||||||
return dst
|
|
||||||
case math.IsInf(l, 0) && math.IsInf(u, 0):
|
|
||||||
for i := range dst[:len(dst)/2] {
|
|
||||||
dst[i] = l
|
|
||||||
dst[len(dst)-i-1] = u
|
|
||||||
}
|
|
||||||
if len(dst)%2 == 1 {
|
|
||||||
if l != u {
|
|
||||||
dst[len(dst)/2] = 0
|
|
||||||
} else {
|
|
||||||
dst[len(dst)/2] = l
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
case math.IsInf(l, 0):
|
|
||||||
for i := range dst[:len(dst)-1] {
|
|
||||||
dst[i] = l
|
|
||||||
}
|
|
||||||
dst[len(dst)-1] = u
|
|
||||||
return dst
|
|
||||||
case math.IsInf(u, 0):
|
|
||||||
for i := range dst[1:] {
|
|
||||||
dst[i+1] = u
|
|
||||||
}
|
|
||||||
dst[0] = l
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
step := (u - l) / float64(n-1)
|
|
||||||
for i := range dst {
|
|
||||||
dst[i] = l + step*float64(i)
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sub subtracts, element-wise, the elements of s from dst. Panics if
|
|
||||||
// the lengths of dst and s do not match.
|
|
||||||
func Sub(dst, s []float64) {
|
|
||||||
if len(dst) != len(s) {
|
|
||||||
panic("floats: length of the slices do not match")
|
|
||||||
}
|
|
||||||
f64.AxpyUnitaryTo(dst, -1, s, dst)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SubTo subtracts, element-wise, the elements of t from s and
|
|
||||||
// stores the result in dst. Panics if the lengths of s, t and dst do not match.
|
|
||||||
func SubTo(dst, s, t []float64) []float64 {
|
|
||||||
if len(s) != len(t) {
|
|
||||||
panic("floats: length of subtractor and subtractee do not match")
|
|
||||||
}
|
|
||||||
if len(dst) != len(s) {
|
|
||||||
panic("floats: length of destination does not match length of subtractor")
|
|
||||||
}
|
|
||||||
f64.AxpyUnitaryTo(dst, -1, t, s)
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sum returns the sum of the elements of the slice.
|
|
||||||
func Sum(s []float64) float64 {
|
|
||||||
return f64.Sum(s)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Within returns the first index i where s[i] <= v < s[i+1]. Within panics if:
|
|
||||||
// - len(s) < 2
|
|
||||||
// - s is not sorted
|
|
||||||
func Within(s []float64, v float64) int {
|
|
||||||
if len(s) < 2 {
|
|
||||||
panic("floats: slice length less than 2")
|
|
||||||
}
|
|
||||||
if !sort.Float64sAreSorted(s) {
|
|
||||||
panic("floats: input slice not sorted")
|
|
||||||
}
|
|
||||||
if v < s[0] || v >= s[len(s)-1] || math.IsNaN(v) {
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
for i, f := range s[1:] {
|
|
||||||
if v < f {
|
|
||||||
return i
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
1
vendor/gonum.org/v1/gonum/graph/.gitignore
generated
vendored
1
vendor/gonum.org/v1/gonum/graph/.gitignore
generated
vendored
@@ -1 +0,0 @@
|
|||||||
test.out
|
|
||||||
3
vendor/gonum.org/v1/gonum/graph/README.md
generated
vendored
3
vendor/gonum.org/v1/gonum/graph/README.md
generated
vendored
@@ -1,3 +0,0 @@
|
|||||||
# Gonum graph [](https://godoc.org/gonum.org/v1/gonum/graph)
|
|
||||||
|
|
||||||
This is a generalized graph package for the Go language.
|
|
||||||
9
vendor/gonum.org/v1/gonum/graph/doc.go
generated
vendored
9
vendor/gonum.org/v1/gonum/graph/doc.go
generated
vendored
@@ -1,9 +0,0 @@
|
|||||||
// Copyright ©2014 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 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"
|
|
||||||
6
vendor/gonum.org/v1/gonum/graph/encoding/doc.go
generated
vendored
6
vendor/gonum.org/v1/gonum/graph/encoding/doc.go
generated
vendored
@@ -1,6 +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 encoding provides a common graph encoding API.
|
|
||||||
package encoding // import "gonum.org/v1/gonum/graph/encoding"
|
|
||||||
527
vendor/gonum.org/v1/gonum/graph/encoding/dot/decode.go
generated
vendored
527
vendor/gonum.org/v1/gonum/graph/encoding/dot/decode.go
generated
vendored
@@ -1,527 +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 dot
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"gonum.org/v1/gonum/graph"
|
|
||||||
"gonum.org/v1/gonum/graph/encoding"
|
|
||||||
"gonum.org/v1/gonum/graph/formats/dot"
|
|
||||||
"gonum.org/v1/gonum/graph/formats/dot/ast"
|
|
||||||
"gonum.org/v1/gonum/graph/internal/set"
|
|
||||||
)
|
|
||||||
|
|
||||||
// AttributeSetters is implemented by graph values that can set global
|
|
||||||
// DOT attributes.
|
|
||||||
type AttributeSetters interface {
|
|
||||||
// DOTAttributeSetters returns the global attribute setters.
|
|
||||||
DOTAttributeSetters() (graph, node, edge encoding.AttributeSetter)
|
|
||||||
}
|
|
||||||
|
|
||||||
// DOTIDSetter is implemented by types that can set a DOT ID.
|
|
||||||
type DOTIDSetter interface {
|
|
||||||
SetDOTID(id string)
|
|
||||||
}
|
|
||||||
|
|
||||||
// PortSetter is implemented by graph.Edge and graph.Line that can set
|
|
||||||
// the DOT port and compass directions of an edge.
|
|
||||||
type PortSetter interface {
|
|
||||||
// SetFromPort sets the From port and
|
|
||||||
// compass direction of the receiver.
|
|
||||||
SetFromPort(port, compass string) error
|
|
||||||
|
|
||||||
// SetToPort sets the To port and compass
|
|
||||||
// direction of the receiver.
|
|
||||||
SetToPort(port, compass string) error
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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
|
|
||||||
}
|
|
||||||
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 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
|
|
||||||
// the destination graph. Edge direction is maintained if present.
|
|
||||||
func copyGraph(dst encoding.Builder, src *ast.Graph) (err error) {
|
|
||||||
defer func() {
|
|
||||||
switch e := recover().(type) {
|
|
||||||
case nil:
|
|
||||||
case error:
|
|
||||||
err = e
|
|
||||||
default:
|
|
||||||
panic(e)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
gen := &simpleGraph{
|
|
||||||
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()
|
|
||||||
}
|
|
||||||
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()
|
|
||||||
}
|
|
||||||
for _, stmt := range src.Stmts {
|
|
||||||
gen.addStmt(dst, stmt)
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// A generator keeps track of the information required for generating a gonum
|
|
||||||
// graph from a dot AST graph.
|
|
||||||
type generator struct {
|
|
||||||
// Directed graph.
|
|
||||||
directed bool
|
|
||||||
// Map from dot AST node ID to gonum node.
|
|
||||||
ids map[string]graph.Node
|
|
||||||
// Nodes processed within the context of a subgraph, that is to be used as a
|
|
||||||
// vertex of an edge.
|
|
||||||
subNodes []graph.Node
|
|
||||||
// Stack of start indices into the subgraph node slice. The top element
|
|
||||||
// corresponds to the start index of the active (or inner-most) subgraph.
|
|
||||||
subStart []int
|
|
||||||
// graphAttr, nodeAttr and edgeAttr are global graph attributes.
|
|
||||||
graphAttr, nodeAttr, edgeAttr encoding.AttributeSetter
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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 graph.NodeAdder, id string) graph.Node {
|
|
||||||
if n, ok := gen.ids[id]; ok {
|
|
||||||
return n
|
|
||||||
}
|
|
||||||
n := dst.NewNode()
|
|
||||||
if n, ok := n.(DOTIDSetter); ok {
|
|
||||||
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.
|
|
||||||
if gen.isInSubgraph() {
|
|
||||||
// Append node processed within the context of a subgraph, that is to be
|
|
||||||
// used as a vertex of an edge
|
|
||||||
gen.appendSubgraphNode(n)
|
|
||||||
}
|
|
||||||
return n
|
|
||||||
}
|
|
||||||
|
|
||||||
type simpleGraph struct{ generator }
|
|
||||||
|
|
||||||
// addStmt adds the given statement to the graph.
|
|
||||||
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)
|
|
||||||
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))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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 basicEdge) {
|
|
||||||
if ps, isPortSetter := edge.(PortSetter); isPortSetter {
|
|
||||||
if n, vertexIsNode := from.(*ast.Node); vertexIsNode {
|
|
||||||
if n.Port != nil {
|
|
||||||
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()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if n, vertexIsNode := to.Vertex.(*ast.Node); vertexIsNode {
|
|
||||||
if n.Port != nil {
|
|
||||||
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()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// addEdgeStmt adds the given edge statement to the graph.
|
|
||||||
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 {
|
|
||||||
for _, t := range ts {
|
|
||||||
edge := dst.NewEdge(f, t)
|
|
||||||
dst.SetEdge(edge)
|
|
||||||
applyPortsToEdge(stmt.From, stmt.To, edge)
|
|
||||||
addEdgeAttrs(edge, stmt.Attrs)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// addVertex adds the given vertex to the graph, and returns its set of nodes.
|
|
||||||
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)
|
|
||||||
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))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// addEdge adds the given edge to the graph, and returns its set of nodes.
|
|
||||||
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))
|
|
||||||
}
|
|
||||||
fs := gen.addVertex(dst, to.Vertex)
|
|
||||||
if to.To != nil {
|
|
||||||
ts := gen.addEdge(dst, to.To, attrs)
|
|
||||||
for _, f := range fs {
|
|
||||||
for _, t := range ts {
|
|
||||||
edge := dst.NewEdge(f, t)
|
|
||||||
dst.SetEdge(edge)
|
|
||||||
applyPortsToEdge(to.Vertex, to.To, edge)
|
|
||||||
addEdgeAttrs(edge, attrs)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return fs
|
|
||||||
}
|
|
||||||
|
|
||||||
// pushSubgraph pushes the node start index of the active subgraph onto the
|
|
||||||
// stack.
|
|
||||||
func (gen *generator) pushSubgraph() {
|
|
||||||
gen.subStart = append(gen.subStart, len(gen.subNodes))
|
|
||||||
}
|
|
||||||
|
|
||||||
// popSubgraph pops the node start index of the active subgraph from the stack,
|
|
||||||
// and returns the nodes processed since.
|
|
||||||
func (gen *generator) popSubgraph() []graph.Node {
|
|
||||||
// Get nodes processed since the subgraph became active.
|
|
||||||
start := gen.subStart[len(gen.subStart)-1]
|
|
||||||
// TODO: Figure out a better way to store subgraph nodes, so that duplicates
|
|
||||||
// may not occur.
|
|
||||||
nodes := unique(gen.subNodes[start:])
|
|
||||||
// Remove subgraph from stack.
|
|
||||||
gen.subStart = gen.subStart[:len(gen.subStart)-1]
|
|
||||||
if len(gen.subStart) == 0 {
|
|
||||||
// Remove subgraph nodes when the bottom-most subgraph has been processed.
|
|
||||||
gen.subNodes = gen.subNodes[:0]
|
|
||||||
}
|
|
||||||
return nodes
|
|
||||||
}
|
|
||||||
|
|
||||||
// unique returns the set of unique nodes contained within ns.
|
|
||||||
func unique(ns []graph.Node) []graph.Node {
|
|
||||||
var nodes []graph.Node
|
|
||||||
seen := make(set.Int64s)
|
|
||||||
for _, n := range ns {
|
|
||||||
id := n.ID()
|
|
||||||
if seen.Has(id) {
|
|
||||||
// skip duplicate node
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
seen.Add(id)
|
|
||||||
nodes = append(nodes, n)
|
|
||||||
}
|
|
||||||
return nodes
|
|
||||||
}
|
|
||||||
|
|
||||||
// isInSubgraph reports whether the active context is within a subgraph, that is
|
|
||||||
// to be used as a vertex of an edge.
|
|
||||||
func (gen *generator) isInSubgraph() bool {
|
|
||||||
return len(gen.subStart) > 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// appendSubgraphNode appends the given node to the slice of nodes processed
|
|
||||||
// within the context of a subgraph.
|
|
||||||
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 basicEdge, attrs []*ast.Attr) {
|
|
||||||
e, ok := edge.(encoding.AttributeSetter)
|
|
||||||
if !ok {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for _, attr := range attrs {
|
|
||||||
a := encoding.Attribute{
|
|
||||||
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): %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
|
|
||||||
}
|
|
||||||
21
vendor/gonum.org/v1/gonum/graph/encoding/dot/doc.go
generated
vendored
21
vendor/gonum.org/v1/gonum/graph/encoding/dot/doc.go
generated
vendored
@@ -1,21 +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 dot implements GraphViz DOT marshaling and unmarshaling of graphs.
|
|
||||||
//
|
|
||||||
// See the GraphViz DOT Guide and the DOT grammar for more information
|
|
||||||
// on using specific aspects of the DOT language:
|
|
||||||
//
|
|
||||||
// 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"
|
|
||||||
654
vendor/gonum.org/v1/gonum/graph/encoding/dot/encode.go
generated
vendored
654
vendor/gonum.org/v1/gonum/graph/encoding/dot/encode.go
generated
vendored
@@ -1,654 +0,0 @@
|
|||||||
// 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 dot
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"regexp"
|
|
||||||
"sort"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"gonum.org/v1/gonum/graph"
|
|
||||||
"gonum.org/v1/gonum/graph/encoding"
|
|
||||||
"gonum.org/v1/gonum/graph/internal/ordered"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Node is a DOT graph node.
|
|
||||||
type Node interface {
|
|
||||||
// DOTID returns a DOT node ID.
|
|
||||||
//
|
|
||||||
// An ID is one of the following:
|
|
||||||
//
|
|
||||||
// - a string of alphabetic ([a-zA-Z\x80-\xff]) characters, underscores ('_').
|
|
||||||
// digits ([0-9]), not beginning with a digit.
|
|
||||||
// - a numeral [-]?(.[0-9]+ | [0-9]+(.[0-9]*)?).
|
|
||||||
// - a double-quoted string ("...") possibly containing escaped quotes (\").
|
|
||||||
// - an HTML string (<...>).
|
|
||||||
DOTID() string
|
|
||||||
}
|
|
||||||
|
|
||||||
// Attributers are graph.Graph values that specify top-level DOT
|
|
||||||
// attributes.
|
|
||||||
type Attributers interface {
|
|
||||||
DOTAttributers() (graph, node, edge encoding.Attributer)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Porter defines the behavior of graph.Edge values that can specify
|
|
||||||
// connection ports for their end points. The returned port 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() (port, compass string)
|
|
||||||
|
|
||||||
// ToPort returns the port and compass for
|
|
||||||
// the To node of a graph.Edge.
|
|
||||||
ToPort() (port, compass string)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Structurer represents a graph.Graph that can define subgraphs.
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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.
|
|
||||||
//
|
|
||||||
// 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)
|
|
||||||
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
|
|
||||||
}
|
|
||||||
return p.buf.Bytes(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type printer struct {
|
|
||||||
buf bytes.Buffer
|
|
||||||
|
|
||||||
prefix string
|
|
||||||
indent string
|
|
||||||
depth int
|
|
||||||
}
|
|
||||||
|
|
||||||
type edge struct {
|
|
||||||
inGraph string
|
|
||||||
from, to int64
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *simpleGraphPrinter) print(g graph.Graph, name string, needsIndent, isSubgraph bool) error {
|
|
||||||
if name == "" {
|
|
||||||
if g, ok := g.(Graph); ok {
|
|
||||||
name = g.DOTID()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_, isDirected := g.(graph.Directed)
|
|
||||||
p.printFrontMatter(name, needsIndent, isSubgraph, isDirected, true)
|
|
||||||
|
|
||||||
if a, ok := g.(Attributers); ok {
|
|
||||||
p.writeAttributeComplex(a)
|
|
||||||
}
|
|
||||||
if s, ok := g.(Structurer); 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.(Subgrapher); 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()
|
|
||||||
if isDirected {
|
|
||||||
if p.visited[edge{inGraph: name, from: nid, to: tid}] {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
p.visited[edge{inGraph: name, from: nid, to: tid}] = true
|
|
||||||
} else {
|
|
||||||
if p.visited[edge{inGraph: name, from: nid, to: tid}] {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
p.visited[edge{inGraph: name, from: nid, to: tid}] = true
|
|
||||||
p.visited[edge{inGraph: name, from: tid, to: n.ID()}] = 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.(Subgrapher); 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)
|
|
||||||
}
|
|
||||||
e := g.Edge(nid, tid)
|
|
||||||
porter, edgeIsPorter := e.(Porter)
|
|
||||||
if edgeIsPorter {
|
|
||||||
if e.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.(Subgrapher); 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 e.From().ID() == nid {
|
|
||||||
p.writePorts(porter.ToPort())
|
|
||||||
} else {
|
|
||||||
p.writePorts(porter.FromPort())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if a, ok := g.Edge(nid, tid).(encoding.Attributer); ok {
|
|
||||||
p.writeAttributeList(a)
|
|
||||||
}
|
|
||||||
|
|
||||||
p.buf.WriteByte(';')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
p.closeBlock("}")
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *printer) printFrontMatter(name string, needsIndent, isSubgraph, isDirected, isStrict bool) {
|
|
||||||
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(" {")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *printer) writeNode(n graph.Node) {
|
|
||||||
p.buf.WriteString(quoteID(nodeID(n)))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *printer) writePorts(port, cp string) {
|
|
||||||
if port != "" {
|
|
||||||
p.buf.WriteByte(':')
|
|
||||||
p.buf.WriteString(quoteID(port))
|
|
||||||
}
|
|
||||||
if cp != "" {
|
|
||||||
p.buf.WriteByte(':')
|
|
||||||
p.buf.WriteString(cp)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func nodeID(n graph.Node) string {
|
|
||||||
switch n := n.(type) {
|
|
||||||
case Node:
|
|
||||||
return n.DOTID()
|
|
||||||
default:
|
|
||||||
return fmt.Sprint(n.ID())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func graphID(g interface{}, n graph.Node) string {
|
|
||||||
switch g := g.(type) {
|
|
||||||
case Node:
|
|
||||||
return g.DOTID()
|
|
||||||
default:
|
|
||||||
return nodeID(n)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *printer) writeAttributeList(a encoding.Attributer) {
|
|
||||||
attributes := a.Attributes()
|
|
||||||
switch len(attributes) {
|
|
||||||
case 0:
|
|
||||||
case 1:
|
|
||||||
p.buf.WriteString(" [")
|
|
||||||
p.buf.WriteString(quoteID(attributes[0].Key))
|
|
||||||
p.buf.WriteByte('=')
|
|
||||||
p.buf.WriteString(quoteID(attributes[0].Value))
|
|
||||||
p.buf.WriteString("]")
|
|
||||||
default:
|
|
||||||
p.openBlock(" [")
|
|
||||||
for _, att := range attributes {
|
|
||||||
p.newline()
|
|
||||||
p.buf.WriteString(quoteID(att.Key))
|
|
||||||
p.buf.WriteByte('=')
|
|
||||||
p.buf.WriteString(quoteID(att.Value))
|
|
||||||
}
|
|
||||||
p.closeBlock("]")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var attType = []string{"graph", "node", "edge"}
|
|
||||||
|
|
||||||
func (p *printer) writeAttributeComplex(ca Attributers) {
|
|
||||||
g, n, e := ca.DOTAttributers()
|
|
||||||
haveWrittenBlock := false
|
|
||||||
for i, a := range []encoding.Attributer{g, n, e} {
|
|
||||||
attributes := a.Attributes()
|
|
||||||
if len(attributes) == 0 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if haveWrittenBlock {
|
|
||||||
p.buf.WriteByte(';')
|
|
||||||
}
|
|
||||||
p.newline()
|
|
||||||
p.buf.WriteString(attType[i])
|
|
||||||
p.openBlock(" [")
|
|
||||||
for _, att := range attributes {
|
|
||||||
p.newline()
|
|
||||||
p.buf.WriteString(quoteID(att.Key))
|
|
||||||
p.buf.WriteByte('=')
|
|
||||||
p.buf.WriteString(quoteID(att.Value))
|
|
||||||
}
|
|
||||||
p.closeBlock("]")
|
|
||||||
haveWrittenBlock = true
|
|
||||||
}
|
|
||||||
if haveWrittenBlock {
|
|
||||||
p.buf.WriteString(";\n")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *printer) newline() {
|
|
||||||
p.buf.WriteByte('\n')
|
|
||||||
p.buf.WriteString(p.prefix)
|
|
||||||
for i := 0; i < p.depth; i++ {
|
|
||||||
p.buf.WriteString(p.indent)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *printer) openBlock(b string) {
|
|
||||||
p.buf.WriteString(b)
|
|
||||||
p.depth++
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *printer) closeBlock(b string) {
|
|
||||||
p.depth--
|
|
||||||
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, ">")
|
|
||||||
}
|
|
||||||
36
vendor/gonum.org/v1/gonum/graph/encoding/encoding.go
generated
vendored
36
vendor/gonum.org/v1/gonum/graph/encoding/encoding.go
generated
vendored
@@ -1,36 +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 encoding
|
|
||||||
|
|
||||||
import "gonum.org/v1/gonum/graph"
|
|
||||||
|
|
||||||
// Builder is a graph that can have user-defined nodes and edges added.
|
|
||||||
type Builder interface {
|
|
||||||
graph.Graph
|
|
||||||
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 {
|
|
||||||
SetAttribute(Attribute) error
|
|
||||||
}
|
|
||||||
|
|
||||||
// Attributer defines graph.Node or graph.Edge values that can
|
|
||||||
// specify graph attributes.
|
|
||||||
type Attributer interface {
|
|
||||||
Attributes() []Attribute
|
|
||||||
}
|
|
||||||
|
|
||||||
// Attribute is an encoded key value attribute pair use in graph encoding.
|
|
||||||
type Attribute struct {
|
|
||||||
Key, Value string
|
|
||||||
}
|
|
||||||
9
vendor/gonum.org/v1/gonum/graph/formats/dot/README.md
generated
vendored
9
vendor/gonum.org/v1/gonum/graph/formats/dot/README.md
generated
vendored
@@ -1,9 +0,0 @@
|
|||||||
# formats/dot
|
|
||||||
|
|
||||||
## License
|
|
||||||
|
|
||||||
The source code and any original content of the formats/dot directory is released under [Public Domain Dedication](https://creativecommons.org/publicdomain/zero/1.0/).
|
|
||||||
|
|
||||||
The source code is also licensed under the gonum license, and users are free to choose the license which suits their needs.
|
|
||||||
|
|
||||||
Please see gonum.org/v1/gonum for general license information, contributors, authors, etc on the Gonum suite of packages.
|
|
||||||
409
vendor/gonum.org/v1/gonum/graph/formats/dot/ast/ast.go
generated
vendored
409
vendor/gonum.org/v1/gonum/graph/formats/dot/ast/ast.go
generated
vendored
@@ -1,409 +0,0 @@
|
|||||||
// This file is dual licensed under CC0 and The gonum license.
|
|
||||||
//
|
|
||||||
// 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.
|
|
||||||
//
|
|
||||||
// Copyright ©2017 Robin Eklind.
|
|
||||||
// This file is made available under a Creative Commons CC0 1.0
|
|
||||||
// Universal Public Domain Dedication.
|
|
||||||
|
|
||||||
package ast
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
)
|
|
||||||
|
|
||||||
// === [ File ] ================================================================
|
|
||||||
|
|
||||||
// A File represents a DOT file.
|
|
||||||
//
|
|
||||||
// Examples.
|
|
||||||
//
|
|
||||||
// digraph G {
|
|
||||||
// A -> B
|
|
||||||
// }
|
|
||||||
// graph H {
|
|
||||||
// C - D
|
|
||||||
// }
|
|
||||||
type File struct {
|
|
||||||
// Graphs.
|
|
||||||
Graphs []*Graph
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns the string representation of the file.
|
|
||||||
func (f *File) String() string {
|
|
||||||
buf := new(bytes.Buffer)
|
|
||||||
for i, graph := range f.Graphs {
|
|
||||||
if i != 0 {
|
|
||||||
buf.WriteString("\n")
|
|
||||||
}
|
|
||||||
buf.WriteString(graph.String())
|
|
||||||
}
|
|
||||||
return buf.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
// === [ Graphs ] ==============================================================
|
|
||||||
|
|
||||||
// A Graph represents a directed or an undirected graph.
|
|
||||||
//
|
|
||||||
// Examples.
|
|
||||||
//
|
|
||||||
// digraph G {
|
|
||||||
// A -> {B C}
|
|
||||||
// B -> C
|
|
||||||
// }
|
|
||||||
type Graph struct {
|
|
||||||
// Strict graph; multi-edges forbidden.
|
|
||||||
Strict bool
|
|
||||||
// Directed graph.
|
|
||||||
Directed bool
|
|
||||||
// Graph ID; or empty if anonymous.
|
|
||||||
ID string
|
|
||||||
// Graph statements.
|
|
||||||
Stmts []Stmt
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns the string representation of the graph.
|
|
||||||
func (g *Graph) String() string {
|
|
||||||
buf := new(bytes.Buffer)
|
|
||||||
if g.Strict {
|
|
||||||
buf.WriteString("strict ")
|
|
||||||
}
|
|
||||||
if g.Directed {
|
|
||||||
buf.WriteString("digraph ")
|
|
||||||
} else {
|
|
||||||
buf.WriteString("graph ")
|
|
||||||
}
|
|
||||||
if len(g.ID) > 0 {
|
|
||||||
fmt.Fprintf(buf, "%s ", g.ID)
|
|
||||||
}
|
|
||||||
buf.WriteString("{\n")
|
|
||||||
for _, stmt := range g.Stmts {
|
|
||||||
fmt.Fprintf(buf, "\t%s\n", stmt)
|
|
||||||
}
|
|
||||||
buf.WriteString("}")
|
|
||||||
return buf.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
// === [ Statements ] ==========================================================
|
|
||||||
|
|
||||||
// A Stmt represents a statement, and has one of the following underlying types.
|
|
||||||
//
|
|
||||||
// *NodeStmt
|
|
||||||
// *EdgeStmt
|
|
||||||
// *AttrStmt
|
|
||||||
// *Attr
|
|
||||||
// *Subgraph
|
|
||||||
type Stmt interface {
|
|
||||||
fmt.Stringer
|
|
||||||
// isStmt ensures that only statements can be assigned to the Stmt interface.
|
|
||||||
isStmt()
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- [ Node statement ] ------------------------------------------------------
|
|
||||||
|
|
||||||
// A NodeStmt represents a node statement.
|
|
||||||
//
|
|
||||||
// Examples.
|
|
||||||
//
|
|
||||||
// A [color=blue]
|
|
||||||
type NodeStmt struct {
|
|
||||||
// Node.
|
|
||||||
Node *Node
|
|
||||||
// Node attributes.
|
|
||||||
Attrs []*Attr
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns the string representation of the node statement.
|
|
||||||
func (e *NodeStmt) String() string {
|
|
||||||
buf := new(bytes.Buffer)
|
|
||||||
buf.WriteString(e.Node.String())
|
|
||||||
if len(e.Attrs) > 0 {
|
|
||||||
buf.WriteString(" [")
|
|
||||||
for i, attr := range e.Attrs {
|
|
||||||
if i != 0 {
|
|
||||||
buf.WriteString(" ")
|
|
||||||
}
|
|
||||||
buf.WriteString(attr.String())
|
|
||||||
}
|
|
||||||
buf.WriteString("]")
|
|
||||||
}
|
|
||||||
return buf.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- [ Edge statement ] ------------------------------------------------------
|
|
||||||
|
|
||||||
// An EdgeStmt represents an edge statement.
|
|
||||||
//
|
|
||||||
// Examples.
|
|
||||||
//
|
|
||||||
// A -> B
|
|
||||||
// A -> {B C}
|
|
||||||
// A -> B -> C
|
|
||||||
type EdgeStmt struct {
|
|
||||||
// Source vertex.
|
|
||||||
From Vertex
|
|
||||||
// Outgoing edge.
|
|
||||||
To *Edge
|
|
||||||
// Edge attributes.
|
|
||||||
Attrs []*Attr
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns the string representation of the edge statement.
|
|
||||||
func (e *EdgeStmt) String() string {
|
|
||||||
buf := new(bytes.Buffer)
|
|
||||||
fmt.Fprintf(buf, "%s %s", e.From, e.To)
|
|
||||||
if len(e.Attrs) > 0 {
|
|
||||||
buf.WriteString(" [")
|
|
||||||
for i, attr := range e.Attrs {
|
|
||||||
if i != 0 {
|
|
||||||
buf.WriteString(" ")
|
|
||||||
}
|
|
||||||
buf.WriteString(attr.String())
|
|
||||||
}
|
|
||||||
buf.WriteString("]")
|
|
||||||
}
|
|
||||||
return buf.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
// An Edge represents an edge between two vertices.
|
|
||||||
type Edge struct {
|
|
||||||
// Directed edge.
|
|
||||||
Directed bool
|
|
||||||
// Destination vertex.
|
|
||||||
Vertex Vertex
|
|
||||||
// Outgoing edge; or nil if none.
|
|
||||||
To *Edge
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns the string representation of the edge.
|
|
||||||
func (e *Edge) String() string {
|
|
||||||
op := "--"
|
|
||||||
if e.Directed {
|
|
||||||
op = "->"
|
|
||||||
}
|
|
||||||
if e.To != nil {
|
|
||||||
return fmt.Sprintf("%s %s %s", op, e.Vertex, e.To)
|
|
||||||
}
|
|
||||||
return fmt.Sprintf("%s %s", op, e.Vertex)
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- [ Attribute statement ] -------------------------------------------------
|
|
||||||
|
|
||||||
// An AttrStmt represents an attribute statement.
|
|
||||||
//
|
|
||||||
// Examples.
|
|
||||||
//
|
|
||||||
// graph [rankdir=LR]
|
|
||||||
// node [color=blue fillcolor=red]
|
|
||||||
// edge [minlen=1]
|
|
||||||
type AttrStmt struct {
|
|
||||||
// Graph component kind to which the attributes are assigned.
|
|
||||||
Kind Kind
|
|
||||||
// Attributes.
|
|
||||||
Attrs []*Attr
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns the string representation of the attribute statement.
|
|
||||||
func (a *AttrStmt) String() string {
|
|
||||||
buf := new(bytes.Buffer)
|
|
||||||
fmt.Fprintf(buf, "%s [", a.Kind)
|
|
||||||
for i, attr := range a.Attrs {
|
|
||||||
if i != 0 {
|
|
||||||
buf.WriteString(" ")
|
|
||||||
}
|
|
||||||
buf.WriteString(attr.String())
|
|
||||||
}
|
|
||||||
buf.WriteString("]")
|
|
||||||
return buf.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Kind specifies the set of graph components to which attribute statements may
|
|
||||||
// be assigned.
|
|
||||||
type Kind uint
|
|
||||||
|
|
||||||
// Graph component kinds.
|
|
||||||
const (
|
|
||||||
GraphKind Kind = iota // graph
|
|
||||||
NodeKind // node
|
|
||||||
EdgeKind // edge
|
|
||||||
)
|
|
||||||
|
|
||||||
// String returns the string representation of the graph component kind.
|
|
||||||
func (k Kind) String() string {
|
|
||||||
switch k {
|
|
||||||
case GraphKind:
|
|
||||||
return "graph"
|
|
||||||
case NodeKind:
|
|
||||||
return "node"
|
|
||||||
case EdgeKind:
|
|
||||||
return "edge"
|
|
||||||
}
|
|
||||||
panic(fmt.Sprintf("invalid graph component kind (%d)", k))
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- [ Attribute ] -----------------------------------------------------------
|
|
||||||
|
|
||||||
// An Attr represents an attribute.
|
|
||||||
//
|
|
||||||
// Examples.
|
|
||||||
//
|
|
||||||
// rank=same
|
|
||||||
type Attr struct {
|
|
||||||
// Attribute key.
|
|
||||||
Key string
|
|
||||||
// Attribute value.
|
|
||||||
Val string
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns the string representation of the attribute.
|
|
||||||
func (a *Attr) String() string {
|
|
||||||
return fmt.Sprintf("%s=%s", a.Key, a.Val)
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- [ Subgraph ] ------------------------------------------------------------
|
|
||||||
|
|
||||||
// A Subgraph represents a subgraph vertex.
|
|
||||||
//
|
|
||||||
// Examples.
|
|
||||||
//
|
|
||||||
// subgraph S {A B C}
|
|
||||||
type Subgraph struct {
|
|
||||||
// Subgraph ID; or empty if none.
|
|
||||||
ID string
|
|
||||||
// Subgraph statements.
|
|
||||||
Stmts []Stmt
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns the string representation of the subgraph.
|
|
||||||
func (s *Subgraph) String() string {
|
|
||||||
buf := new(bytes.Buffer)
|
|
||||||
if len(s.ID) > 0 {
|
|
||||||
fmt.Fprintf(buf, "subgraph %s ", s.ID)
|
|
||||||
}
|
|
||||||
buf.WriteString("{")
|
|
||||||
for i, stmt := range s.Stmts {
|
|
||||||
if i != 0 {
|
|
||||||
buf.WriteString(" ")
|
|
||||||
}
|
|
||||||
buf.WriteString(stmt.String())
|
|
||||||
}
|
|
||||||
buf.WriteString("}")
|
|
||||||
return buf.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
// isStmt ensures that only statements can be assigned to the Stmt interface.
|
|
||||||
func (*NodeStmt) isStmt() {}
|
|
||||||
func (*EdgeStmt) isStmt() {}
|
|
||||||
func (*AttrStmt) isStmt() {}
|
|
||||||
func (*Attr) isStmt() {}
|
|
||||||
func (*Subgraph) isStmt() {}
|
|
||||||
|
|
||||||
// === [ Vertices ] ============================================================
|
|
||||||
|
|
||||||
// A Vertex represents a vertex, and has one of the following underlying types.
|
|
||||||
//
|
|
||||||
// *Node
|
|
||||||
// *Subgraph
|
|
||||||
type Vertex interface {
|
|
||||||
fmt.Stringer
|
|
||||||
// isVertex ensures that only vertices can be assigned to the Vertex
|
|
||||||
// interface.
|
|
||||||
isVertex()
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- [ Node identifier ] -----------------------------------------------------
|
|
||||||
|
|
||||||
// A Node represents a node vertex.
|
|
||||||
//
|
|
||||||
// Examples.
|
|
||||||
//
|
|
||||||
// A
|
|
||||||
// A:nw
|
|
||||||
type Node struct {
|
|
||||||
// Node ID.
|
|
||||||
ID string
|
|
||||||
// Node port; or nil if none.
|
|
||||||
Port *Port
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns the string representation of the node.
|
|
||||||
func (n *Node) String() string {
|
|
||||||
if n.Port != nil {
|
|
||||||
return fmt.Sprintf("%s%s", n.ID, n.Port)
|
|
||||||
}
|
|
||||||
return n.ID
|
|
||||||
}
|
|
||||||
|
|
||||||
// A Port specifies where on a node an edge should be aimed.
|
|
||||||
type Port struct {
|
|
||||||
// Port ID; or empty if none.
|
|
||||||
ID string
|
|
||||||
// Compass point.
|
|
||||||
CompassPoint CompassPoint
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns the string representation of the port.
|
|
||||||
func (p *Port) String() string {
|
|
||||||
buf := new(bytes.Buffer)
|
|
||||||
if len(p.ID) > 0 {
|
|
||||||
fmt.Fprintf(buf, ":%s", p.ID)
|
|
||||||
}
|
|
||||||
if p.CompassPoint != CompassPointNone {
|
|
||||||
fmt.Fprintf(buf, ":%s", p.CompassPoint)
|
|
||||||
}
|
|
||||||
return buf.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
// CompassPoint specifies the set of compass points.
|
|
||||||
type CompassPoint uint
|
|
||||||
|
|
||||||
// Compass points.
|
|
||||||
const (
|
|
||||||
CompassPointNone CompassPoint = iota //
|
|
||||||
CompassPointNorth // n
|
|
||||||
CompassPointNorthEast // ne
|
|
||||||
CompassPointEast // e
|
|
||||||
CompassPointSouthEast // se
|
|
||||||
CompassPointSouth // s
|
|
||||||
CompassPointSouthWest // sw
|
|
||||||
CompassPointWest // w
|
|
||||||
CompassPointNorthWest // nw
|
|
||||||
CompassPointCenter // c
|
|
||||||
CompassPointDefault // _
|
|
||||||
)
|
|
||||||
|
|
||||||
// String returns the string representation of the compass point.
|
|
||||||
func (c CompassPoint) String() string {
|
|
||||||
switch c {
|
|
||||||
case CompassPointNone:
|
|
||||||
return ""
|
|
||||||
case CompassPointNorth:
|
|
||||||
return "n"
|
|
||||||
case CompassPointNorthEast:
|
|
||||||
return "ne"
|
|
||||||
case CompassPointEast:
|
|
||||||
return "e"
|
|
||||||
case CompassPointSouthEast:
|
|
||||||
return "se"
|
|
||||||
case CompassPointSouth:
|
|
||||||
return "s"
|
|
||||||
case CompassPointSouthWest:
|
|
||||||
return "sw"
|
|
||||||
case CompassPointWest:
|
|
||||||
return "w"
|
|
||||||
case CompassPointNorthWest:
|
|
||||||
return "nw"
|
|
||||||
case CompassPointCenter:
|
|
||||||
return "c"
|
|
||||||
case CompassPointDefault:
|
|
||||||
return "_"
|
|
||||||
}
|
|
||||||
panic(fmt.Sprintf("invalid compass point (%d)", uint(c)))
|
|
||||||
}
|
|
||||||
|
|
||||||
// isVertex ensures that only vertices can be assigned to the Vertex interface.
|
|
||||||
func (*Node) isVertex() {}
|
|
||||||
func (*Subgraph) isVertex() {}
|
|
||||||
7
vendor/gonum.org/v1/gonum/graph/formats/dot/ast/doc.go
generated
vendored
7
vendor/gonum.org/v1/gonum/graph/formats/dot/ast/doc.go
generated
vendored
@@ -1,7 +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 ast declares the types used to represent abstract syntax trees of
|
|
||||||
// Graphviz DOT graphs.
|
|
||||||
package ast // import "gonum.org/v1/gonum/graph/formats/dot/ast"
|
|
||||||
6
vendor/gonum.org/v1/gonum/graph/formats/dot/doc.go
generated
vendored
6
vendor/gonum.org/v1/gonum/graph/formats/dot/doc.go
generated
vendored
@@ -1,6 +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 dot implements a parser for Graphviz DOT files.
|
|
||||||
package dot // import "gonum.org/v1/gonum/graph/formats/dot"
|
|
||||||
64
vendor/gonum.org/v1/gonum/graph/formats/dot/dot.go
generated
vendored
64
vendor/gonum.org/v1/gonum/graph/formats/dot/dot.go
generated
vendored
@@ -1,64 +0,0 @@
|
|||||||
// This file is dual licensed under CC0 and The gonum license.
|
|
||||||
//
|
|
||||||
// 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.
|
|
||||||
//
|
|
||||||
// Copyright ©2017 Robin Eklind.
|
|
||||||
// This file is made available under a Creative Commons CC0 1.0
|
|
||||||
// Universal Public Domain Dedication.
|
|
||||||
|
|
||||||
//go:generate ./makeinternal.bash
|
|
||||||
|
|
||||||
package dot
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
|
||||||
|
|
||||||
"gonum.org/v1/gonum/graph/formats/dot/ast"
|
|
||||||
"gonum.org/v1/gonum/graph/formats/dot/internal/lexer"
|
|
||||||
"gonum.org/v1/gonum/graph/formats/dot/internal/parser"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ParseFile parses the given Graphviz DOT file into an AST.
|
|
||||||
func ParseFile(path string) (*ast.File, error) {
|
|
||||||
buf, err := ioutil.ReadFile(path)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return ParseBytes(buf)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse parses the given Graphviz DOT file into an AST, reading from r.
|
|
||||||
func Parse(r io.Reader) (*ast.File, error) {
|
|
||||||
buf, err := ioutil.ReadAll(r)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return ParseBytes(buf)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ParseBytes parses the given Graphviz DOT file into an AST, reading from b.
|
|
||||||
func ParseBytes(b []byte) (*ast.File, error) {
|
|
||||||
l := lexer.NewLexer(b)
|
|
||||||
p := parser.NewParser()
|
|
||||||
file, err := p.Parse(l)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
f, ok := file.(*ast.File)
|
|
||||||
if !ok {
|
|
||||||
return nil, fmt.Errorf("invalid file type; expected *ast.File, got %T", file)
|
|
||||||
}
|
|
||||||
if err := check(f); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return f, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ParseString parses the given Graphviz DOT file into an AST, reading from s.
|
|
||||||
func ParseString(s string) (*ast.File, error) {
|
|
||||||
return ParseBytes([]byte(s))
|
|
||||||
}
|
|
||||||
326
vendor/gonum.org/v1/gonum/graph/formats/dot/internal/astx/astx.go
generated
vendored
326
vendor/gonum.org/v1/gonum/graph/formats/dot/internal/astx/astx.go
generated
vendored
@@ -1,326 +0,0 @@
|
|||||||
// This file is dual licensed under CC0 and The gonum license.
|
|
||||||
//
|
|
||||||
// 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.
|
|
||||||
//
|
|
||||||
// Copyright ©2017 Robin Eklind.
|
|
||||||
// This file is made available under a Creative Commons CC0 1.0
|
|
||||||
// Universal Public Domain Dedication.
|
|
||||||
|
|
||||||
package astx
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"gonum.org/v1/gonum/graph/formats/dot/ast"
|
|
||||||
"gonum.org/v1/gonum/graph/formats/dot/internal/token"
|
|
||||||
)
|
|
||||||
|
|
||||||
// === [ File ] ================================================================
|
|
||||||
|
|
||||||
// NewFile returns a new file based on the given graph.
|
|
||||||
func NewFile(graph interface{}) (*ast.File, error) {
|
|
||||||
g, ok := graph.(*ast.Graph)
|
|
||||||
if !ok {
|
|
||||||
return nil, fmt.Errorf("invalid graph type; expected *ast.Graph, got %T", graph)
|
|
||||||
}
|
|
||||||
return &ast.File{Graphs: []*ast.Graph{g}}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// AppendGraph appends graph to the given file.
|
|
||||||
func AppendGraph(file, graph interface{}) (*ast.File, error) {
|
|
||||||
f, ok := file.(*ast.File)
|
|
||||||
if !ok {
|
|
||||||
return nil, fmt.Errorf("invalid file type; expected *ast.File, got %T", file)
|
|
||||||
}
|
|
||||||
g, ok := graph.(*ast.Graph)
|
|
||||||
if !ok {
|
|
||||||
return nil, fmt.Errorf("invalid graph type; expected *ast.Graph, got %T", graph)
|
|
||||||
}
|
|
||||||
f.Graphs = append(f.Graphs, g)
|
|
||||||
return f, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// === [ Graphs ] ==============================================================
|
|
||||||
|
|
||||||
// NewGraph returns a new graph based on the given graph strictness, direction,
|
|
||||||
// optional ID and optional statements.
|
|
||||||
func NewGraph(strict, directed, optID, optStmts interface{}) (*ast.Graph, error) {
|
|
||||||
s, ok := strict.(bool)
|
|
||||||
if !ok {
|
|
||||||
return nil, fmt.Errorf("invalid strictness type; expected bool, got %T", strict)
|
|
||||||
}
|
|
||||||
d, ok := directed.(bool)
|
|
||||||
if !ok {
|
|
||||||
return nil, fmt.Errorf("invalid direction type; expected bool, got %T", directed)
|
|
||||||
}
|
|
||||||
id, ok := optID.(string)
|
|
||||||
if optID != nil && !ok {
|
|
||||||
return nil, fmt.Errorf("invalid ID type; expected string or nil, got %T", optID)
|
|
||||||
}
|
|
||||||
stmts, ok := optStmts.([]ast.Stmt)
|
|
||||||
if optStmts != nil && !ok {
|
|
||||||
return nil, fmt.Errorf("invalid statements type; expected []ast.Stmt or nil, got %T", optStmts)
|
|
||||||
}
|
|
||||||
return &ast.Graph{Strict: s, Directed: d, ID: id, Stmts: stmts}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// === [ Statements ] ==========================================================
|
|
||||||
|
|
||||||
// NewStmtList returns a new statement list based on the given statement.
|
|
||||||
func NewStmtList(stmt interface{}) ([]ast.Stmt, error) {
|
|
||||||
s, ok := stmt.(ast.Stmt)
|
|
||||||
if !ok {
|
|
||||||
return nil, fmt.Errorf("invalid statement type; expected ast.Stmt, got %T", stmt)
|
|
||||||
}
|
|
||||||
return []ast.Stmt{s}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// AppendStmt appends stmt to the given statement list.
|
|
||||||
func AppendStmt(list, stmt interface{}) ([]ast.Stmt, error) {
|
|
||||||
l, ok := list.([]ast.Stmt)
|
|
||||||
if !ok {
|
|
||||||
return nil, fmt.Errorf("invalid statement list type; expected []ast.Stmt, got %T", list)
|
|
||||||
}
|
|
||||||
s, ok := stmt.(ast.Stmt)
|
|
||||||
if !ok {
|
|
||||||
return nil, fmt.Errorf("invalid statement type; expected ast.Stmt, got %T", stmt)
|
|
||||||
}
|
|
||||||
return append(l, s), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- [ Node statement ] ------------------------------------------------------
|
|
||||||
|
|
||||||
// NewNodeStmt returns a new node statement based on the given node and optional
|
|
||||||
// attributes.
|
|
||||||
func NewNodeStmt(node, optAttrs interface{}) (*ast.NodeStmt, error) {
|
|
||||||
n, ok := node.(*ast.Node)
|
|
||||||
if !ok {
|
|
||||||
return nil, fmt.Errorf("invalid node type; expected *ast.Node, got %T", node)
|
|
||||||
}
|
|
||||||
attrs, ok := optAttrs.([]*ast.Attr)
|
|
||||||
if optAttrs != nil && !ok {
|
|
||||||
return nil, fmt.Errorf("invalid attributes type; expected []*ast.Attr or nil, got %T", optAttrs)
|
|
||||||
}
|
|
||||||
return &ast.NodeStmt{Node: n, Attrs: attrs}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- [ Edge statement ] ------------------------------------------------------
|
|
||||||
|
|
||||||
// NewEdgeStmt returns a new edge statement based on the given source vertex,
|
|
||||||
// outgoing edge and optional attributes.
|
|
||||||
func NewEdgeStmt(from, to, optAttrs interface{}) (*ast.EdgeStmt, error) {
|
|
||||||
f, ok := from.(ast.Vertex)
|
|
||||||
if !ok {
|
|
||||||
return nil, fmt.Errorf("invalid source vertex type; expected ast.Vertex, got %T", from)
|
|
||||||
}
|
|
||||||
t, ok := to.(*ast.Edge)
|
|
||||||
if !ok {
|
|
||||||
return nil, fmt.Errorf("invalid outgoing edge type; expected *ast.Edge, got %T", to)
|
|
||||||
}
|
|
||||||
attrs, ok := optAttrs.([]*ast.Attr)
|
|
||||||
if optAttrs != nil && !ok {
|
|
||||||
return nil, fmt.Errorf("invalid attributes type; expected []*ast.Attr or nil, got %T", optAttrs)
|
|
||||||
}
|
|
||||||
return &ast.EdgeStmt{From: f, To: t, Attrs: attrs}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewEdge returns a new edge based on the given edge direction, destination
|
|
||||||
// vertex and optional outgoing edge.
|
|
||||||
func NewEdge(directed, vertex, optTo interface{}) (*ast.Edge, error) {
|
|
||||||
d, ok := directed.(bool)
|
|
||||||
if !ok {
|
|
||||||
return nil, fmt.Errorf("invalid direction type; expected bool, got %T", directed)
|
|
||||||
}
|
|
||||||
v, ok := vertex.(ast.Vertex)
|
|
||||||
if !ok {
|
|
||||||
return nil, fmt.Errorf("invalid destination vertex type; expected ast.Vertex, got %T", vertex)
|
|
||||||
}
|
|
||||||
to, ok := optTo.(*ast.Edge)
|
|
||||||
if optTo != nil && !ok {
|
|
||||||
return nil, fmt.Errorf("invalid outgoing edge type; expected *ast.Edge or nil, got %T", optTo)
|
|
||||||
}
|
|
||||||
return &ast.Edge{Directed: d, Vertex: v, To: to}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- [ Attribute statement ] -------------------------------------------------
|
|
||||||
|
|
||||||
// NewAttrStmt returns a new attribute statement based on the given graph
|
|
||||||
// component kind and attributes.
|
|
||||||
func NewAttrStmt(kind, optAttrs interface{}) (*ast.AttrStmt, error) {
|
|
||||||
k, ok := kind.(ast.Kind)
|
|
||||||
if !ok {
|
|
||||||
return nil, fmt.Errorf("invalid graph component kind type; expected ast.Kind, got %T", kind)
|
|
||||||
}
|
|
||||||
attrs, ok := optAttrs.([]*ast.Attr)
|
|
||||||
if optAttrs != nil && !ok {
|
|
||||||
return nil, fmt.Errorf("invalid attributes type; expected []*ast.Attr or nil, got %T", optAttrs)
|
|
||||||
}
|
|
||||||
return &ast.AttrStmt{Kind: k, Attrs: attrs}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewAttrList returns a new attribute list based on the given attribute.
|
|
||||||
func NewAttrList(attr interface{}) ([]*ast.Attr, error) {
|
|
||||||
a, ok := attr.(*ast.Attr)
|
|
||||||
if !ok {
|
|
||||||
return nil, fmt.Errorf("invalid attribute type; expected *ast.Attr, got %T", attr)
|
|
||||||
}
|
|
||||||
return []*ast.Attr{a}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// AppendAttr appends attr to the given attribute list.
|
|
||||||
func AppendAttr(list, attr interface{}) ([]*ast.Attr, error) {
|
|
||||||
l, ok := list.([]*ast.Attr)
|
|
||||||
if !ok {
|
|
||||||
return nil, fmt.Errorf("invalid attribute list type; expected []*ast.Attr, got %T", list)
|
|
||||||
}
|
|
||||||
a, ok := attr.(*ast.Attr)
|
|
||||||
if !ok {
|
|
||||||
return nil, fmt.Errorf("invalid attribute type; expected *ast.Attr, got %T", attr)
|
|
||||||
}
|
|
||||||
return append(l, a), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// AppendAttrList appends the optional attrs to the given optional attribute
|
|
||||||
// list.
|
|
||||||
func AppendAttrList(optList, optAttrs interface{}) ([]*ast.Attr, error) {
|
|
||||||
list, ok := optList.([]*ast.Attr)
|
|
||||||
if optList != nil && !ok {
|
|
||||||
return nil, fmt.Errorf("invalid attribute list type; expected []*ast.Attr or nil, got %T", optList)
|
|
||||||
}
|
|
||||||
attrs, ok := optAttrs.([]*ast.Attr)
|
|
||||||
if optAttrs != nil && !ok {
|
|
||||||
return nil, fmt.Errorf("invalid attributes type; expected []*ast.Attr or nil, got %T", optAttrs)
|
|
||||||
}
|
|
||||||
return append(list, attrs...), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- [ Attribute ] -----------------------------------------------------------
|
|
||||||
|
|
||||||
// NewAttr returns a new attribute based on the given key-value pair.
|
|
||||||
func NewAttr(key, val interface{}) (*ast.Attr, error) {
|
|
||||||
k, ok := key.(string)
|
|
||||||
if !ok {
|
|
||||||
return nil, fmt.Errorf("invalid key type; expected string, got %T", key)
|
|
||||||
}
|
|
||||||
v, ok := val.(string)
|
|
||||||
if !ok {
|
|
||||||
return nil, fmt.Errorf("invalid value type; expected string, got %T", val)
|
|
||||||
}
|
|
||||||
return &ast.Attr{Key: k, Val: v}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- [ Subgraph ] ------------------------------------------------------------
|
|
||||||
|
|
||||||
// NewSubgraph returns a new subgraph based on the given optional subgraph ID
|
|
||||||
// and optional statements.
|
|
||||||
func NewSubgraph(optID, optStmts interface{}) (*ast.Subgraph, error) {
|
|
||||||
id, ok := optID.(string)
|
|
||||||
if optID != nil && !ok {
|
|
||||||
return nil, fmt.Errorf("invalid ID type; expected string or nil, got %T", optID)
|
|
||||||
}
|
|
||||||
stmts, ok := optStmts.([]ast.Stmt)
|
|
||||||
if optStmts != nil && !ok {
|
|
||||||
return nil, fmt.Errorf("invalid statements type; expected []ast.Stmt or nil, got %T", optStmts)
|
|
||||||
}
|
|
||||||
return &ast.Subgraph{ID: id, Stmts: stmts}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// === [ Vertices ] ============================================================
|
|
||||||
|
|
||||||
// --- [ Node identifier ] -----------------------------------------------------
|
|
||||||
|
|
||||||
// NewNode returns a new node based on the given node id and optional port.
|
|
||||||
func NewNode(id, optPort interface{}) (*ast.Node, error) {
|
|
||||||
i, ok := id.(string)
|
|
||||||
if !ok {
|
|
||||||
return nil, fmt.Errorf("invalid ID type; expected string, got %T", id)
|
|
||||||
}
|
|
||||||
port, ok := optPort.(*ast.Port)
|
|
||||||
if optPort != nil && !ok {
|
|
||||||
return nil, fmt.Errorf("invalid port type; expected *ast.Port or nil, got %T", optPort)
|
|
||||||
}
|
|
||||||
return &ast.Node{ID: i, Port: port}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewPort returns a new port based on the given id and optional compass point.
|
|
||||||
func NewPort(id, optCompassPoint interface{}) (*ast.Port, error) {
|
|
||||||
// Note, if optCompassPoint is nil, id may be either an identifier or a
|
|
||||||
// compass point.
|
|
||||||
//
|
|
||||||
// The following strings are valid compass points:
|
|
||||||
//
|
|
||||||
// "n", "ne", "e", "se", "s", "sw", "w", "nw", "c" and "_"
|
|
||||||
i, ok := id.(string)
|
|
||||||
if !ok {
|
|
||||||
return nil, fmt.Errorf("invalid ID type; expected string, got %T", id)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Early return if optional compass point is absent and ID is a valid compass
|
|
||||||
// point.
|
|
||||||
if optCompassPoint == nil {
|
|
||||||
if compassPoint, ok := getCompassPoint(i); ok {
|
|
||||||
return &ast.Port{CompassPoint: compassPoint}, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
c, ok := optCompassPoint.(string)
|
|
||||||
if optCompassPoint != nil && !ok {
|
|
||||||
return nil, fmt.Errorf("invalid compass point type; expected string or nil, got %T", optCompassPoint)
|
|
||||||
}
|
|
||||||
compassPoint, _ := getCompassPoint(c)
|
|
||||||
return &ast.Port{ID: i, CompassPoint: compassPoint}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// getCompassPoint returns the corresponding compass point to the given string,
|
|
||||||
// and a boolean value indicating if such a compass point exists.
|
|
||||||
func getCompassPoint(s string) (ast.CompassPoint, bool) {
|
|
||||||
switch s {
|
|
||||||
case "_":
|
|
||||||
return ast.CompassPointDefault, true
|
|
||||||
case "n":
|
|
||||||
return ast.CompassPointNorth, true
|
|
||||||
case "ne":
|
|
||||||
return ast.CompassPointNorthEast, true
|
|
||||||
case "e":
|
|
||||||
return ast.CompassPointEast, true
|
|
||||||
case "se":
|
|
||||||
return ast.CompassPointSouthEast, true
|
|
||||||
case "s":
|
|
||||||
return ast.CompassPointSouth, true
|
|
||||||
case "sw":
|
|
||||||
return ast.CompassPointSouthWest, true
|
|
||||||
case "w":
|
|
||||||
return ast.CompassPointWest, true
|
|
||||||
case "nw":
|
|
||||||
return ast.CompassPointNorthWest, true
|
|
||||||
case "c":
|
|
||||||
return ast.CompassPointCenter, true
|
|
||||||
}
|
|
||||||
return ast.CompassPointNone, false
|
|
||||||
}
|
|
||||||
|
|
||||||
// === [ Identifiers ] =========================================================
|
|
||||||
|
|
||||||
// NewID returns a new identifier based on the given ID token.
|
|
||||||
func NewID(id interface{}) (string, error) {
|
|
||||||
i, ok := id.(*token.Token)
|
|
||||||
if !ok {
|
|
||||||
return "", fmt.Errorf("invalid identifier type; expected *token.Token, got %T", id)
|
|
||||||
}
|
|
||||||
s := string(i.Lit)
|
|
||||||
|
|
||||||
// As another aid for readability, dot allows double-quoted strings to span
|
|
||||||
// multiple physical lines using the standard C convention of a backslash
|
|
||||||
// immediately preceding a newline character.
|
|
||||||
if strings.HasPrefix(s, `"`) && strings.HasSuffix(s, `"`) {
|
|
||||||
// Strip "\\\n" sequences.
|
|
||||||
s = strings.Replace(s, "\\\n", "", -1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Add support for concatenated using a '+' operator.
|
|
||||||
|
|
||||||
return s, nil
|
|
||||||
}
|
|
||||||
7
vendor/gonum.org/v1/gonum/graph/formats/dot/internal/astx/doc.go
generated
vendored
7
vendor/gonum.org/v1/gonum/graph/formats/dot/internal/astx/doc.go
generated
vendored
@@ -1,7 +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 astx implements utility functions for generating abstract syntax
|
|
||||||
// trees of Graphviz DOT graphs.
|
|
||||||
package astx // import "gonum.org/v1/gonum/graph/formats/dot/internal/astx"
|
|
||||||
6
vendor/gonum.org/v1/gonum/graph/formats/dot/internal/errors/doc.go
generated
vendored
6
vendor/gonum.org/v1/gonum/graph/formats/dot/internal/errors/doc.go
generated
vendored
@@ -1,6 +0,0 @@
|
|||||||
// 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 error provides generated internal error functions for DOT parsing.
|
|
||||||
package errors // import "gonum.org/v1/gonum/graph/formats/dot/internal/errors"
|
|
||||||
66
vendor/gonum.org/v1/gonum/graph/formats/dot/internal/errors/errors.go
generated
vendored
66
vendor/gonum.org/v1/gonum/graph/formats/dot/internal/errors/errors.go
generated
vendored
@@ -1,66 +0,0 @@
|
|||||||
// Code generated by gocc; DO NOT EDIT.
|
|
||||||
|
|
||||||
// This file is dual licensed under CC0 and The gonum license.
|
|
||||||
//
|
|
||||||
// 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.
|
|
||||||
//
|
|
||||||
// Copyright ©2017 Robin Eklind.
|
|
||||||
// This file is made available under a Creative Commons CC0 1.0
|
|
||||||
// Universal Public Domain Dedication.
|
|
||||||
|
|
||||||
package errors
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"gonum.org/v1/gonum/graph/formats/dot/internal/token"
|
|
||||||
)
|
|
||||||
|
|
||||||
type ErrorSymbol interface {
|
|
||||||
}
|
|
||||||
|
|
||||||
type Error struct {
|
|
||||||
Err error
|
|
||||||
ErrorToken *token.Token
|
|
||||||
ErrorSymbols []ErrorSymbol
|
|
||||||
ExpectedTokens []string
|
|
||||||
StackTop int
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *Error) String() string {
|
|
||||||
w := new(strings.Builder)
|
|
||||||
fmt.Fprintf(w, "Error")
|
|
||||||
if e.Err != nil {
|
|
||||||
fmt.Fprintf(w, " %s\n", e.Err)
|
|
||||||
} else {
|
|
||||||
fmt.Fprintf(w, "\n")
|
|
||||||
}
|
|
||||||
fmt.Fprintf(w, "Token: type=%d, lit=%s\n", e.ErrorToken.Type, e.ErrorToken.Lit)
|
|
||||||
fmt.Fprintf(w, "Pos: offset=%d, line=%d, column=%d\n", e.ErrorToken.Pos.Offset, e.ErrorToken.Pos.Line, e.ErrorToken.Pos.Column)
|
|
||||||
fmt.Fprintf(w, "Expected one of: ")
|
|
||||||
for _, sym := range e.ExpectedTokens {
|
|
||||||
fmt.Fprintf(w, "%s ", sym)
|
|
||||||
}
|
|
||||||
fmt.Fprintf(w, "ErrorSymbol:\n")
|
|
||||||
for _, sym := range e.ErrorSymbols {
|
|
||||||
fmt.Fprintf(w, "%v\n", sym)
|
|
||||||
}
|
|
||||||
return w.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *Error) Error() string {
|
|
||||||
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)
|
|
||||||
} else {
|
|
||||||
fmt.Fprintf(w, ", expected one of: ")
|
|
||||||
for _, expected := range e.ExpectedTokens {
|
|
||||||
fmt.Fprintf(w, "%s ", expected)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return w.String()
|
|
||||||
}
|
|
||||||
605
vendor/gonum.org/v1/gonum/graph/formats/dot/internal/lexer/acttab.go
generated
vendored
605
vendor/gonum.org/v1/gonum/graph/formats/dot/internal/lexer/acttab.go
generated
vendored
@@ -1,605 +0,0 @@
|
|||||||
// Code generated by gocc; DO NOT EDIT.
|
|
||||||
|
|
||||||
// This file is dual licensed under CC0 and The gonum license.
|
|
||||||
//
|
|
||||||
// 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.
|
|
||||||
//
|
|
||||||
// Copyright ©2017 Robin Eklind.
|
|
||||||
// This file is made available under a Creative Commons CC0 1.0
|
|
||||||
// Universal Public Domain Dedication.
|
|
||||||
|
|
||||||
package lexer
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"gonum.org/v1/gonum/graph/formats/dot/internal/token"
|
|
||||||
)
|
|
||||||
|
|
||||||
type ActionTable [NumStates]ActionRow
|
|
||||||
|
|
||||||
type ActionRow struct {
|
|
||||||
Accept token.Type
|
|
||||||
Ignore string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a ActionRow) String() string {
|
|
||||||
return fmt.Sprintf("Accept=%d, Ignore=%s", a.Accept, a.Ignore)
|
|
||||||
}
|
|
||||||
|
|
||||||
var ActTab = ActionTable{
|
|
||||||
ActionRow{ // S0
|
|
||||||
Accept: 0,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S1
|
|
||||||
Accept: -1,
|
|
||||||
Ignore: "!whitespace",
|
|
||||||
},
|
|
||||||
ActionRow{ // S2
|
|
||||||
Accept: 0,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S3
|
|
||||||
Accept: 0,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S4
|
|
||||||
Accept: 15,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S5
|
|
||||||
Accept: 0,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S6
|
|
||||||
Accept: 0,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S7
|
|
||||||
Accept: 0,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S8
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S9
|
|
||||||
Accept: 18,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S10
|
|
||||||
Accept: 8,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S11
|
|
||||||
Accept: 0,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S12
|
|
||||||
Accept: 16,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S13
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S14
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S15
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S16
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S17
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S18
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S19
|
|
||||||
Accept: 13,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S20
|
|
||||||
Accept: 14,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S21
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S22
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S23
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S24
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S25
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S26
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S27
|
|
||||||
Accept: 2,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S28
|
|
||||||
Accept: 3,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S29
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S30
|
|
||||||
Accept: 0,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S31
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S32
|
|
||||||
Accept: 0,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S33
|
|
||||||
Accept: 0,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S34
|
|
||||||
Accept: -1,
|
|
||||||
Ignore: "!comment",
|
|
||||||
},
|
|
||||||
ActionRow{ // S35
|
|
||||||
Accept: 9,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S36
|
|
||||||
Accept: 10,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S37
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S38
|
|
||||||
Accept: 0,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S39
|
|
||||||
Accept: 0,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S40
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S41
|
|
||||||
Accept: 0,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S42
|
|
||||||
Accept: 0,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S43
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S44
|
|
||||||
Accept: 0,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S45
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S46
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S47
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S48
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S49
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S50
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S51
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S52
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S53
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S54
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S55
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S56
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S57
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S58
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S59
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S60
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S61
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S62
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S63
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S64
|
|
||||||
Accept: 0,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S65
|
|
||||||
Accept: 0,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S66
|
|
||||||
Accept: 0,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S67
|
|
||||||
Accept: 0,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S68
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S69
|
|
||||||
Accept: 0,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S70
|
|
||||||
Accept: 0,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S71
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S72
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S73
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S74
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S75
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S76
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S77
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S78
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S79
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S80
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S81
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S82
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S83
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S84
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S85
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S86
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S87
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S88
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S89
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S90
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S91
|
|
||||||
Accept: -1,
|
|
||||||
Ignore: "!comment",
|
|
||||||
},
|
|
||||||
ActionRow{ // S92
|
|
||||||
Accept: 0,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S93
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S94
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S95
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S96
|
|
||||||
Accept: 12,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S97
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S98
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S99
|
|
||||||
Accept: 11,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S100
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S101
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S102
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S103
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S104
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S105
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S106
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S107
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S108
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S109
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S110
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S111
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S112
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S113
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S114
|
|
||||||
Accept: 6,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S115
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S116
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S117
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S118
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S119
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S120
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S121
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S122
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S123
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S124
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S125
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S126
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S127
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S128
|
|
||||||
Accept: 5,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S129
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S130
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S131
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S132
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S133
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S134
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S135
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S136
|
|
||||||
Accept: 7,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S137
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S138
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S139
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S140
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S141
|
|
||||||
Accept: 19,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
ActionRow{ // S142
|
|
||||||
Accept: 17,
|
|
||||||
Ignore: "",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
6
vendor/gonum.org/v1/gonum/graph/formats/dot/internal/lexer/doc.go
generated
vendored
6
vendor/gonum.org/v1/gonum/graph/formats/dot/internal/lexer/doc.go
generated
vendored
@@ -1,6 +0,0 @@
|
|||||||
// 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 lexer provides generated internal lexer functions for DOT parsing.
|
|
||||||
package lexer // import "gonum.org/v1/gonum/graph/formats/dot/internal/lexer"
|
|
||||||
310
vendor/gonum.org/v1/gonum/graph/formats/dot/internal/lexer/lexer.go
generated
vendored
310
vendor/gonum.org/v1/gonum/graph/formats/dot/internal/lexer/lexer.go
generated
vendored
@@ -1,310 +0,0 @@
|
|||||||
// Code generated by gocc; DO NOT EDIT.
|
|
||||||
|
|
||||||
// This file is dual licensed under CC0 and The gonum license.
|
|
||||||
//
|
|
||||||
// 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.
|
|
||||||
//
|
|
||||||
// Copyright ©2017 Robin Eklind.
|
|
||||||
// This file is made available under a Creative Commons CC0 1.0
|
|
||||||
// Universal Public Domain Dedication.
|
|
||||||
|
|
||||||
package lexer
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io/ioutil"
|
|
||||||
"unicode/utf8"
|
|
||||||
|
|
||||||
"gonum.org/v1/gonum/graph/formats/dot/internal/token"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
NoState = -1
|
|
||||||
NumStates = 143
|
|
||||||
NumSymbols = 184
|
|
||||||
)
|
|
||||||
|
|
||||||
type Lexer struct {
|
|
||||||
src []byte
|
|
||||||
pos int
|
|
||||||
line int
|
|
||||||
column int
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewLexer(src []byte) *Lexer {
|
|
||||||
lexer := &Lexer{
|
|
||||||
src: src,
|
|
||||||
pos: 0,
|
|
||||||
line: 1,
|
|
||||||
column: 1,
|
|
||||||
}
|
|
||||||
return lexer
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewLexerFile(fpath string) (*Lexer, error) {
|
|
||||||
src, err := ioutil.ReadFile(fpath)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return NewLexer(src), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *Lexer) Scan() (tok *token.Token) {
|
|
||||||
tok = new(token.Token)
|
|
||||||
if l.pos >= len(l.src) {
|
|
||||||
tok.Type = token.EOF
|
|
||||||
tok.Pos.Offset, tok.Pos.Line, tok.Pos.Column = l.pos, l.line, l.column
|
|
||||||
return
|
|
||||||
}
|
|
||||||
start, startLine, startColumn, end := l.pos, l.line, l.column, 0
|
|
||||||
tok.Type = token.INVALID
|
|
||||||
state, rune1, size := 0, rune(-1), 0
|
|
||||||
for state != -1 {
|
|
||||||
if l.pos >= len(l.src) {
|
|
||||||
rune1 = -1
|
|
||||||
} else {
|
|
||||||
rune1, size = utf8.DecodeRune(l.src[l.pos:])
|
|
||||||
l.pos += size
|
|
||||||
}
|
|
||||||
|
|
||||||
nextState := -1
|
|
||||||
if rune1 != -1 {
|
|
||||||
nextState = TransTab[state](rune1)
|
|
||||||
}
|
|
||||||
state = nextState
|
|
||||||
|
|
||||||
if state != -1 {
|
|
||||||
|
|
||||||
switch rune1 {
|
|
||||||
case '\n':
|
|
||||||
l.line++
|
|
||||||
l.column = 1
|
|
||||||
case '\r':
|
|
||||||
l.column = 1
|
|
||||||
case '\t':
|
|
||||||
l.column += 4
|
|
||||||
default:
|
|
||||||
l.column++
|
|
||||||
}
|
|
||||||
|
|
||||||
switch {
|
|
||||||
case ActTab[state].Accept != -1:
|
|
||||||
tok.Type = ActTab[state].Accept
|
|
||||||
end = l.pos
|
|
||||||
case ActTab[state].Ignore != "":
|
|
||||||
start, startLine, startColumn = l.pos, l.line, l.column
|
|
||||||
state = 0
|
|
||||||
if start >= len(l.src) {
|
|
||||||
tok.Type = token.EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if tok.Type == token.INVALID {
|
|
||||||
end = l.pos
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if end > start {
|
|
||||||
l.pos = end
|
|
||||||
tok.Lit = l.src[start:end]
|
|
||||||
} else {
|
|
||||||
tok.Lit = []byte{}
|
|
||||||
}
|
|
||||||
tok.Pos.Offset, tok.Pos.Line, tok.Pos.Column = start, startLine, startColumn
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *Lexer) Reset() {
|
|
||||||
l.pos = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Lexer symbols:
|
|
||||||
0: 'n'
|
|
||||||
1: 'o'
|
|
||||||
2: 'd'
|
|
||||||
3: 'e'
|
|
||||||
4: 'N'
|
|
||||||
5: 'o'
|
|
||||||
6: 'd'
|
|
||||||
7: 'e'
|
|
||||||
8: 'N'
|
|
||||||
9: 'O'
|
|
||||||
10: 'D'
|
|
||||||
11: 'E'
|
|
||||||
12: 'e'
|
|
||||||
13: 'd'
|
|
||||||
14: 'g'
|
|
||||||
15: 'e'
|
|
||||||
16: 'E'
|
|
||||||
17: 'd'
|
|
||||||
18: 'g'
|
|
||||||
19: 'e'
|
|
||||||
20: 'E'
|
|
||||||
21: 'D'
|
|
||||||
22: 'G'
|
|
||||||
23: 'E'
|
|
||||||
24: 'g'
|
|
||||||
25: 'r'
|
|
||||||
26: 'a'
|
|
||||||
27: 'p'
|
|
||||||
28: 'h'
|
|
||||||
29: 'G'
|
|
||||||
30: 'r'
|
|
||||||
31: 'a'
|
|
||||||
32: 'p'
|
|
||||||
33: 'h'
|
|
||||||
34: 'G'
|
|
||||||
35: 'R'
|
|
||||||
36: 'A'
|
|
||||||
37: 'P'
|
|
||||||
38: 'H'
|
|
||||||
39: 'd'
|
|
||||||
40: 'i'
|
|
||||||
41: 'g'
|
|
||||||
42: 'r'
|
|
||||||
43: 'a'
|
|
||||||
44: 'p'
|
|
||||||
45: 'h'
|
|
||||||
46: 'D'
|
|
||||||
47: 'i'
|
|
||||||
48: 'g'
|
|
||||||
49: 'r'
|
|
||||||
50: 'a'
|
|
||||||
51: 'p'
|
|
||||||
52: 'h'
|
|
||||||
53: 'd'
|
|
||||||
54: 'i'
|
|
||||||
55: 'G'
|
|
||||||
56: 'r'
|
|
||||||
57: 'a'
|
|
||||||
58: 'p'
|
|
||||||
59: 'h'
|
|
||||||
60: 'D'
|
|
||||||
61: 'i'
|
|
||||||
62: 'G'
|
|
||||||
63: 'r'
|
|
||||||
64: 'a'
|
|
||||||
65: 'p'
|
|
||||||
66: 'h'
|
|
||||||
67: 'D'
|
|
||||||
68: 'I'
|
|
||||||
69: 'G'
|
|
||||||
70: 'R'
|
|
||||||
71: 'A'
|
|
||||||
72: 'P'
|
|
||||||
73: 'H'
|
|
||||||
74: 's'
|
|
||||||
75: 'u'
|
|
||||||
76: 'b'
|
|
||||||
77: 'g'
|
|
||||||
78: 'r'
|
|
||||||
79: 'a'
|
|
||||||
80: 'p'
|
|
||||||
81: 'h'
|
|
||||||
82: 'S'
|
|
||||||
83: 'u'
|
|
||||||
84: 'b'
|
|
||||||
85: 'g'
|
|
||||||
86: 'r'
|
|
||||||
87: 'a'
|
|
||||||
88: 'p'
|
|
||||||
89: 'h'
|
|
||||||
90: 's'
|
|
||||||
91: 'u'
|
|
||||||
92: 'b'
|
|
||||||
93: 'G'
|
|
||||||
94: 'r'
|
|
||||||
95: 'a'
|
|
||||||
96: 'p'
|
|
||||||
97: 'h'
|
|
||||||
98: 'S'
|
|
||||||
99: 'u'
|
|
||||||
100: 'b'
|
|
||||||
101: 'G'
|
|
||||||
102: 'r'
|
|
||||||
103: 'a'
|
|
||||||
104: 'p'
|
|
||||||
105: 'h'
|
|
||||||
106: 'S'
|
|
||||||
107: 'U'
|
|
||||||
108: 'B'
|
|
||||||
109: 'G'
|
|
||||||
110: 'R'
|
|
||||||
111: 'A'
|
|
||||||
112: 'P'
|
|
||||||
113: 'H'
|
|
||||||
114: 's'
|
|
||||||
115: 't'
|
|
||||||
116: 'r'
|
|
||||||
117: 'i'
|
|
||||||
118: 'c'
|
|
||||||
119: 't'
|
|
||||||
120: 'S'
|
|
||||||
121: 't'
|
|
||||||
122: 'r'
|
|
||||||
123: 'i'
|
|
||||||
124: 'c'
|
|
||||||
125: 't'
|
|
||||||
126: 'S'
|
|
||||||
127: 'T'
|
|
||||||
128: 'R'
|
|
||||||
129: 'I'
|
|
||||||
130: 'C'
|
|
||||||
131: 'T'
|
|
||||||
132: '{'
|
|
||||||
133: '}'
|
|
||||||
134: ';'
|
|
||||||
135: '-'
|
|
||||||
136: '-'
|
|
||||||
137: '-'
|
|
||||||
138: '>'
|
|
||||||
139: '['
|
|
||||||
140: ']'
|
|
||||||
141: ','
|
|
||||||
142: '='
|
|
||||||
143: ':'
|
|
||||||
144: '_'
|
|
||||||
145: '-'
|
|
||||||
146: '.'
|
|
||||||
147: '-'
|
|
||||||
148: '.'
|
|
||||||
149: '\'
|
|
||||||
150: '"'
|
|
||||||
151: '\'
|
|
||||||
152: '"'
|
|
||||||
153: '"'
|
|
||||||
154: '='
|
|
||||||
155: '<'
|
|
||||||
156: '>'
|
|
||||||
157: '<'
|
|
||||||
158: '>'
|
|
||||||
159: '/'
|
|
||||||
160: '/'
|
|
||||||
161: '\n'
|
|
||||||
162: '#'
|
|
||||||
163: '\n'
|
|
||||||
164: '/'
|
|
||||||
165: '*'
|
|
||||||
166: '*'
|
|
||||||
167: '*'
|
|
||||||
168: '/'
|
|
||||||
169: ' '
|
|
||||||
170: '\t'
|
|
||||||
171: '\r'
|
|
||||||
172: '\n'
|
|
||||||
173: \u0001-'!'
|
|
||||||
174: '#'-'['
|
|
||||||
175: ']'-\u007f
|
|
||||||
176: 'a'-'z'
|
|
||||||
177: 'A'-'Z'
|
|
||||||
178: '0'-'9'
|
|
||||||
179: \u0080-\ufffc
|
|
||||||
180: \ufffe-\U0010ffff
|
|
||||||
181: \u0001-';'
|
|
||||||
182: '?'-\u00ff
|
|
||||||
183: .
|
|
||||||
*/
|
|
||||||
2813
vendor/gonum.org/v1/gonum/graph/formats/dot/internal/lexer/transitiontable.go
generated
vendored
2813
vendor/gonum.org/v1/gonum/graph/formats/dot/internal/lexer/transitiontable.go
generated
vendored
File diff suppressed because it is too large
Load Diff
61
vendor/gonum.org/v1/gonum/graph/formats/dot/internal/parser/action.go
generated
vendored
61
vendor/gonum.org/v1/gonum/graph/formats/dot/internal/parser/action.go
generated
vendored
@@ -1,61 +0,0 @@
|
|||||||
// Code generated by gocc; DO NOT EDIT.
|
|
||||||
|
|
||||||
// This file is dual licensed under CC0 and The gonum license.
|
|
||||||
//
|
|
||||||
// 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.
|
|
||||||
//
|
|
||||||
// Copyright ©2017 Robin Eklind.
|
|
||||||
// This file is made available under a Creative Commons CC0 1.0
|
|
||||||
// Universal Public Domain Dedication.
|
|
||||||
|
|
||||||
package parser
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
)
|
|
||||||
|
|
||||||
type action interface {
|
|
||||||
act()
|
|
||||||
String() string
|
|
||||||
}
|
|
||||||
|
|
||||||
type (
|
|
||||||
accept bool
|
|
||||||
shift int // value is next state index
|
|
||||||
reduce int // value is production index
|
|
||||||
)
|
|
||||||
|
|
||||||
func (this accept) act() {}
|
|
||||||
func (this shift) act() {}
|
|
||||||
func (this reduce) act() {}
|
|
||||||
|
|
||||||
func (this accept) Equal(that action) bool {
|
|
||||||
if _, ok := that.(accept); ok {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this reduce) Equal(that action) bool {
|
|
||||||
that1, ok := that.(reduce)
|
|
||||||
if !ok {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return this == that1
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this shift) Equal(that action) bool {
|
|
||||||
that1, ok := that.(shift)
|
|
||||||
if !ok {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return this == that1
|
|
||||||
}
|
|
||||||
|
|
||||||
func (this accept) String() string { return "accept(0)" }
|
|
||||||
func (this shift) String() string { return fmt.Sprintf("shift:%d", this) }
|
|
||||||
func (this reduce) String() string {
|
|
||||||
return fmt.Sprintf("reduce:%d(%s)", this, productionsTable[this].String)
|
|
||||||
}
|
|
||||||
2199
vendor/gonum.org/v1/gonum/graph/formats/dot/internal/parser/actiontable.go
generated
vendored
2199
vendor/gonum.org/v1/gonum/graph/formats/dot/internal/parser/actiontable.go
generated
vendored
File diff suppressed because it is too large
Load Diff
6
vendor/gonum.org/v1/gonum/graph/formats/dot/internal/parser/doc.go
generated
vendored
6
vendor/gonum.org/v1/gonum/graph/formats/dot/internal/parser/doc.go
generated
vendored
@@ -1,6 +0,0 @@
|
|||||||
// 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 parser provides generated internal parsing functions for DOT parsing.
|
|
||||||
package parser // import "gonum.org/v1/gonum/graph/formats/dot/internal/parser"
|
|
||||||
2807
vendor/gonum.org/v1/gonum/graph/formats/dot/internal/parser/gototable.go
generated
vendored
2807
vendor/gonum.org/v1/gonum/graph/formats/dot/internal/parser/gototable.go
generated
vendored
File diff suppressed because it is too large
Load Diff
226
vendor/gonum.org/v1/gonum/graph/formats/dot/internal/parser/parser.go
generated
vendored
226
vendor/gonum.org/v1/gonum/graph/formats/dot/internal/parser/parser.go
generated
vendored
@@ -1,226 +0,0 @@
|
|||||||
// Code generated by gocc; DO NOT EDIT.
|
|
||||||
|
|
||||||
// This file is dual licensed under CC0 and The gonum license.
|
|
||||||
//
|
|
||||||
// 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.
|
|
||||||
//
|
|
||||||
// Copyright ©2017 Robin Eklind.
|
|
||||||
// This file is made available under a Creative Commons CC0 1.0
|
|
||||||
// Universal Public Domain Dedication.
|
|
||||||
|
|
||||||
package parser
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
parseError "gonum.org/v1/gonum/graph/formats/dot/internal/errors"
|
|
||||||
"gonum.org/v1/gonum/graph/formats/dot/internal/token"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
numProductions = 55
|
|
||||||
numStates = 87
|
|
||||||
numSymbols = 50
|
|
||||||
)
|
|
||||||
|
|
||||||
// Stack
|
|
||||||
|
|
||||||
type stack struct {
|
|
||||||
state []int
|
|
||||||
attrib []Attrib
|
|
||||||
}
|
|
||||||
|
|
||||||
const iNITIAL_STACK_SIZE = 100
|
|
||||||
|
|
||||||
func newStack() *stack {
|
|
||||||
return &stack{
|
|
||||||
state: make([]int, 0, iNITIAL_STACK_SIZE),
|
|
||||||
attrib: make([]Attrib, 0, iNITIAL_STACK_SIZE),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *stack) reset() {
|
|
||||||
s.state = s.state[:0]
|
|
||||||
s.attrib = s.attrib[:0]
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *stack) push(state int, a Attrib) {
|
|
||||||
s.state = append(s.state, state)
|
|
||||||
s.attrib = append(s.attrib, a)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *stack) top() int {
|
|
||||||
return s.state[len(s.state)-1]
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *stack) peek(pos int) int {
|
|
||||||
return s.state[pos]
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *stack) topIndex() int {
|
|
||||||
return len(s.state) - 1
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *stack) popN(items int) []Attrib {
|
|
||||||
lo, hi := len(s.state)-items, len(s.state)
|
|
||||||
|
|
||||||
attrib := s.attrib[lo:hi]
|
|
||||||
|
|
||||||
s.state = s.state[:lo]
|
|
||||||
s.attrib = s.attrib[:lo]
|
|
||||||
|
|
||||||
return attrib
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *stack) String() string {
|
|
||||||
w := new(strings.Builder)
|
|
||||||
fmt.Fprintf(w, "stack:\n")
|
|
||||||
for i, st := range s.state {
|
|
||||||
fmt.Fprintf(w, "\t%d: %d , ", i, st)
|
|
||||||
if s.attrib[i] == nil {
|
|
||||||
fmt.Fprintf(w, "nil")
|
|
||||||
} else {
|
|
||||||
switch attr := s.attrib[i].(type) {
|
|
||||||
case *token.Token:
|
|
||||||
fmt.Fprintf(w, "%s", attr.Lit)
|
|
||||||
default:
|
|
||||||
fmt.Fprintf(w, "%v", attr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fmt.Fprintf(w, "\n")
|
|
||||||
}
|
|
||||||
return w.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parser
|
|
||||||
|
|
||||||
type Parser struct {
|
|
||||||
stack *stack
|
|
||||||
nextToken *token.Token
|
|
||||||
pos int
|
|
||||||
}
|
|
||||||
|
|
||||||
type Scanner interface {
|
|
||||||
Scan() (tok *token.Token)
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewParser() *Parser {
|
|
||||||
p := &Parser{stack: newStack()}
|
|
||||||
p.Reset()
|
|
||||||
return p
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Parser) Reset() {
|
|
||||||
p.stack.reset()
|
|
||||||
p.stack.push(0, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Parser) Error(err error, scanner Scanner) (recovered bool, errorAttrib *parseError.Error) {
|
|
||||||
errorAttrib = &parseError.Error{
|
|
||||||
Err: err,
|
|
||||||
ErrorToken: p.nextToken,
|
|
||||||
ErrorSymbols: p.popNonRecoveryStates(),
|
|
||||||
ExpectedTokens: make([]string, 0, 8),
|
|
||||||
}
|
|
||||||
for t, action := range actionTab[p.stack.top()].actions {
|
|
||||||
if action != nil {
|
|
||||||
errorAttrib.ExpectedTokens = append(errorAttrib.ExpectedTokens, token.TokMap.Id(token.Type(t)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if action := actionTab[p.stack.top()].actions[token.TokMap.Type("error")]; action != nil {
|
|
||||||
p.stack.push(int(action.(shift)), errorAttrib) // action can only be shift
|
|
||||||
} else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if action := actionTab[p.stack.top()].actions[p.nextToken.Type]; action != nil {
|
|
||||||
recovered = true
|
|
||||||
}
|
|
||||||
for !recovered && p.nextToken.Type != token.EOF {
|
|
||||||
p.nextToken = scanner.Scan()
|
|
||||||
if action := actionTab[p.stack.top()].actions[p.nextToken.Type]; action != nil {
|
|
||||||
recovered = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Parser) popNonRecoveryStates() (removedAttribs []parseError.ErrorSymbol) {
|
|
||||||
if rs, ok := p.firstRecoveryState(); ok {
|
|
||||||
errorSymbols := p.stack.popN(p.stack.topIndex() - rs)
|
|
||||||
removedAttribs = make([]parseError.ErrorSymbol, len(errorSymbols))
|
|
||||||
for i, e := range errorSymbols {
|
|
||||||
removedAttribs[i] = e
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
removedAttribs = []parseError.ErrorSymbol{}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// recoveryState points to the highest state on the stack, which can recover
|
|
||||||
func (p *Parser) firstRecoveryState() (recoveryState int, canRecover bool) {
|
|
||||||
recoveryState, canRecover = p.stack.topIndex(), actionTab[p.stack.top()].canRecover
|
|
||||||
for recoveryState > 0 && !canRecover {
|
|
||||||
recoveryState--
|
|
||||||
canRecover = actionTab[p.stack.peek(recoveryState)].canRecover
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Parser) newError(err error) error {
|
|
||||||
e := &parseError.Error{
|
|
||||||
Err: err,
|
|
||||||
StackTop: p.stack.top(),
|
|
||||||
ErrorToken: p.nextToken,
|
|
||||||
}
|
|
||||||
actRow := actionTab[p.stack.top()]
|
|
||||||
for i, t := range actRow.actions {
|
|
||||||
if t != nil {
|
|
||||||
e.ExpectedTokens = append(e.ExpectedTokens, token.TokMap.Id(token.Type(i)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return e
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Parser) Parse(scanner Scanner) (res interface{}, err error) {
|
|
||||||
p.Reset()
|
|
||||||
p.nextToken = scanner.Scan()
|
|
||||||
for acc := false; !acc; {
|
|
||||||
action := actionTab[p.stack.top()].actions[p.nextToken.Type]
|
|
||||||
if action == nil {
|
|
||||||
if recovered, errAttrib := p.Error(nil, scanner); !recovered {
|
|
||||||
p.nextToken = errAttrib.ErrorToken
|
|
||||||
return nil, p.newError(nil)
|
|
||||||
}
|
|
||||||
if action = actionTab[p.stack.top()].actions[p.nextToken.Type]; action == nil {
|
|
||||||
panic("Error recovery led to invalid action")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch act := action.(type) {
|
|
||||||
case accept:
|
|
||||||
res = p.stack.popN(1)[0]
|
|
||||||
acc = true
|
|
||||||
case shift:
|
|
||||||
p.stack.push(int(act), p.nextToken)
|
|
||||||
p.nextToken = scanner.Scan()
|
|
||||||
case reduce:
|
|
||||||
prod := productionsTable[int(act)]
|
|
||||||
attrib, err := prod.ReduceFunc(p.stack.popN(prod.NumSymbols))
|
|
||||||
if err != nil {
|
|
||||||
return nil, p.newError(err)
|
|
||||||
} else {
|
|
||||||
p.stack.push(gotoTab[p.stack.top()][prod.NTType], attrib)
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
panic("unknown action: " + action.String())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
586
vendor/gonum.org/v1/gonum/graph/formats/dot/internal/parser/productionstable.go
generated
vendored
586
vendor/gonum.org/v1/gonum/graph/formats/dot/internal/parser/productionstable.go
generated
vendored
@@ -1,586 +0,0 @@
|
|||||||
// Code generated by gocc; DO NOT EDIT.
|
|
||||||
|
|
||||||
// This file is dual licensed under CC0 and The gonum license.
|
|
||||||
//
|
|
||||||
// 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.
|
|
||||||
//
|
|
||||||
// Copyright ©2017 Robin Eklind.
|
|
||||||
// This file is made available under a Creative Commons CC0 1.0
|
|
||||||
// Universal Public Domain Dedication.
|
|
||||||
|
|
||||||
package parser
|
|
||||||
|
|
||||||
import (
|
|
||||||
"gonum.org/v1/gonum/graph/formats/dot/ast"
|
|
||||||
"gonum.org/v1/gonum/graph/formats/dot/internal/astx"
|
|
||||||
)
|
|
||||||
|
|
||||||
type (
|
|
||||||
//TODO: change type and variable names to be consistent with other tables
|
|
||||||
ProdTab [numProductions]ProdTabEntry
|
|
||||||
ProdTabEntry struct {
|
|
||||||
String string
|
|
||||||
Id string
|
|
||||||
NTType int
|
|
||||||
Index int
|
|
||||||
NumSymbols int
|
|
||||||
ReduceFunc func([]Attrib) (Attrib, error)
|
|
||||||
}
|
|
||||||
Attrib interface {
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
var productionsTable = ProdTab{
|
|
||||||
ProdTabEntry{
|
|
||||||
String: `S' : File << >>`,
|
|
||||||
Id: "S'",
|
|
||||||
NTType: 0,
|
|
||||||
Index: 0,
|
|
||||||
NumSymbols: 1,
|
|
||||||
ReduceFunc: func(X []Attrib) (Attrib, error) {
|
|
||||||
return X[0], nil
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ProdTabEntry{
|
|
||||||
String: `File : Graph << astx.NewFile(X[0]) >>`,
|
|
||||||
Id: "File",
|
|
||||||
NTType: 1,
|
|
||||||
Index: 1,
|
|
||||||
NumSymbols: 1,
|
|
||||||
ReduceFunc: func(X []Attrib) (Attrib, error) {
|
|
||||||
return astx.NewFile(X[0])
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ProdTabEntry{
|
|
||||||
String: `File : File Graph << astx.AppendGraph(X[0], X[1]) >>`,
|
|
||||||
Id: "File",
|
|
||||||
NTType: 1,
|
|
||||||
Index: 2,
|
|
||||||
NumSymbols: 2,
|
|
||||||
ReduceFunc: func(X []Attrib) (Attrib, error) {
|
|
||||||
return astx.AppendGraph(X[0], X[1])
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ProdTabEntry{
|
|
||||||
String: `Graph : OptStrict DirectedGraph OptID "{" OptStmtList "}" << astx.NewGraph(X[0], X[1], X[2], X[4]) >>`,
|
|
||||||
Id: "Graph",
|
|
||||||
NTType: 2,
|
|
||||||
Index: 3,
|
|
||||||
NumSymbols: 6,
|
|
||||||
ReduceFunc: func(X []Attrib) (Attrib, error) {
|
|
||||||
return astx.NewGraph(X[0], X[1], X[2], X[4])
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ProdTabEntry{
|
|
||||||
String: `OptStrict : empty << false, nil >>`,
|
|
||||||
Id: "OptStrict",
|
|
||||||
NTType: 3,
|
|
||||||
Index: 4,
|
|
||||||
NumSymbols: 0,
|
|
||||||
ReduceFunc: func(X []Attrib) (Attrib, error) {
|
|
||||||
return false, nil
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ProdTabEntry{
|
|
||||||
String: `OptStrict : strict << true, nil >>`,
|
|
||||||
Id: "OptStrict",
|
|
||||||
NTType: 3,
|
|
||||||
Index: 5,
|
|
||||||
NumSymbols: 1,
|
|
||||||
ReduceFunc: func(X []Attrib) (Attrib, error) {
|
|
||||||
return true, nil
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ProdTabEntry{
|
|
||||||
String: `DirectedGraph : graphx << false, nil >>`,
|
|
||||||
Id: "DirectedGraph",
|
|
||||||
NTType: 4,
|
|
||||||
Index: 6,
|
|
||||||
NumSymbols: 1,
|
|
||||||
ReduceFunc: func(X []Attrib) (Attrib, error) {
|
|
||||||
return false, nil
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ProdTabEntry{
|
|
||||||
String: `DirectedGraph : digraph << true, nil >>`,
|
|
||||||
Id: "DirectedGraph",
|
|
||||||
NTType: 4,
|
|
||||||
Index: 7,
|
|
||||||
NumSymbols: 1,
|
|
||||||
ReduceFunc: func(X []Attrib) (Attrib, error) {
|
|
||||||
return true, nil
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ProdTabEntry{
|
|
||||||
String: `StmtList : Stmt OptSemi << astx.NewStmtList(X[0]) >>`,
|
|
||||||
Id: "StmtList",
|
|
||||||
NTType: 5,
|
|
||||||
Index: 8,
|
|
||||||
NumSymbols: 2,
|
|
||||||
ReduceFunc: func(X []Attrib) (Attrib, error) {
|
|
||||||
return astx.NewStmtList(X[0])
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ProdTabEntry{
|
|
||||||
String: `StmtList : StmtList Stmt OptSemi << astx.AppendStmt(X[0], X[1]) >>`,
|
|
||||||
Id: "StmtList",
|
|
||||||
NTType: 5,
|
|
||||||
Index: 9,
|
|
||||||
NumSymbols: 3,
|
|
||||||
ReduceFunc: func(X []Attrib) (Attrib, error) {
|
|
||||||
return astx.AppendStmt(X[0], X[1])
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ProdTabEntry{
|
|
||||||
String: `OptStmtList : empty << >>`,
|
|
||||||
Id: "OptStmtList",
|
|
||||||
NTType: 6,
|
|
||||||
Index: 10,
|
|
||||||
NumSymbols: 0,
|
|
||||||
ReduceFunc: func(X []Attrib) (Attrib, error) {
|
|
||||||
return nil, nil
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ProdTabEntry{
|
|
||||||
String: `OptStmtList : StmtList << >>`,
|
|
||||||
Id: "OptStmtList",
|
|
||||||
NTType: 6,
|
|
||||||
Index: 11,
|
|
||||||
NumSymbols: 1,
|
|
||||||
ReduceFunc: func(X []Attrib) (Attrib, error) {
|
|
||||||
return X[0], nil
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ProdTabEntry{
|
|
||||||
String: `Stmt : NodeStmt << >>`,
|
|
||||||
Id: "Stmt",
|
|
||||||
NTType: 7,
|
|
||||||
Index: 12,
|
|
||||||
NumSymbols: 1,
|
|
||||||
ReduceFunc: func(X []Attrib) (Attrib, error) {
|
|
||||||
return X[0], nil
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ProdTabEntry{
|
|
||||||
String: `Stmt : EdgeStmt << >>`,
|
|
||||||
Id: "Stmt",
|
|
||||||
NTType: 7,
|
|
||||||
Index: 13,
|
|
||||||
NumSymbols: 1,
|
|
||||||
ReduceFunc: func(X []Attrib) (Attrib, error) {
|
|
||||||
return X[0], nil
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ProdTabEntry{
|
|
||||||
String: `Stmt : AttrStmt << >>`,
|
|
||||||
Id: "Stmt",
|
|
||||||
NTType: 7,
|
|
||||||
Index: 14,
|
|
||||||
NumSymbols: 1,
|
|
||||||
ReduceFunc: func(X []Attrib) (Attrib, error) {
|
|
||||||
return X[0], nil
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ProdTabEntry{
|
|
||||||
String: `Stmt : Attr << >>`,
|
|
||||||
Id: "Stmt",
|
|
||||||
NTType: 7,
|
|
||||||
Index: 15,
|
|
||||||
NumSymbols: 1,
|
|
||||||
ReduceFunc: func(X []Attrib) (Attrib, error) {
|
|
||||||
return X[0], nil
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ProdTabEntry{
|
|
||||||
String: `Stmt : Subgraph << >>`,
|
|
||||||
Id: "Stmt",
|
|
||||||
NTType: 7,
|
|
||||||
Index: 16,
|
|
||||||
NumSymbols: 1,
|
|
||||||
ReduceFunc: func(X []Attrib) (Attrib, error) {
|
|
||||||
return X[0], nil
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ProdTabEntry{
|
|
||||||
String: `OptSemi : empty << >>`,
|
|
||||||
Id: "OptSemi",
|
|
||||||
NTType: 8,
|
|
||||||
Index: 17,
|
|
||||||
NumSymbols: 0,
|
|
||||||
ReduceFunc: func(X []Attrib) (Attrib, error) {
|
|
||||||
return nil, nil
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ProdTabEntry{
|
|
||||||
String: `OptSemi : ";" << >>`,
|
|
||||||
Id: "OptSemi",
|
|
||||||
NTType: 8,
|
|
||||||
Index: 18,
|
|
||||||
NumSymbols: 1,
|
|
||||||
ReduceFunc: func(X []Attrib) (Attrib, error) {
|
|
||||||
return X[0], nil
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ProdTabEntry{
|
|
||||||
String: `NodeStmt : Node OptAttrList << astx.NewNodeStmt(X[0], X[1]) >>`,
|
|
||||||
Id: "NodeStmt",
|
|
||||||
NTType: 9,
|
|
||||||
Index: 19,
|
|
||||||
NumSymbols: 2,
|
|
||||||
ReduceFunc: func(X []Attrib) (Attrib, error) {
|
|
||||||
return astx.NewNodeStmt(X[0], X[1])
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ProdTabEntry{
|
|
||||||
String: `EdgeStmt : Vertex Edge OptAttrList << astx.NewEdgeStmt(X[0], X[1], X[2]) >>`,
|
|
||||||
Id: "EdgeStmt",
|
|
||||||
NTType: 10,
|
|
||||||
Index: 20,
|
|
||||||
NumSymbols: 3,
|
|
||||||
ReduceFunc: func(X []Attrib) (Attrib, error) {
|
|
||||||
return astx.NewEdgeStmt(X[0], X[1], X[2])
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ProdTabEntry{
|
|
||||||
String: `Edge : DirectedEdge Vertex OptEdge << astx.NewEdge(X[0], X[1], X[2]) >>`,
|
|
||||||
Id: "Edge",
|
|
||||||
NTType: 11,
|
|
||||||
Index: 21,
|
|
||||||
NumSymbols: 3,
|
|
||||||
ReduceFunc: func(X []Attrib) (Attrib, error) {
|
|
||||||
return astx.NewEdge(X[0], X[1], X[2])
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ProdTabEntry{
|
|
||||||
String: `DirectedEdge : "--" << false, nil >>`,
|
|
||||||
Id: "DirectedEdge",
|
|
||||||
NTType: 12,
|
|
||||||
Index: 22,
|
|
||||||
NumSymbols: 1,
|
|
||||||
ReduceFunc: func(X []Attrib) (Attrib, error) {
|
|
||||||
return false, nil
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ProdTabEntry{
|
|
||||||
String: `DirectedEdge : "->" << true, nil >>`,
|
|
||||||
Id: "DirectedEdge",
|
|
||||||
NTType: 12,
|
|
||||||
Index: 23,
|
|
||||||
NumSymbols: 1,
|
|
||||||
ReduceFunc: func(X []Attrib) (Attrib, error) {
|
|
||||||
return true, nil
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ProdTabEntry{
|
|
||||||
String: `OptEdge : empty << >>`,
|
|
||||||
Id: "OptEdge",
|
|
||||||
NTType: 13,
|
|
||||||
Index: 24,
|
|
||||||
NumSymbols: 0,
|
|
||||||
ReduceFunc: func(X []Attrib) (Attrib, error) {
|
|
||||||
return nil, nil
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ProdTabEntry{
|
|
||||||
String: `OptEdge : Edge << >>`,
|
|
||||||
Id: "OptEdge",
|
|
||||||
NTType: 13,
|
|
||||||
Index: 25,
|
|
||||||
NumSymbols: 1,
|
|
||||||
ReduceFunc: func(X []Attrib) (Attrib, error) {
|
|
||||||
return X[0], nil
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ProdTabEntry{
|
|
||||||
String: `AttrStmt : Component AttrList << astx.NewAttrStmt(X[0], X[1]) >>`,
|
|
||||||
Id: "AttrStmt",
|
|
||||||
NTType: 14,
|
|
||||||
Index: 26,
|
|
||||||
NumSymbols: 2,
|
|
||||||
ReduceFunc: func(X []Attrib) (Attrib, error) {
|
|
||||||
return astx.NewAttrStmt(X[0], X[1])
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ProdTabEntry{
|
|
||||||
String: `Component : graphx << ast.GraphKind, nil >>`,
|
|
||||||
Id: "Component",
|
|
||||||
NTType: 15,
|
|
||||||
Index: 27,
|
|
||||||
NumSymbols: 1,
|
|
||||||
ReduceFunc: func(X []Attrib) (Attrib, error) {
|
|
||||||
return ast.GraphKind, nil
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ProdTabEntry{
|
|
||||||
String: `Component : node << ast.NodeKind, nil >>`,
|
|
||||||
Id: "Component",
|
|
||||||
NTType: 15,
|
|
||||||
Index: 28,
|
|
||||||
NumSymbols: 1,
|
|
||||||
ReduceFunc: func(X []Attrib) (Attrib, error) {
|
|
||||||
return ast.NodeKind, nil
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ProdTabEntry{
|
|
||||||
String: `Component : edge << ast.EdgeKind, nil >>`,
|
|
||||||
Id: "Component",
|
|
||||||
NTType: 15,
|
|
||||||
Index: 29,
|
|
||||||
NumSymbols: 1,
|
|
||||||
ReduceFunc: func(X []Attrib) (Attrib, error) {
|
|
||||||
return ast.EdgeKind, nil
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ProdTabEntry{
|
|
||||||
String: `AttrList : "[" OptAList "]" << X[1], nil >>`,
|
|
||||||
Id: "AttrList",
|
|
||||||
NTType: 16,
|
|
||||||
Index: 30,
|
|
||||||
NumSymbols: 3,
|
|
||||||
ReduceFunc: func(X []Attrib) (Attrib, error) {
|
|
||||||
return X[1], nil
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ProdTabEntry{
|
|
||||||
String: `AttrList : AttrList "[" OptAList "]" << astx.AppendAttrList(X[0], X[2]) >>`,
|
|
||||||
Id: "AttrList",
|
|
||||||
NTType: 16,
|
|
||||||
Index: 31,
|
|
||||||
NumSymbols: 4,
|
|
||||||
ReduceFunc: func(X []Attrib) (Attrib, error) {
|
|
||||||
return astx.AppendAttrList(X[0], X[2])
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ProdTabEntry{
|
|
||||||
String: `OptAttrList : empty << >>`,
|
|
||||||
Id: "OptAttrList",
|
|
||||||
NTType: 17,
|
|
||||||
Index: 32,
|
|
||||||
NumSymbols: 0,
|
|
||||||
ReduceFunc: func(X []Attrib) (Attrib, error) {
|
|
||||||
return nil, nil
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ProdTabEntry{
|
|
||||||
String: `OptAttrList : AttrList << >>`,
|
|
||||||
Id: "OptAttrList",
|
|
||||||
NTType: 17,
|
|
||||||
Index: 33,
|
|
||||||
NumSymbols: 1,
|
|
||||||
ReduceFunc: func(X []Attrib) (Attrib, error) {
|
|
||||||
return X[0], nil
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ProdTabEntry{
|
|
||||||
String: `AList : Attr OptSep << astx.NewAttrList(X[0]) >>`,
|
|
||||||
Id: "AList",
|
|
||||||
NTType: 18,
|
|
||||||
Index: 34,
|
|
||||||
NumSymbols: 2,
|
|
||||||
ReduceFunc: func(X []Attrib) (Attrib, error) {
|
|
||||||
return astx.NewAttrList(X[0])
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ProdTabEntry{
|
|
||||||
String: `AList : AList Attr OptSep << astx.AppendAttr(X[0], X[1]) >>`,
|
|
||||||
Id: "AList",
|
|
||||||
NTType: 18,
|
|
||||||
Index: 35,
|
|
||||||
NumSymbols: 3,
|
|
||||||
ReduceFunc: func(X []Attrib) (Attrib, error) {
|
|
||||||
return astx.AppendAttr(X[0], X[1])
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ProdTabEntry{
|
|
||||||
String: `OptAList : empty << >>`,
|
|
||||||
Id: "OptAList",
|
|
||||||
NTType: 19,
|
|
||||||
Index: 36,
|
|
||||||
NumSymbols: 0,
|
|
||||||
ReduceFunc: func(X []Attrib) (Attrib, error) {
|
|
||||||
return nil, nil
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ProdTabEntry{
|
|
||||||
String: `OptAList : AList << >>`,
|
|
||||||
Id: "OptAList",
|
|
||||||
NTType: 19,
|
|
||||||
Index: 37,
|
|
||||||
NumSymbols: 1,
|
|
||||||
ReduceFunc: func(X []Attrib) (Attrib, error) {
|
|
||||||
return X[0], nil
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ProdTabEntry{
|
|
||||||
String: `OptSep : empty << >>`,
|
|
||||||
Id: "OptSep",
|
|
||||||
NTType: 20,
|
|
||||||
Index: 38,
|
|
||||||
NumSymbols: 0,
|
|
||||||
ReduceFunc: func(X []Attrib) (Attrib, error) {
|
|
||||||
return nil, nil
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ProdTabEntry{
|
|
||||||
String: `OptSep : ";" << >>`,
|
|
||||||
Id: "OptSep",
|
|
||||||
NTType: 20,
|
|
||||||
Index: 39,
|
|
||||||
NumSymbols: 1,
|
|
||||||
ReduceFunc: func(X []Attrib) (Attrib, error) {
|
|
||||||
return X[0], nil
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ProdTabEntry{
|
|
||||||
String: `OptSep : "," << >>`,
|
|
||||||
Id: "OptSep",
|
|
||||||
NTType: 20,
|
|
||||||
Index: 40,
|
|
||||||
NumSymbols: 1,
|
|
||||||
ReduceFunc: func(X []Attrib) (Attrib, error) {
|
|
||||||
return X[0], nil
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ProdTabEntry{
|
|
||||||
String: `Attr : ID "=" ID << astx.NewAttr(X[0], X[2]) >>`,
|
|
||||||
Id: "Attr",
|
|
||||||
NTType: 21,
|
|
||||||
Index: 41,
|
|
||||||
NumSymbols: 3,
|
|
||||||
ReduceFunc: func(X []Attrib) (Attrib, error) {
|
|
||||||
return astx.NewAttr(X[0], X[2])
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ProdTabEntry{
|
|
||||||
String: `Subgraph : OptSubgraphID "{" OptStmtList "}" << astx.NewSubgraph(X[0], X[2]) >>`,
|
|
||||||
Id: "Subgraph",
|
|
||||||
NTType: 22,
|
|
||||||
Index: 42,
|
|
||||||
NumSymbols: 4,
|
|
||||||
ReduceFunc: func(X []Attrib) (Attrib, error) {
|
|
||||||
return astx.NewSubgraph(X[0], X[2])
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ProdTabEntry{
|
|
||||||
String: `OptSubgraphID : empty << >>`,
|
|
||||||
Id: "OptSubgraphID",
|
|
||||||
NTType: 23,
|
|
||||||
Index: 43,
|
|
||||||
NumSymbols: 0,
|
|
||||||
ReduceFunc: func(X []Attrib) (Attrib, error) {
|
|
||||||
return nil, nil
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ProdTabEntry{
|
|
||||||
String: `OptSubgraphID : subgraph OptID << X[1], nil >>`,
|
|
||||||
Id: "OptSubgraphID",
|
|
||||||
NTType: 23,
|
|
||||||
Index: 44,
|
|
||||||
NumSymbols: 2,
|
|
||||||
ReduceFunc: func(X []Attrib) (Attrib, error) {
|
|
||||||
return X[1], nil
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ProdTabEntry{
|
|
||||||
String: `Vertex : Node << >>`,
|
|
||||||
Id: "Vertex",
|
|
||||||
NTType: 24,
|
|
||||||
Index: 45,
|
|
||||||
NumSymbols: 1,
|
|
||||||
ReduceFunc: func(X []Attrib) (Attrib, error) {
|
|
||||||
return X[0], nil
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ProdTabEntry{
|
|
||||||
String: `Vertex : Subgraph << >>`,
|
|
||||||
Id: "Vertex",
|
|
||||||
NTType: 24,
|
|
||||||
Index: 46,
|
|
||||||
NumSymbols: 1,
|
|
||||||
ReduceFunc: func(X []Attrib) (Attrib, error) {
|
|
||||||
return X[0], nil
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ProdTabEntry{
|
|
||||||
String: `Node : ID OptPort << astx.NewNode(X[0], X[1]) >>`,
|
|
||||||
Id: "Node",
|
|
||||||
NTType: 25,
|
|
||||||
Index: 47,
|
|
||||||
NumSymbols: 2,
|
|
||||||
ReduceFunc: func(X []Attrib) (Attrib, error) {
|
|
||||||
return astx.NewNode(X[0], X[1])
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ProdTabEntry{
|
|
||||||
String: `Port : ":" ID << astx.NewPort(X[1], nil) >>`,
|
|
||||||
Id: "Port",
|
|
||||||
NTType: 26,
|
|
||||||
Index: 48,
|
|
||||||
NumSymbols: 2,
|
|
||||||
ReduceFunc: func(X []Attrib) (Attrib, error) {
|
|
||||||
return astx.NewPort(X[1], nil)
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ProdTabEntry{
|
|
||||||
String: `Port : ":" ID ":" ID << astx.NewPort(X[1], X[3]) >>`,
|
|
||||||
Id: "Port",
|
|
||||||
NTType: 26,
|
|
||||||
Index: 49,
|
|
||||||
NumSymbols: 4,
|
|
||||||
ReduceFunc: func(X []Attrib) (Attrib, error) {
|
|
||||||
return astx.NewPort(X[1], X[3])
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ProdTabEntry{
|
|
||||||
String: `OptPort : empty << >>`,
|
|
||||||
Id: "OptPort",
|
|
||||||
NTType: 27,
|
|
||||||
Index: 50,
|
|
||||||
NumSymbols: 0,
|
|
||||||
ReduceFunc: func(X []Attrib) (Attrib, error) {
|
|
||||||
return nil, nil
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ProdTabEntry{
|
|
||||||
String: `OptPort : Port << >>`,
|
|
||||||
Id: "OptPort",
|
|
||||||
NTType: 27,
|
|
||||||
Index: 51,
|
|
||||||
NumSymbols: 1,
|
|
||||||
ReduceFunc: func(X []Attrib) (Attrib, error) {
|
|
||||||
return X[0], nil
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ProdTabEntry{
|
|
||||||
String: `ID : id << astx.NewID(X[0]) >>`,
|
|
||||||
Id: "ID",
|
|
||||||
NTType: 28,
|
|
||||||
Index: 52,
|
|
||||||
NumSymbols: 1,
|
|
||||||
ReduceFunc: func(X []Attrib) (Attrib, error) {
|
|
||||||
return astx.NewID(X[0])
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ProdTabEntry{
|
|
||||||
String: `OptID : empty << "", nil >>`,
|
|
||||||
Id: "OptID",
|
|
||||||
NTType: 29,
|
|
||||||
Index: 53,
|
|
||||||
NumSymbols: 0,
|
|
||||||
ReduceFunc: func(X []Attrib) (Attrib, error) {
|
|
||||||
return "", nil
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ProdTabEntry{
|
|
||||||
String: `OptID : ID << >>`,
|
|
||||||
Id: "OptID",
|
|
||||||
NTType: 29,
|
|
||||||
Index: 54,
|
|
||||||
NumSymbols: 1,
|
|
||||||
ReduceFunc: func(X []Attrib) (Attrib, error) {
|
|
||||||
return X[0], nil
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
6
vendor/gonum.org/v1/gonum/graph/formats/dot/internal/token/doc.go
generated
vendored
6
vendor/gonum.org/v1/gonum/graph/formats/dot/internal/token/doc.go
generated
vendored
@@ -1,6 +0,0 @@
|
|||||||
// 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 token provides generated internal tokenizing functions for DOT parsing.
|
|
||||||
package token // import "gonum.org/v1/gonum/graph/formats/dot/internal/token"
|
|
||||||
116
vendor/gonum.org/v1/gonum/graph/formats/dot/internal/token/token.go
generated
vendored
116
vendor/gonum.org/v1/gonum/graph/formats/dot/internal/token/token.go
generated
vendored
@@ -1,116 +0,0 @@
|
|||||||
// Code generated by gocc; DO NOT EDIT.
|
|
||||||
|
|
||||||
// This file is dual licensed under CC0 and The gonum license.
|
|
||||||
//
|
|
||||||
// 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.
|
|
||||||
//
|
|
||||||
// Copyright ©2017 Robin Eklind.
|
|
||||||
// This file is made available under a Creative Commons CC0 1.0
|
|
||||||
// Universal Public Domain Dedication.
|
|
||||||
|
|
||||||
package token
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Token struct {
|
|
||||||
Type
|
|
||||||
Lit []byte
|
|
||||||
Pos
|
|
||||||
}
|
|
||||||
|
|
||||||
type Type int
|
|
||||||
|
|
||||||
const (
|
|
||||||
INVALID Type = iota
|
|
||||||
EOF
|
|
||||||
)
|
|
||||||
|
|
||||||
type Pos struct {
|
|
||||||
Offset int
|
|
||||||
Line int
|
|
||||||
Column int
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p Pos) String() string {
|
|
||||||
return fmt.Sprintf("Pos(offset=%d, line=%d, column=%d)", p.Offset, p.Line, p.Column)
|
|
||||||
}
|
|
||||||
|
|
||||||
type TokenMap struct {
|
|
||||||
typeMap []string
|
|
||||||
idMap map[string]Type
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m TokenMap) Id(tok Type) string {
|
|
||||||
if int(tok) < len(m.typeMap) {
|
|
||||||
return m.typeMap[tok]
|
|
||||||
}
|
|
||||||
return "unknown"
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m TokenMap) Type(tok string) Type {
|
|
||||||
if typ, exist := m.idMap[tok]; exist {
|
|
||||||
return typ
|
|
||||||
}
|
|
||||||
return INVALID
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m TokenMap) TokenString(tok *Token) string {
|
|
||||||
//TODO: refactor to print pos & token string properly
|
|
||||||
return fmt.Sprintf("%s(%d,%s)", m.Id(tok.Type), tok.Type, tok.Lit)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m TokenMap) StringType(typ Type) string {
|
|
||||||
return fmt.Sprintf("%s(%d)", m.Id(typ), typ)
|
|
||||||
}
|
|
||||||
|
|
||||||
var TokMap = TokenMap{
|
|
||||||
typeMap: []string{
|
|
||||||
"INVALID",
|
|
||||||
"$",
|
|
||||||
"{",
|
|
||||||
"}",
|
|
||||||
"empty",
|
|
||||||
"strict",
|
|
||||||
"graphx",
|
|
||||||
"digraph",
|
|
||||||
";",
|
|
||||||
"--",
|
|
||||||
"->",
|
|
||||||
"node",
|
|
||||||
"edge",
|
|
||||||
"[",
|
|
||||||
"]",
|
|
||||||
",",
|
|
||||||
"=",
|
|
||||||
"subgraph",
|
|
||||||
":",
|
|
||||||
"id",
|
|
||||||
},
|
|
||||||
|
|
||||||
idMap: map[string]Type{
|
|
||||||
"INVALID": 0,
|
|
||||||
"$": 1,
|
|
||||||
"{": 2,
|
|
||||||
"}": 3,
|
|
||||||
"empty": 4,
|
|
||||||
"strict": 5,
|
|
||||||
"graphx": 6,
|
|
||||||
"digraph": 7,
|
|
||||||
";": 8,
|
|
||||||
"--": 9,
|
|
||||||
"->": 10,
|
|
||||||
"node": 11,
|
|
||||||
"edge": 12,
|
|
||||||
"[": 13,
|
|
||||||
"]": 14,
|
|
||||||
",": 15,
|
|
||||||
"=": 16,
|
|
||||||
"subgraph": 17,
|
|
||||||
":": 18,
|
|
||||||
"id": 19,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
4
vendor/gonum.org/v1/gonum/graph/formats/dot/makeinternal.bash
generated
vendored
4
vendor/gonum.org/v1/gonum/graph/formats/dot/makeinternal.bash
generated
vendored
@@ -1,4 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
cd internal
|
|
||||||
make clean && make
|
|
||||||
160
vendor/gonum.org/v1/gonum/graph/formats/dot/sem.go
generated
vendored
160
vendor/gonum.org/v1/gonum/graph/formats/dot/sem.go
generated
vendored
@@ -1,160 +0,0 @@
|
|||||||
// This file is dual licensed under CC0 and The gonum license.
|
|
||||||
//
|
|
||||||
// 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.
|
|
||||||
//
|
|
||||||
// Copyright ©2017 Robin Eklind.
|
|
||||||
// This file is made available under a Creative Commons CC0 1.0
|
|
||||||
// Universal Public Domain Dedication.
|
|
||||||
|
|
||||||
package dot
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"gonum.org/v1/gonum/graph/formats/dot/ast"
|
|
||||||
)
|
|
||||||
|
|
||||||
// check validates the semantics of the given DOT file.
|
|
||||||
func check(file *ast.File) error {
|
|
||||||
for _, graph := range file.Graphs {
|
|
||||||
// TODO: Check graph.ID for duplicates?
|
|
||||||
if err := checkGraph(graph); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// check validates the semantics of the given graph.
|
|
||||||
func checkGraph(graph *ast.Graph) error {
|
|
||||||
for _, stmt := range graph.Stmts {
|
|
||||||
if err := checkStmt(graph, stmt); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// check validates the semantics of the given statement.
|
|
||||||
func checkStmt(graph *ast.Graph, stmt ast.Stmt) error {
|
|
||||||
switch stmt := stmt.(type) {
|
|
||||||
case *ast.NodeStmt:
|
|
||||||
return checkNodeStmt(graph, stmt)
|
|
||||||
case *ast.EdgeStmt:
|
|
||||||
return checkEdgeStmt(graph, stmt)
|
|
||||||
case *ast.AttrStmt:
|
|
||||||
return checkAttrStmt(graph, stmt)
|
|
||||||
case *ast.Attr:
|
|
||||||
// TODO: Verify that the attribute is indeed of graph component kind.
|
|
||||||
return checkAttr(graph, ast.GraphKind, stmt)
|
|
||||||
case *ast.Subgraph:
|
|
||||||
return checkSubgraph(graph, stmt)
|
|
||||||
default:
|
|
||||||
panic(fmt.Sprintf("support for statement of type %T not yet implemented", stmt))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// checkNodeStmt validates the semantics of the given node statement.
|
|
||||||
func checkNodeStmt(graph *ast.Graph, stmt *ast.NodeStmt) error {
|
|
||||||
if err := checkNode(graph, stmt.Node); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
for _, attr := range stmt.Attrs {
|
|
||||||
// TODO: Verify that the attribute is indeed of node component kind.
|
|
||||||
if err := checkAttr(graph, ast.NodeKind, attr); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// checkEdgeStmt validates the semantics of the given edge statement.
|
|
||||||
func checkEdgeStmt(graph *ast.Graph, stmt *ast.EdgeStmt) error {
|
|
||||||
// TODO: if graph.Strict, check for multi-edges.
|
|
||||||
if err := checkVertex(graph, stmt.From); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
for _, attr := range stmt.Attrs {
|
|
||||||
// TODO: Verify that the attribute is indeed of edge component kind.
|
|
||||||
if err := checkAttr(graph, ast.EdgeKind, attr); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return checkEdge(graph, stmt.From, stmt.To)
|
|
||||||
}
|
|
||||||
|
|
||||||
// checkEdge validates the semantics of the given edge.
|
|
||||||
func checkEdge(graph *ast.Graph, from ast.Vertex, to *ast.Edge) error {
|
|
||||||
if !graph.Directed && to.Directed {
|
|
||||||
return fmt.Errorf("undirected graph %q contains directed edge from %q to %q", graph.ID, from, to.Vertex)
|
|
||||||
}
|
|
||||||
if err := checkVertex(graph, to.Vertex); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if to.To != nil {
|
|
||||||
return checkEdge(graph, to.Vertex, to.To)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// checkAttrStmt validates the semantics of the given attribute statement.
|
|
||||||
func checkAttrStmt(graph *ast.Graph, stmt *ast.AttrStmt) error {
|
|
||||||
for _, attr := range stmt.Attrs {
|
|
||||||
if err := checkAttr(graph, stmt.Kind, attr); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// checkAttr validates the semantics of the given attribute for the given
|
|
||||||
// component kind.
|
|
||||||
func checkAttr(graph *ast.Graph, kind ast.Kind, attr *ast.Attr) error {
|
|
||||||
switch kind {
|
|
||||||
case ast.GraphKind:
|
|
||||||
// TODO: Validate key-value pairs for graphs.
|
|
||||||
return nil
|
|
||||||
case ast.NodeKind:
|
|
||||||
// TODO: Validate key-value pairs for nodes.
|
|
||||||
return nil
|
|
||||||
case ast.EdgeKind:
|
|
||||||
// TODO: Validate key-value pairs for edges.
|
|
||||||
return nil
|
|
||||||
default:
|
|
||||||
panic(fmt.Sprintf("support for component kind %v not yet supported", kind))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// checkSubgraph validates the semantics of the given subgraph.
|
|
||||||
func checkSubgraph(graph *ast.Graph, subgraph *ast.Subgraph) error {
|
|
||||||
// TODO: Check subgraph.ID for duplicates?
|
|
||||||
for _, stmt := range subgraph.Stmts {
|
|
||||||
// TODO: Refine handling of subgraph statements?
|
|
||||||
// checkSubgraphStmt(graph, subgraph, stmt)
|
|
||||||
if err := checkStmt(graph, stmt); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// checkVertex validates the semantics of the given vertex.
|
|
||||||
func checkVertex(graph *ast.Graph, vertex ast.Vertex) error {
|
|
||||||
switch vertex := vertex.(type) {
|
|
||||||
case *ast.Node:
|
|
||||||
return checkNode(graph, vertex)
|
|
||||||
case *ast.Subgraph:
|
|
||||||
return checkSubgraph(graph, vertex)
|
|
||||||
default:
|
|
||||||
panic(fmt.Sprintf("support for vertex of type %T not yet supported", vertex))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// checNode validates the semantics of the given node.
|
|
||||||
func checkNode(graph *ast.Graph, node *ast.Node) error {
|
|
||||||
// TODO: Check node.ID for duplicates?
|
|
||||||
// TODO: Validate node.Port.
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
282
vendor/gonum.org/v1/gonum/graph/graph.go
generated
vendored
282
vendor/gonum.org/v1/gonum/graph/graph.go
generated
vendored
@@ -1,282 +0,0 @@
|
|||||||
// Copyright ©2014 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
|
|
||||||
|
|
||||||
// Node is a graph node. It returns a graph-unique integer ID.
|
|
||||||
type Node interface {
|
|
||||||
ID() int64
|
|
||||||
}
|
|
||||||
|
|
||||||
// Edge is a graph edge. In directed graphs, the direction of the
|
|
||||||
// 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
|
|
||||||
// of the edge is given from -> to, otherwise the edge is semantically
|
|
||||||
// unordered.
|
|
||||||
type WeightedEdge interface {
|
|
||||||
Edge
|
|
||||||
Weight() float64
|
|
||||||
}
|
|
||||||
|
|
||||||
// Graph is a generalized graph.
|
|
||||||
type Graph interface {
|
|
||||||
// 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 must not return nil.
|
|
||||||
Nodes() Nodes
|
|
||||||
|
|
||||||
// From returns all nodes that can be reached directly
|
|
||||||
// from the node with the given ID.
|
|
||||||
//
|
|
||||||
// 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.
|
|
||||||
HasEdgeBetween(xid, yid int64) bool
|
|
||||||
|
|
||||||
// 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.
|
|
||||||
Edge(uid, vid int64) Edge
|
|
||||||
}
|
|
||||||
|
|
||||||
// Weighted is a weighted graph.
|
|
||||||
type Weighted interface {
|
|
||||||
Graph
|
|
||||||
|
|
||||||
// WeightedEdge returns the weighted 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.
|
|
||||||
WeightedEdge(uid, vid int64) WeightedEdge
|
|
||||||
|
|
||||||
// Weight returns the weight for the edge between
|
|
||||||
// x and y with IDs xid and yid if Edge(xid, yid)
|
|
||||||
// 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 implementation dependent.
|
|
||||||
// Weight returns true if an edge exists between
|
|
||||||
// x and y or if x and y have the same ID, false
|
|
||||||
// otherwise.
|
|
||||||
Weight(xid, yid int64) (w float64, ok bool)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Undirected is an undirected graph.
|
|
||||||
type Undirected interface {
|
|
||||||
Graph
|
|
||||||
|
|
||||||
// EdgeBetween returns the edge between nodes x and y
|
|
||||||
// with IDs xid and yid.
|
|
||||||
EdgeBetween(xid, yid int64) Edge
|
|
||||||
}
|
|
||||||
|
|
||||||
// WeightedUndirected is a weighted undirected graph.
|
|
||||||
type WeightedUndirected interface {
|
|
||||||
Weighted
|
|
||||||
|
|
||||||
// WeightedEdgeBetween returns the edge between nodes
|
|
||||||
// x and y with IDs xid and yid.
|
|
||||||
WeightedEdgeBetween(xid, yid int64) WeightedEdge
|
|
||||||
}
|
|
||||||
|
|
||||||
// Directed is a directed graph.
|
|
||||||
type Directed interface {
|
|
||||||
Graph
|
|
||||||
|
|
||||||
// HasEdgeFromTo returns whether an edge exists
|
|
||||||
// in the graph from u to v with IDs uid and vid.
|
|
||||||
HasEdgeFromTo(uid, vid int64) bool
|
|
||||||
|
|
||||||
// To returns all nodes that can reach directly
|
|
||||||
// to the node with the given ID.
|
|
||||||
//
|
|
||||||
// To must not return nil.
|
|
||||||
To(id int64) Nodes
|
|
||||||
}
|
|
||||||
|
|
||||||
// WeightedDirected is a weighted directed graph.
|
|
||||||
type WeightedDirected interface {
|
|
||||||
Weighted
|
|
||||||
|
|
||||||
// HasEdgeFromTo returns whether an edge exists
|
|
||||||
// in the graph from u to v with the IDs uid and
|
|
||||||
// vid.
|
|
||||||
HasEdgeFromTo(uid, vid int64) bool
|
|
||||||
|
|
||||||
// To returns all nodes that can reach directly
|
|
||||||
// to the node with the given ID.
|
|
||||||
//
|
|
||||||
// To must not return nil.
|
|
||||||
To(id int64) Nodes
|
|
||||||
}
|
|
||||||
|
|
||||||
// NodeAdder is an interface for adding arbitrary nodes to a graph.
|
|
||||||
type NodeAdder interface {
|
|
||||||
// NewNode returns a new Node with a unique
|
|
||||||
// arbitrary ID.
|
|
||||||
NewNode() Node
|
|
||||||
|
|
||||||
// AddNode adds a node to the graph. AddNode panics if
|
|
||||||
// the added node ID matches an existing node ID.
|
|
||||||
AddNode(Node)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NodeRemover is an interface for removing nodes from a graph.
|
|
||||||
type NodeRemover interface {
|
|
||||||
// RemoveNode removes the node with the given ID
|
|
||||||
// from the graph, as well as any edges attached
|
|
||||||
// to it. If the node is not in the graph it is
|
|
||||||
// a no-op.
|
|
||||||
RemoveNode(id int64)
|
|
||||||
}
|
|
||||||
|
|
||||||
// EdgeAdder is an interface for adding edges to a graph.
|
|
||||||
type EdgeAdder interface {
|
|
||||||
// NewEdge returns a new Edge from the source to the destination node.
|
|
||||||
NewEdge(from, to Node) Edge
|
|
||||||
|
|
||||||
// SetEdge adds an edge from one node to another.
|
|
||||||
// If the graph supports node addition the nodes
|
|
||||||
// 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
|
|
||||||
// implementation-dependent.
|
|
||||||
// Whether e, e.From() and e.To() are stored
|
|
||||||
// within the graph is implementation dependent.
|
|
||||||
SetEdge(e Edge)
|
|
||||||
}
|
|
||||||
|
|
||||||
// WeightedEdgeAdder is an interface for adding edges to a graph.
|
|
||||||
type WeightedEdgeAdder interface {
|
|
||||||
// NewWeightedEdge returns a new WeightedEdge from
|
|
||||||
// the source to the destination node.
|
|
||||||
NewWeightedEdge(from, to Node, weight float64) WeightedEdge
|
|
||||||
|
|
||||||
// SetWeightedEdge adds an edge from one node to
|
|
||||||
// another. If the graph supports node addition
|
|
||||||
// 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
|
|
||||||
// implementation-dependent.
|
|
||||||
// Whether e, e.From() and e.To() are stored
|
|
||||||
// within the graph is implementation dependent.
|
|
||||||
SetWeightedEdge(e WeightedEdge)
|
|
||||||
}
|
|
||||||
|
|
||||||
// EdgeRemover is an interface for removing nodes from a graph.
|
|
||||||
type EdgeRemover interface {
|
|
||||||
// RemoveEdge removes the edge with the given end
|
|
||||||
// IDs, leaving the terminal nodes. If the edge
|
|
||||||
// does not exist it is a no-op.
|
|
||||||
RemoveEdge(fid, tid int64)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Builder is a graph that can have nodes and edges added.
|
|
||||||
type Builder interface {
|
|
||||||
NodeAdder
|
|
||||||
EdgeAdder
|
|
||||||
}
|
|
||||||
|
|
||||||
// WeightedBuilder is a graph that can have nodes and weighted edges added.
|
|
||||||
type WeightedBuilder interface {
|
|
||||||
NodeAdder
|
|
||||||
WeightedEdgeAdder
|
|
||||||
}
|
|
||||||
|
|
||||||
// UndirectedBuilder is an undirected graph builder.
|
|
||||||
type UndirectedBuilder interface {
|
|
||||||
Undirected
|
|
||||||
Builder
|
|
||||||
}
|
|
||||||
|
|
||||||
// UndirectedWeightedBuilder is an undirected weighted graph builder.
|
|
||||||
type UndirectedWeightedBuilder interface {
|
|
||||||
Undirected
|
|
||||||
WeightedBuilder
|
|
||||||
}
|
|
||||||
|
|
||||||
// DirectedBuilder is a directed graph builder.
|
|
||||||
type DirectedBuilder interface {
|
|
||||||
Directed
|
|
||||||
Builder
|
|
||||||
}
|
|
||||||
|
|
||||||
// DirectedWeightedBuilder is a directed weighted graph builder.
|
|
||||||
type DirectedWeightedBuilder interface {
|
|
||||||
Directed
|
|
||||||
WeightedBuilder
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy copies nodes and edges as undirected edges from the source to the destination
|
|
||||||
// without first clearing the destination. Copy will panic if a node ID in the source
|
|
||||||
// graph matches a node ID in the destination.
|
|
||||||
//
|
|
||||||
// If the source is undirected and the destination is directed both directions will
|
|
||||||
// be present in the destination after the copy is complete.
|
|
||||||
func Copy(dst Builder, src Graph) {
|
|
||||||
nodes := src.Nodes()
|
|
||||||
for nodes.Next() {
|
|
||||||
dst.AddNode(nodes.Node())
|
|
||||||
}
|
|
||||||
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()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// CopyWeighted copies nodes and edges as undirected edges from the source to the destination
|
|
||||||
// without first clearing the destination. Copy will panic if a node ID in the source
|
|
||||||
// graph matches a node ID in the destination.
|
|
||||||
//
|
|
||||||
// If the source is undirected and the destination is directed both directions will
|
|
||||||
// be present in the destination after the copy is complete.
|
|
||||||
//
|
|
||||||
// If the source is a directed graph, the destination is undirected, and a fundamental
|
|
||||||
// cycle exists with two nodes where the edge weights differ, the resulting destination
|
|
||||||
// graph's edge weight between those nodes is undefined. If there is a defined function
|
|
||||||
// to resolve such conflicts, an UndirectWeighted may be used to do this.
|
|
||||||
func CopyWeighted(dst WeightedBuilder, src Weighted) {
|
|
||||||
nodes := src.Nodes()
|
|
||||||
for nodes.Next() {
|
|
||||||
dst.AddNode(nodes.Node())
|
|
||||||
}
|
|
||||||
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()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
6
vendor/gonum.org/v1/gonum/graph/internal/ordered/doc.go
generated
vendored
6
vendor/gonum.org/v1/gonum/graph/internal/ordered/doc.go
generated
vendored
@@ -1,6 +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 ordered provides common sort ordering types.
|
|
||||||
package ordered // import "gonum.org/v1/gonum/graph/internal/ordered"
|
|
||||||
93
vendor/gonum.org/v1/gonum/graph/internal/ordered/sort.go
generated
vendored
93
vendor/gonum.org/v1/gonum/graph/internal/ordered/sort.go
generated
vendored
@@ -1,93 +0,0 @@
|
|||||||
// 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 ordered
|
|
||||||
|
|
||||||
import "gonum.org/v1/gonum/graph"
|
|
||||||
|
|
||||||
// ByID implements the sort.Interface sorting a slice of graph.Node
|
|
||||||
// by ID.
|
|
||||||
type ByID []graph.Node
|
|
||||||
|
|
||||||
func (n ByID) Len() int { return len(n) }
|
|
||||||
func (n ByID) Less(i, j int) bool { return n[i].ID() < n[j].ID() }
|
|
||||||
func (n ByID) Swap(i, j int) { n[i], n[j] = n[j], n[i] }
|
|
||||||
|
|
||||||
// BySliceValues implements the sort.Interface sorting a slice of
|
|
||||||
// []int64 lexically by the values of the []int64.
|
|
||||||
type BySliceValues [][]int64
|
|
||||||
|
|
||||||
func (c BySliceValues) Len() int { return len(c) }
|
|
||||||
func (c BySliceValues) Less(i, j int) bool {
|
|
||||||
a, b := c[i], c[j]
|
|
||||||
l := len(a)
|
|
||||||
if len(b) < l {
|
|
||||||
l = len(b)
|
|
||||||
}
|
|
||||||
for k, v := range a[:l] {
|
|
||||||
if v < b[k] {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
if v > b[k] {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return len(a) < len(b)
|
|
||||||
}
|
|
||||||
func (c BySliceValues) Swap(i, j int) { c[i], c[j] = c[j], c[i] }
|
|
||||||
|
|
||||||
// BySliceIDs implements the sort.Interface sorting a slice of
|
|
||||||
// []graph.Node lexically by the IDs of the []graph.Node.
|
|
||||||
type BySliceIDs [][]graph.Node
|
|
||||||
|
|
||||||
func (c BySliceIDs) Len() int { return len(c) }
|
|
||||||
func (c BySliceIDs) Less(i, j int) bool {
|
|
||||||
a, b := c[i], c[j]
|
|
||||||
l := len(a)
|
|
||||||
if len(b) < l {
|
|
||||||
l = len(b)
|
|
||||||
}
|
|
||||||
for k, v := range a[:l] {
|
|
||||||
if v.ID() < b[k].ID() {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
if v.ID() > b[k].ID() {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return len(a) < len(b)
|
|
||||||
}
|
|
||||||
func (c BySliceIDs) Swap(i, j int) { c[i], c[j] = c[j], c[i] }
|
|
||||||
|
|
||||||
// Int64s implements the sort.Interface sorting a slice of
|
|
||||||
// int64.
|
|
||||||
type Int64s []int64
|
|
||||||
|
|
||||||
func (s Int64s) Len() int { return len(s) }
|
|
||||||
func (s Int64s) Less(i, j int) bool { return s[i] < s[j] }
|
|
||||||
func (s Int64s) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
|
||||||
|
|
||||||
// Reverse reverses the order of nodes.
|
|
||||||
func Reverse(nodes []graph.Node) {
|
|
||||||
for i, j := 0, len(nodes)-1; i < j; i, j = i+1, j-1 {
|
|
||||||
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] }
|
|
||||||
6
vendor/gonum.org/v1/gonum/graph/internal/set/doc.go
generated
vendored
6
vendor/gonum.org/v1/gonum/graph/internal/set/doc.go
generated
vendored
@@ -1,6 +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 set provides integer and graph.Node sets.
|
|
||||||
package set // import "gonum.org/v1/gonum/graph/internal/set"
|
|
||||||
36
vendor/gonum.org/v1/gonum/graph/internal/set/same.go
generated
vendored
36
vendor/gonum.org/v1/gonum/graph/internal/set/same.go
generated
vendored
@@ -1,36 +0,0 @@
|
|||||||
// Copyright ©2014 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 !appengine,!safe
|
|
||||||
|
|
||||||
package set
|
|
||||||
|
|
||||||
import "unsafe"
|
|
||||||
|
|
||||||
// same determines whether two sets are backed by the same store. In the
|
|
||||||
// current implementation using hash maps it makes use of the fact that
|
|
||||||
// hash maps are passed as a pointer to a runtime Hmap struct. A map is
|
|
||||||
// not seen by the runtime as a pointer though, so we use unsafe to get
|
|
||||||
// the maps' pointer values to compare.
|
|
||||||
func same(a, b Nodes) bool {
|
|
||||||
return *(*uintptr)(unsafe.Pointer(&a)) == *(*uintptr)(unsafe.Pointer(&b))
|
|
||||||
}
|
|
||||||
|
|
||||||
// intsSame determines whether two sets are backed by the same store. In the
|
|
||||||
// current implementation using hash maps it makes use of the fact that
|
|
||||||
// hash maps are passed as a pointer to a runtime Hmap struct. A map is
|
|
||||||
// not seen by the runtime as a pointer though, so we use unsafe to get
|
|
||||||
// the maps' pointer values to compare.
|
|
||||||
func intsSame(a, b Ints) bool {
|
|
||||||
return *(*uintptr)(unsafe.Pointer(&a)) == *(*uintptr)(unsafe.Pointer(&b))
|
|
||||||
}
|
|
||||||
|
|
||||||
// int64sSame determines whether two sets are backed by the same store. In the
|
|
||||||
// current implementation using hash maps it makes use of the fact that
|
|
||||||
// hash maps are passed as a pointer to a runtime Hmap struct. A map is
|
|
||||||
// not seen by the runtime as a pointer though, so we use unsafe to get
|
|
||||||
// the maps' pointer values to compare.
|
|
||||||
func int64sSame(a, b Int64s) bool {
|
|
||||||
return *(*uintptr)(unsafe.Pointer(&a)) == *(*uintptr)(unsafe.Pointer(&b))
|
|
||||||
}
|
|
||||||
36
vendor/gonum.org/v1/gonum/graph/internal/set/same_appengine.go
generated
vendored
36
vendor/gonum.org/v1/gonum/graph/internal/set/same_appengine.go
generated
vendored
@@ -1,36 +0,0 @@
|
|||||||
// Copyright ©2014 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 appengine safe
|
|
||||||
|
|
||||||
package set
|
|
||||||
|
|
||||||
import "reflect"
|
|
||||||
|
|
||||||
// same determines whether two sets are backed by the same store. In the
|
|
||||||
// current implementation using hash maps it makes use of the fact that
|
|
||||||
// hash maps are passed as a pointer to a runtime Hmap struct. A map is
|
|
||||||
// not seen by the runtime as a pointer though, so we use reflect to get
|
|
||||||
// the maps' pointer values to compare.
|
|
||||||
func same(a, b Nodes) bool {
|
|
||||||
return reflect.ValueOf(a).Pointer() == reflect.ValueOf(b).Pointer()
|
|
||||||
}
|
|
||||||
|
|
||||||
// intsSame determines whether two sets are backed by the same store. In the
|
|
||||||
// current implementation using hash maps it makes use of the fact that
|
|
||||||
// hash maps are passed as a pointer to a runtime Hmap struct. A map is
|
|
||||||
// not seen by the runtime as a pointer though, so we use reflect to get
|
|
||||||
// the maps' pointer values to compare.
|
|
||||||
func intsSame(a, b Ints) bool {
|
|
||||||
return reflect.ValueOf(a).Pointer() == reflect.ValueOf(b).Pointer()
|
|
||||||
}
|
|
||||||
|
|
||||||
// int64sSame determines whether two sets are backed by the same store. In the
|
|
||||||
// current implementation using hash maps it makes use of the fact that
|
|
||||||
// hash maps are passed as a pointer to a runtime Hmap struct. A map is
|
|
||||||
// not seen by the runtime as a pointer though, so we use reflect to get
|
|
||||||
// the maps' pointer values to compare.
|
|
||||||
func int64sSame(a, b Int64s) bool {
|
|
||||||
return reflect.ValueOf(a).Pointer() == reflect.ValueOf(b).Pointer()
|
|
||||||
}
|
|
||||||
228
vendor/gonum.org/v1/gonum/graph/internal/set/set.go
generated
vendored
228
vendor/gonum.org/v1/gonum/graph/internal/set/set.go
generated
vendored
@@ -1,228 +0,0 @@
|
|||||||
// Copyright ©2014 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 set
|
|
||||||
|
|
||||||
import "gonum.org/v1/gonum/graph"
|
|
||||||
|
|
||||||
// Ints is a set of int identifiers.
|
|
||||||
type Ints map[int]struct{}
|
|
||||||
|
|
||||||
// The simple accessor methods for Ints are provided to allow ease of
|
|
||||||
// implementation change should the need arise.
|
|
||||||
|
|
||||||
// Add inserts an element into the set.
|
|
||||||
func (s Ints) Add(e int) {
|
|
||||||
s[e] = struct{}{}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Has reports the existence of the element in the set.
|
|
||||||
func (s Ints) Has(e int) bool {
|
|
||||||
_, ok := s[e]
|
|
||||||
return ok
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove deletes the specified element from the set.
|
|
||||||
func (s Ints) Remove(e int) {
|
|
||||||
delete(s, e)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Count reports the number of elements stored in the set.
|
|
||||||
func (s Ints) Count() int {
|
|
||||||
return len(s)
|
|
||||||
}
|
|
||||||
|
|
||||||
// IntsEqual reports set equality between the parameters. Sets are equal if
|
|
||||||
// and only if they have the same elements.
|
|
||||||
func IntsEqual(a, b Ints) bool {
|
|
||||||
if intsSame(a, b) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(a) != len(b) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
for e := range a {
|
|
||||||
if _, ok := b[e]; !ok {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// Int64s is a set of int64 identifiers.
|
|
||||||
type Int64s map[int64]struct{}
|
|
||||||
|
|
||||||
// The simple accessor methods for Ints are provided to allow ease of
|
|
||||||
// implementation change should the need arise.
|
|
||||||
|
|
||||||
// Add inserts an element into the set.
|
|
||||||
func (s Int64s) Add(e int64) {
|
|
||||||
s[e] = struct{}{}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Has reports the existence of the element in the set.
|
|
||||||
func (s Int64s) Has(e int64) bool {
|
|
||||||
_, ok := s[e]
|
|
||||||
return ok
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove deletes the specified element from the set.
|
|
||||||
func (s Int64s) Remove(e int64) {
|
|
||||||
delete(s, e)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Count reports the number of elements stored in the set.
|
|
||||||
func (s Int64s) Count() int {
|
|
||||||
return len(s)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Int64sEqual reports set equality between the parameters. Sets are equal if
|
|
||||||
// and only if they have the same elements.
|
|
||||||
func Int64sEqual(a, b Int64s) bool {
|
|
||||||
if int64sSame(a, b) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(a) != len(b) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
for e := range a {
|
|
||||||
if _, ok := b[e]; !ok {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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.
|
|
||||||
|
|
||||||
// Add inserts an element into the set.
|
|
||||||
func (s Nodes) Add(n graph.Node) {
|
|
||||||
s[n.ID()] = n
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove deletes the specified element from the set.
|
|
||||||
func (s Nodes) Remove(e graph.Node) {
|
|
||||||
delete(s, e.ID())
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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
|
|
||||||
}
|
|
||||||
|
|
||||||
// Equal reports set equality between the parameters. Sets are equal if
|
|
||||||
// and only if they have the same elements.
|
|
||||||
func Equal(a, b Nodes) bool {
|
|
||||||
if same(a, b) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(a) != len(b) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
for e := range a {
|
|
||||||
if _, ok := b[e]; !ok {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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:
|
|
||||||
//
|
|
||||||
// {a,b,c} UNION {d,e,f} = {a,b,c,d,e,f}
|
|
||||||
//
|
|
||||||
// Since sets may not have repetition, unions of two sets that overlap
|
|
||||||
// do not contain repeat elements, that is:
|
|
||||||
//
|
|
||||||
// {a,b,c} UNION {b,c,d} = {a,b,c,d}
|
|
||||||
//
|
|
||||||
func UnionOfNodes(a, b Nodes) Nodes {
|
|
||||||
if same(a, b) {
|
|
||||||
return CloneNodes(a)
|
|
||||||
}
|
|
||||||
|
|
||||||
dst := make(Nodes)
|
|
||||||
for e, n := range a {
|
|
||||||
dst[e] = n
|
|
||||||
}
|
|
||||||
for e, n := range b {
|
|
||||||
dst[e] = n
|
|
||||||
}
|
|
||||||
|
|
||||||
return 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:
|
|
||||||
//
|
|
||||||
// {a,b,c} INTERSECT {b,c,d} = {b,c}
|
|
||||||
//
|
|
||||||
// The intersection between a set and itself is itself, and thus
|
|
||||||
// effectively a copy operation:
|
|
||||||
//
|
|
||||||
// {a,b,c} INTERSECT {a,b,c} = {a,b,c}
|
|
||||||
//
|
|
||||||
// The intersection between two sets that share no elements is the empty
|
|
||||||
// set:
|
|
||||||
//
|
|
||||||
// {a,b,c} INTERSECT {d,e,f} = {}
|
|
||||||
//
|
|
||||||
func IntersectionOfNodes(a, b Nodes) Nodes {
|
|
||||||
if same(a, b) {
|
|
||||||
return CloneNodes(a)
|
|
||||||
}
|
|
||||||
dst := make(Nodes)
|
|
||||||
if len(a) > len(b) {
|
|
||||||
a, b = b, a
|
|
||||||
}
|
|
||||||
for e, n := range a {
|
|
||||||
if _, ok := b[e]; ok {
|
|
||||||
dst[e] = n
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
54
vendor/gonum.org/v1/gonum/graph/internal/uid/uid.go
generated
vendored
54
vendor/gonum.org/v1/gonum/graph/internal/uid/uid.go
generated
vendored
@@ -1,54 +0,0 @@
|
|||||||
// Copyright ©2014 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 uid implements unique ID provision for graphs.
|
|
||||||
package uid
|
|
||||||
|
|
||||||
import "gonum.org/v1/gonum/graph/internal/set"
|
|
||||||
|
|
||||||
// Max is the maximum value of int64.
|
|
||||||
const Max = int64(^uint64(0) >> 1)
|
|
||||||
|
|
||||||
// Set implements available ID storage.
|
|
||||||
type Set struct {
|
|
||||||
maxID int64
|
|
||||||
used, free set.Int64s
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewSet returns a new Set. The returned value should not be passed except by pointer.
|
|
||||||
func NewSet() Set {
|
|
||||||
return Set{maxID: -1, used: make(set.Int64s), free: make(set.Int64s)}
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewID returns a new unique ID. The ID returned is not considered used
|
|
||||||
// until passed in a call to use.
|
|
||||||
func (s *Set) NewID() int64 {
|
|
||||||
for id := range s.free {
|
|
||||||
return id
|
|
||||||
}
|
|
||||||
if s.maxID != Max {
|
|
||||||
return s.maxID + 1
|
|
||||||
}
|
|
||||||
for id := int64(0); id <= s.maxID+1; id++ {
|
|
||||||
if !s.used.Has(id) {
|
|
||||||
return id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
panic("unreachable")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Use adds the id to the used IDs in the Set.
|
|
||||||
func (s *Set) Use(id int64) {
|
|
||||||
s.used.Add(id)
|
|
||||||
s.free.Remove(id)
|
|
||||||
if id > s.maxID {
|
|
||||||
s.maxID = id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Release frees the id for reuse.
|
|
||||||
func (s *Set) Release(id int64) {
|
|
||||||
s.free.Add(id)
|
|
||||||
s.used.Remove(id)
|
|
||||||
}
|
|
||||||
9
vendor/gonum.org/v1/gonum/graph/iterator/doc.go
generated
vendored
9
vendor/gonum.org/v1/gonum/graph/iterator/doc.go
generated
vendored
@@ -1,9 +0,0 @@
|
|||||||
// 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
131
vendor/gonum.org/v1/gonum/graph/iterator/edges.go
generated
vendored
@@ -1,131 +0,0 @@
|
|||||||
// 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
131
vendor/gonum.org/v1/gonum/graph/iterator/lines.go
generated
vendored
@@ -1,131 +0,0 @@
|
|||||||
// 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
|
|
||||||
}
|
|
||||||
180
vendor/gonum.org/v1/gonum/graph/iterator/nodes.go
generated
vendored
180
vendor/gonum.org/v1/gonum/graph/iterator/nodes.go
generated
vendored
@@ -1,180 +0,0 @@
|
|||||||
// 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 (
|
|
||||||
"reflect"
|
|
||||||
|
|
||||||
"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
|
|
||||||
}
|
|
||||||
|
|
||||||
// Nodes implements the graph.Nodes interfaces.
|
|
||||||
// The iteration order of Nodes is randomized.
|
|
||||||
type Nodes struct {
|
|
||||||
nodes reflect.Value
|
|
||||||
iter *reflect.MapIter
|
|
||||||
pos int
|
|
||||||
curr graph.Node
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewNodes returns a Nodes initialized with the provided nodes, a
|
|
||||||
// map of node IDs to graph.Nodes. No check is made that the keys
|
|
||||||
// match the graph.Node IDs, and the map keys are not used.
|
|
||||||
//
|
|
||||||
// Behavior of the Nodes is unspecified if nodes is mutated after
|
|
||||||
// the call the NewNodes.
|
|
||||||
func NewNodes(nodes map[int64]graph.Node) *Nodes {
|
|
||||||
rv := reflect.ValueOf(nodes)
|
|
||||||
return &Nodes{nodes: rv, iter: rv.MapRange()}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Len returns the remaining number of nodes to be iterated over.
|
|
||||||
func (n *Nodes) Len() int {
|
|
||||||
return n.nodes.Len() - n.pos
|
|
||||||
}
|
|
||||||
|
|
||||||
// Next returns whether the next call of Node will return a valid node.
|
|
||||||
func (n *Nodes) Next() bool {
|
|
||||||
if n.pos >= n.nodes.Len() {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
ok := n.iter.Next()
|
|
||||||
if ok {
|
|
||||||
n.pos++
|
|
||||||
n.curr = n.iter.Value().Interface().(graph.Node)
|
|
||||||
}
|
|
||||||
return ok
|
|
||||||
}
|
|
||||||
|
|
||||||
// Node returns the current node of the iterator. Next must have been
|
|
||||||
// called prior to a call to Node.
|
|
||||||
func (n *Nodes) Node() graph.Node {
|
|
||||||
return n.curr
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reset returns the iterator to its initial state.
|
|
||||||
func (n *Nodes) Reset() {
|
|
||||||
n.curr = nil
|
|
||||||
n.pos = 0
|
|
||||||
n.iter = n.nodes.MapRange()
|
|
||||||
}
|
|
||||||
198
vendor/gonum.org/v1/gonum/graph/multigraph.go
generated
vendored
198
vendor/gonum.org/v1/gonum/graph/multigraph.go
generated
vendored
@@ -1,198 +0,0 @@
|
|||||||
// Copyright ©2014 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
|
|
||||||
|
|
||||||
// Line is an edge in a multigraph. A Line returns an ID that must
|
|
||||||
// distinguish Lines sharing Node end points.
|
|
||||||
type Line interface {
|
|
||||||
// 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
|
|
||||||
}
|
|
||||||
|
|
||||||
// WeightedLine is a weighted multigraph edge.
|
|
||||||
type WeightedLine interface {
|
|
||||||
Line
|
|
||||||
Weight() float64
|
|
||||||
}
|
|
||||||
|
|
||||||
// Multigraph is a generalized multigraph.
|
|
||||||
type Multigraph interface {
|
|
||||||
// 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 must not return nil.
|
|
||||||
Nodes() Nodes
|
|
||||||
|
|
||||||
// From returns all nodes that can be reached directly
|
|
||||||
// from the node with the given ID.
|
|
||||||
//
|
|
||||||
// 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.
|
|
||||||
HasEdgeBetween(xid, yid int64) bool
|
|
||||||
|
|
||||||
// Lines returns the lines from u to v, 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.
|
|
||||||
//
|
|
||||||
// Lines must not return nil.
|
|
||||||
Lines(uid, vid int64) Lines
|
|
||||||
}
|
|
||||||
|
|
||||||
// WeightedMultigraph is a weighted multigraph.
|
|
||||||
type WeightedMultigraph interface {
|
|
||||||
Multigraph
|
|
||||||
|
|
||||||
// WeightedLines returns the weighted lines from u to v
|
|
||||||
// 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 must not return nil.
|
|
||||||
WeightedLines(uid, vid int64) WeightedLines
|
|
||||||
}
|
|
||||||
|
|
||||||
// UndirectedMultigraph is an undirected multigraph.
|
|
||||||
type UndirectedMultigraph interface {
|
|
||||||
Multigraph
|
|
||||||
|
|
||||||
// LinesBetween returns the lines between nodes x and y
|
|
||||||
// with IDs xid and yid.
|
|
||||||
//
|
|
||||||
// LinesBetween must not return nil.
|
|
||||||
LinesBetween(xid, yid int64) Lines
|
|
||||||
}
|
|
||||||
|
|
||||||
// WeightedUndirectedMultigraph is a weighted undirected multigraph.
|
|
||||||
type WeightedUndirectedMultigraph interface {
|
|
||||||
WeightedMultigraph
|
|
||||||
|
|
||||||
// WeightedLinesBetween returns the lines between nodes
|
|
||||||
// x and y with IDs xid and yid.
|
|
||||||
//
|
|
||||||
// WeightedLinesBetween must not return nil.
|
|
||||||
WeightedLinesBetween(xid, yid int64) WeightedLines
|
|
||||||
}
|
|
||||||
|
|
||||||
// DirectedMultigraph is a directed multigraph.
|
|
||||||
type DirectedMultigraph interface {
|
|
||||||
Multigraph
|
|
||||||
|
|
||||||
// HasEdgeFromTo returns whether an edge exists
|
|
||||||
// in the multigraph from u to v with IDs uid
|
|
||||||
// and vid.
|
|
||||||
HasEdgeFromTo(uid, vid int64) bool
|
|
||||||
|
|
||||||
// To returns all nodes that can reach directly
|
|
||||||
// to the node with the given ID.
|
|
||||||
//
|
|
||||||
// To must not return nil.
|
|
||||||
To(id int64) Nodes
|
|
||||||
}
|
|
||||||
|
|
||||||
// WeightedDirectedMultigraph is a weighted directed multigraph.
|
|
||||||
type WeightedDirectedMultigraph interface {
|
|
||||||
WeightedMultigraph
|
|
||||||
|
|
||||||
// HasEdgeFromTo returns whether an edge exists
|
|
||||||
// in the multigraph from u to v with IDs uid
|
|
||||||
// and vid.
|
|
||||||
HasEdgeFromTo(uid, vid int64) bool
|
|
||||||
|
|
||||||
// To returns all nodes that can reach directly
|
|
||||||
// to the node with the given ID.
|
|
||||||
//
|
|
||||||
// To must not return nil.
|
|
||||||
To(id int64) Nodes
|
|
||||||
}
|
|
||||||
|
|
||||||
// LineAdder is an interface for adding lines to a multigraph.
|
|
||||||
type LineAdder interface {
|
|
||||||
// NewLine returns a new Line from the source to the destination node.
|
|
||||||
NewLine(from, to Node) Line
|
|
||||||
|
|
||||||
// SetLine adds a Line from one node to another.
|
|
||||||
// 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)
|
|
||||||
}
|
|
||||||
|
|
||||||
// WeightedLineAdder is an interface for adding lines to a multigraph.
|
|
||||||
type WeightedLineAdder interface {
|
|
||||||
// NewWeightedLine returns a new WeightedLine from
|
|
||||||
// the source to the destination node.
|
|
||||||
NewWeightedLine(from, to Node, weight float64) WeightedLine
|
|
||||||
|
|
||||||
// SetWeightedLine adds a weighted line from one node
|
|
||||||
// to another. If the multigraph supports node addition
|
|
||||||
// the nodes will be added if they do not exist,
|
|
||||||
// otherwise SetWeightedLine will panic.
|
|
||||||
// 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.
|
|
||||||
type LineRemover interface {
|
|
||||||
// RemoveLine removes the line with the given end
|
|
||||||
// and line IDs, leaving the terminal nodes. If
|
|
||||||
// the line does not exist it is a no-op.
|
|
||||||
RemoveLine(fid, tid, id int64)
|
|
||||||
}
|
|
||||||
|
|
||||||
// MultigraphBuilder is a multigraph that can have nodes and lines added.
|
|
||||||
type MultigraphBuilder interface {
|
|
||||||
NodeAdder
|
|
||||||
LineAdder
|
|
||||||
}
|
|
||||||
|
|
||||||
// WeightedMultigraphBuilder is a multigraph that can have nodes and weighted lines added.
|
|
||||||
type WeightedMultigraphBuilder interface {
|
|
||||||
NodeAdder
|
|
||||||
WeightedLineAdder
|
|
||||||
}
|
|
||||||
|
|
||||||
// UndirectedMultgraphBuilder is an undirected multigraph builder.
|
|
||||||
type UndirectedMultigraphBuilder interface {
|
|
||||||
UndirectedMultigraph
|
|
||||||
MultigraphBuilder
|
|
||||||
}
|
|
||||||
|
|
||||||
// UndirectedWeightedMultigraphBuilder is an undirected weighted multigraph builder.
|
|
||||||
type UndirectedWeightedMultigraphBuilder interface {
|
|
||||||
UndirectedMultigraph
|
|
||||||
WeightedMultigraphBuilder
|
|
||||||
}
|
|
||||||
|
|
||||||
// DirectedMultigraphBuilder is a directed multigraph builder.
|
|
||||||
type DirectedMultigraphBuilder interface {
|
|
||||||
DirectedMultigraph
|
|
||||||
MultigraphBuilder
|
|
||||||
}
|
|
||||||
|
|
||||||
// DirectedWeightedMultigraphBuilder is a directed weighted multigraph builder.
|
|
||||||
type DirectedWeightedMultigraphBuilder interface {
|
|
||||||
DirectedMultigraph
|
|
||||||
WeightedMultigraphBuilder
|
|
||||||
}
|
|
||||||
300
vendor/gonum.org/v1/gonum/graph/nodes_edges.go
generated
vendored
300
vendor/gonum.org/v1/gonum/graph/nodes_edges.go
generated
vendored
@@ -1,300 +0,0 @@
|
|||||||
// 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 }
|
|
||||||
301
vendor/gonum.org/v1/gonum/graph/simple/dense_directed_matrix.go
generated
vendored
301
vendor/gonum.org/v1/gonum/graph/simple/dense_directed_matrix.go
generated
vendored
@@ -1,301 +0,0 @@
|
|||||||
// Copyright ©2014 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 simple
|
|
||||||
|
|
||||||
import (
|
|
||||||
"sort"
|
|
||||||
|
|
||||||
"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
|
|
||||||
// the graph are not recoverable.
|
|
||||||
type DirectedMatrix struct {
|
|
||||||
mat *mat.Dense
|
|
||||||
nodes []graph.Node
|
|
||||||
|
|
||||||
self float64
|
|
||||||
absent float64
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewDirectedMatrix creates a directed dense graph with n nodes.
|
|
||||||
// All edges are initialized with the weight given by init. The self parameter
|
|
||||||
// specifies the cost of self connection, and absent specifies the weight
|
|
||||||
// returned for absent edges.
|
|
||||||
func NewDirectedMatrix(n int, init, self, absent float64) *DirectedMatrix {
|
|
||||||
matrix := make([]float64, n*n)
|
|
||||||
if init != 0 {
|
|
||||||
for i := range matrix {
|
|
||||||
matrix[i] = init
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for i := 0; i < len(matrix); i += n + 1 {
|
|
||||||
matrix[i] = self
|
|
||||||
}
|
|
||||||
return &DirectedMatrix{
|
|
||||||
mat: mat.NewDense(n, n, matrix),
|
|
||||||
self: self,
|
|
||||||
absent: absent,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewDirectedMatrixFrom creates a directed dense graph with the given nodes.
|
|
||||||
// The IDs of the nodes must be contiguous from 0 to len(nodes)-1, but may
|
|
||||||
// be in any order. If IDs are not contiguous NewDirectedMatrixFrom will panic.
|
|
||||||
// All edges are initialized with the weight given by init. The self parameter
|
|
||||||
// specifies the cost of self connection, and absent specifies the weight
|
|
||||||
// returned for absent edges.
|
|
||||||
func NewDirectedMatrixFrom(nodes []graph.Node, init, self, absent float64) *DirectedMatrix {
|
|
||||||
sort.Sort(ordered.ByID(nodes))
|
|
||||||
for i, n := range nodes {
|
|
||||||
if int64(i) != n.ID() {
|
|
||||||
panic("simple: non-contiguous node IDs")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
g := NewDirectedMatrix(len(nodes), init, self, absent)
|
|
||||||
g.nodes = nodes
|
|
||||||
return g
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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.Edges {
|
|
||||||
var edges []graph.Edge
|
|
||||||
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.NewOrderedEdges(edges)
|
|
||||||
}
|
|
||||||
|
|
||||||
// From returns all nodes in g that can be reached directly from n.
|
|
||||||
func (g *DirectedMatrix) From(id int64) graph.Nodes {
|
|
||||||
if !g.has(id) {
|
|
||||||
return graph.Empty
|
|
||||||
}
|
|
||||||
var nodes []graph.Node
|
|
||||||
_, c := g.mat.Dims()
|
|
||||||
for j := 0; j < c; j++ {
|
|
||||||
if int64(j) == id {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
// id is not greater than maximum int by this point.
|
|
||||||
if !isSame(g.mat.At(int(id), j), g.absent) {
|
|
||||||
nodes = append(nodes, g.Node(int64(j)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(nodes) == 0 {
|
|
||||||
return graph.Empty
|
|
||||||
}
|
|
||||||
return iterator.NewOrderedNodes(nodes)
|
|
||||||
}
|
|
||||||
|
|
||||||
// HasEdgeBetween returns whether an edge exists between nodes x and y without
|
|
||||||
// considering direction.
|
|
||||||
func (g *DirectedMatrix) HasEdgeBetween(xid, yid int64) bool {
|
|
||||||
if !g.has(xid) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if !g.has(yid) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
// xid and yid are not greater than maximum int by this point.
|
|
||||||
return xid != yid && (!isSame(g.mat.At(int(xid), int(yid)), g.absent) || !isSame(g.mat.At(int(yid), int(xid)), g.absent))
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if !g.has(vid) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
// uid and vid are not greater than maximum int by this point.
|
|
||||||
return uid != vid && !isSame(g.mat.At(int(uid), int(vid)), g.absent)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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]
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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)
|
|
||||||
}
|
|
||||||
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
|
|
||||||
// nodes. If the edge does not exist it is a no-op.
|
|
||||||
func (g *DirectedMatrix) RemoveEdge(fid, tid int64) {
|
|
||||||
if !g.has(fid) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if !g.has(tid) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// fid and tid are not greater than maximum int by this point.
|
|
||||||
g.mat.Set(int(fid), int(tid), g.absent)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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")
|
|
||||||
}
|
|
||||||
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(i, int(id)), g.absent) {
|
|
||||||
nodes = append(nodes, g.Node(int64(i)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(nodes) == 0 {
|
|
||||||
return graph.Empty
|
|
||||||
}
|
|
||||||
return iterator.NewOrderedNodes(nodes)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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)
|
|
||||||
}
|
|
||||||
268
vendor/gonum.org/v1/gonum/graph/simple/dense_undirected_matrix.go
generated
vendored
268
vendor/gonum.org/v1/gonum/graph/simple/dense_undirected_matrix.go
generated
vendored
@@ -1,268 +0,0 @@
|
|||||||
// Copyright ©2014 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 simple
|
|
||||||
|
|
||||||
import (
|
|
||||||
"sort"
|
|
||||||
|
|
||||||
"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
|
|
||||||
// the graph are not recoverable.
|
|
||||||
type UndirectedMatrix struct {
|
|
||||||
mat *mat.SymDense
|
|
||||||
nodes []graph.Node
|
|
||||||
|
|
||||||
self float64
|
|
||||||
absent float64
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewUndirectedMatrix creates an undirected dense graph with n nodes.
|
|
||||||
// All edges are initialized with the weight given by init. The self parameter
|
|
||||||
// specifies the cost of self connection, and absent specifies the weight
|
|
||||||
// returned for absent edges.
|
|
||||||
func NewUndirectedMatrix(n int, init, self, absent float64) *UndirectedMatrix {
|
|
||||||
matrix := make([]float64, n*n)
|
|
||||||
if init != 0 {
|
|
||||||
for i := range matrix {
|
|
||||||
matrix[i] = init
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for i := 0; i < len(matrix); i += n + 1 {
|
|
||||||
matrix[i] = self
|
|
||||||
}
|
|
||||||
return &UndirectedMatrix{
|
|
||||||
mat: mat.NewSymDense(n, matrix),
|
|
||||||
self: self,
|
|
||||||
absent: absent,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewUndirectedMatrixFrom creates an undirected dense graph with the given nodes.
|
|
||||||
// The IDs of the nodes must be contiguous from 0 to len(nodes)-1, but may
|
|
||||||
// be in any order. If IDs are not contiguous NewUndirectedMatrixFrom will panic.
|
|
||||||
// All edges are initialized with the weight given by init. The self parameter
|
|
||||||
// specifies the cost of self connection, and absent specifies the weight
|
|
||||||
// returned for absent edges.
|
|
||||||
func NewUndirectedMatrixFrom(nodes []graph.Node, init, self, absent float64) *UndirectedMatrix {
|
|
||||||
sort.Sort(ordered.ByID(nodes))
|
|
||||||
for i, n := range nodes {
|
|
||||||
if int64(i) != n.ID() {
|
|
||||||
panic("simple: non-contiguous node IDs")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
g := NewUndirectedMatrix(len(nodes), init, self, absent)
|
|
||||||
g.nodes = nodes
|
|
||||||
return g
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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.Edges {
|
|
||||||
var edges []graph.Edge
|
|
||||||
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.NewOrderedEdges(edges)
|
|
||||||
}
|
|
||||||
|
|
||||||
// From returns all nodes in g that can be reached directly from n.
|
|
||||||
func (g *UndirectedMatrix) From(id int64) graph.Nodes {
|
|
||||||
if !g.has(id) {
|
|
||||||
return graph.Empty
|
|
||||||
}
|
|
||||||
var nodes []graph.Node
|
|
||||||
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) {
|
|
||||||
nodes = append(nodes, g.Node(int64(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 *UndirectedMatrix) HasEdgeBetween(uid, vid int64) bool {
|
|
||||||
if !g.has(uid) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if !g.has(vid) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
// uid and vid are not greater than maximum int by this point.
|
|
||||||
return uid != vid && !isSame(g.mat.At(int(uid), int(vid)), g.absent)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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
|
|
||||||
}
|
|
||||||
if g.nodes == nil {
|
|
||||||
return Node(id)
|
|
||||||
}
|
|
||||||
return g.nodes[id]
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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)
|
|
||||||
}
|
|
||||||
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
|
|
||||||
// nodes. If the edge does not exist it is a no-op.
|
|
||||||
func (g *UndirectedMatrix) RemoveEdge(fid, tid int64) {
|
|
||||||
if !g.has(fid) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if !g.has(tid) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// fid and tid are not greater than maximum int by this point.
|
|
||||||
g.mat.SetSym(int(fid), int(tid), g.absent)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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)
|
|
||||||
}
|
|
||||||
241
vendor/gonum.org/v1/gonum/graph/simple/directed.go
generated
vendored
241
vendor/gonum.org/v1/gonum/graph/simple/directed.go
generated
vendored
@@ -1,241 +0,0 @@
|
|||||||
// Copyright ©2014 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 simple
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"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.
|
|
||||||
type DirectedGraph struct {
|
|
||||||
nodes map[int64]graph.Node
|
|
||||||
from map[int64]map[int64]graph.Edge
|
|
||||||
to map[int64]map[int64]graph.Edge
|
|
||||||
|
|
||||||
nodeIDs uid.Set
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewDirectedGraph returns a DirectedGraph.
|
|
||||||
func NewDirectedGraph() *DirectedGraph {
|
|
||||||
return &DirectedGraph{
|
|
||||||
nodes: make(map[int64]graph.Node),
|
|
||||||
from: make(map[int64]map[int64]graph.Edge),
|
|
||||||
to: make(map[int64]map[int64]graph.Edge),
|
|
||||||
|
|
||||||
nodeIDs: uid.NewSet(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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.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 {
|
|
||||||
if len(g.nodes) == 0 {
|
|
||||||
return Node(0)
|
|
||||||
}
|
|
||||||
if int64(len(g.nodes)) == uid.Max {
|
|
||||||
panic("simple: cannot allocate node: no slot")
|
|
||||||
}
|
|
||||||
return Node(g.nodeIDs.NewID())
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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
|
|
||||||
}
|
|
||||||
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
|
|
||||||
// to it. If the node is not in the graph it is a no-op.
|
|
||||||
func (g *DirectedGraph) RemoveNode(id int64) {
|
|
||||||
if _, ok := g.nodes[id]; !ok {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
delete(g.nodes, id)
|
|
||||||
|
|
||||||
for from := range g.from[id] {
|
|
||||||
delete(g.to[from], id)
|
|
||||||
}
|
|
||||||
delete(g.from, id)
|
|
||||||
|
|
||||||
for to := range g.to[id] {
|
|
||||||
delete(g.from[to], id)
|
|
||||||
}
|
|
||||||
delete(g.to, id)
|
|
||||||
|
|
||||||
g.nodeIDs.Release(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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 (
|
|
||||||
from = e.From()
|
|
||||||
fid = from.ID()
|
|
||||||
to = e.To()
|
|
||||||
tid = to.ID()
|
|
||||||
)
|
|
||||||
|
|
||||||
if fid == tid {
|
|
||||||
panic("simple: adding self edge")
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, ok := g.nodes[fid]; !ok {
|
|
||||||
g.AddNode(from)
|
|
||||||
} else {
|
|
||||||
g.nodes[fid] = from
|
|
||||||
}
|
|
||||||
if _, ok := g.nodes[tid]; !ok {
|
|
||||||
g.AddNode(to)
|
|
||||||
} else {
|
|
||||||
g.nodes[tid] = to
|
|
||||||
}
|
|
||||||
|
|
||||||
if fm, ok := g.from[fid]; ok {
|
|
||||||
fm[tid] = e
|
|
||||||
} else {
|
|
||||||
g.from[fid] = map[int64]graph.Edge{tid: e}
|
|
||||||
}
|
|
||||||
if tm, ok := g.to[tid]; ok {
|
|
||||||
tm[fid] = e
|
|
||||||
} else {
|
|
||||||
g.to[tid] = map[int64]graph.Edge{fid: e}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// To returns all nodes in g that can reach directly to n.
|
|
||||||
func (g *DirectedGraph) To(id int64) graph.Nodes {
|
|
||||||
if _, ok := g.to[id]; !ok {
|
|
||||||
return graph.Empty
|
|
||||||
}
|
|
||||||
|
|
||||||
to := make([]graph.Node, len(g.to[id]))
|
|
||||||
i := 0
|
|
||||||
for uid := range g.to[id] {
|
|
||||||
to[i] = g.nodes[uid]
|
|
||||||
i++
|
|
||||||
}
|
|
||||||
if len(to) == 0 {
|
|
||||||
return graph.Empty
|
|
||||||
}
|
|
||||||
return iterator.NewOrderedNodes(to)
|
|
||||||
}
|
|
||||||
9
vendor/gonum.org/v1/gonum/graph/simple/doc.go
generated
vendored
9
vendor/gonum.org/v1/gonum/graph/simple/doc.go
generated
vendored
@@ -1,9 +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 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"
|
|
||||||
72
vendor/gonum.org/v1/gonum/graph/simple/simple.go
generated
vendored
72
vendor/gonum.org/v1/gonum/graph/simple/simple.go
generated
vendored
@@ -1,72 +0,0 @@
|
|||||||
// Copyright ©2014 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 simple
|
|
||||||
|
|
||||||
import (
|
|
||||||
"math"
|
|
||||||
|
|
||||||
"gonum.org/v1/gonum/graph"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Node is a simple graph node.
|
|
||||||
type Node int64
|
|
||||||
|
|
||||||
// ID returns the ID number of the node.
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
// From returns the from-node of the edge.
|
|
||||||
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
|
|
||||||
W float64
|
|
||||||
}
|
|
||||||
|
|
||||||
// From returns the from-node of the edge.
|
|
||||||
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 }
|
|
||||||
|
|
||||||
// isSame returns whether two float64 values are the same where NaN values
|
|
||||||
// are equalable.
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user