mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-10-31 02:08:13 +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/time v0.0.0-20220210224613-90d013bbcef8 | ||||
| 	golang.org/x/tools v0.1.12 | ||||
| 	gonum.org/v1/gonum v0.6.2 | ||||
| 	google.golang.org/api v0.60.0 | ||||
| 	google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21 | ||||
| 	google.golang.org/grpc v1.49.0 | ||||
| @@ -235,10 +234,8 @@ require ( | ||||
| 	go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 // indirect | ||||
| 	go.uber.org/atomic v1.7.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/text v0.3.7 // indirect | ||||
| 	gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e // indirect | ||||
| 	google.golang.org/appengine v1.6.7 // indirect | ||||
| 	gopkg.in/inf.v0 v0.9.1 // 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/bigquery => cloud.google.com/go/bigquery v1.8.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/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 | ||||
| @@ -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/tracing => github.com/Azure/go-autorest/tracing v0.6.0 | ||||
| 	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/JeffAshton/win_pdh => github.com/JeffAshton/win_pdh v0.0.0-20161109143554-76bb4ee9f0ab | ||||
| 	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/PuerkitoBio/purell => github.com/PuerkitoBio/purell v1.1.1 | ||||
| 	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/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 | ||||
| @@ -340,7 +334,6 @@ replace ( | ||||
| 	github.com/fatih/camelcase => github.com/fatih/camelcase v1.0.0 | ||||
| 	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/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/frankban/quicktest => github.com/frankban/quicktest v1.11.3 | ||||
| 	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/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-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/log => github.com/go-kit/log v0.2.0 | ||||
| 	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/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/freetype => github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 | ||||
| 	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/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/json-iterator/go => github.com/json-iterator/go v1.1.12 | ||||
| 	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/kisielk/errcheck => github.com/kisielk/errcheck v1.5.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/common => github.com/prometheus/common v0.37.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/rogpeppe/fastuuid => github.com/rogpeppe/fastuuid v1.2.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/zap => go.uber.org/zap v1.19.0 | ||||
| 	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/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/net => golang.org/x/net v0.0.0-20220722155237-a158d28d115b | ||||
| 	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/tools => golang.org/x/tools v0.1.12 | ||||
| 	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/appengine => google.golang.org/appengine v1.6.7 | ||||
| 	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/system-validators => k8s.io/system-validators v1.8.0 | ||||
| 	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/json => sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 | ||||
| 	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/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= | ||||
| 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/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= | ||||
| 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/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= | ||||
| 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/go.mod h1:FNj4KYEAAHfYu68kRYolGoxkaJn+6mdEsaM12VTwuI0= | ||||
| 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/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I= | ||||
| 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/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= | ||||
| @@ -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/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= | ||||
| 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/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= | ||||
| 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/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-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/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= | ||||
| 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/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/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/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= | ||||
| 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/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= | ||||
| 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/go.mod h1:j4mkqPuvaLI8mp1DroR3P6ad7cyYd4c1qeJ3RV7ULlk= | ||||
| 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/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo= | ||||
| 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/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= | ||||
| 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= | ||||
| 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/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/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/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= | ||||
| 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/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= | ||||
| 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/go.mod h1:d7rl65NZAkEQ90JFzqBjcRq1TVeG5ZoGV3sSpEnnVb4= | ||||
| 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/utils v0.0.0-20220922133306-665eaaec4324 h1:i+xdFemcSNuJvIfBlaYuXgRondKxK4z4prVPKzEaelI= | ||||
| 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/go.mod h1:fEO7lRTdivWO2qYVCVG7dEADOMo/MLDCVr8So2g88Uw= | ||||
| sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k= | ||||
|   | ||||
| @@ -17,22 +17,20 @@ limitations under the License. | ||||
| package garbagecollector | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| 	"net/http" | ||||
| 	"sort" | ||||
| 	"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" | ||||
| 	"k8s.io/apimachinery/pkg/runtime/schema" | ||||
| 	"k8s.io/apimachinery/pkg/types" | ||||
| 	utilruntime "k8s.io/apimachinery/pkg/util/runtime" | ||||
| ) | ||||
|  | ||||
| type gonumVertex struct { | ||||
| type dotVertex struct { | ||||
| 	uid                types.UID | ||||
| 	gvk                schema.GroupVersionKind | ||||
| 	namespace          string | ||||
| @@ -41,14 +39,25 @@ type gonumVertex struct { | ||||
| 	beingDeleted       bool | ||||
| 	deletingDependents bool | ||||
| 	virtual            bool | ||||
| 	vertexID           int64 | ||||
| } | ||||
|  | ||||
| func (v *gonumVertex) ID() int64 { | ||||
| 	return v.vertexID | ||||
| func (v *dotVertex) MarshalDOT(w io.Writer) error { | ||||
| 	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 | ||||
| 	if len(v.gvk.Group) > 0 { | ||||
| 		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) | ||||
| } | ||||
|  | ||||
| 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 | ||||
| 	if len(v.gvk.Group) > 0 { | ||||
| 		kubectlString = kubectlString + "." + v.gvk.Group | ||||
| @@ -106,30 +120,30 @@ namespace=%v | ||||
| 		label = label + conditionString + "\n" | ||||
| 	} | ||||
|  | ||||
| 	return []encoding.Attribute{ | ||||
| 		{Key: "label", Value: fmt.Sprintf(`"%v"`, label)}, | ||||
| 	return []attribute{ | ||||
| 		{Key: "label", Value: label}, | ||||
| 		// 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: "version", Value: fmt.Sprintf(`"%v"`, v.gvk.Version)}, | ||||
| 		{Key: "kind", Value: fmt.Sprintf(`"%v"`, v.gvk.Kind)}, | ||||
| 		{Key: "namespace", Value: fmt.Sprintf(`"%v"`, v.namespace)}, | ||||
| 		{Key: "name", Value: fmt.Sprintf(`"%v"`, v.name)}, | ||||
| 		{Key: "uid", Value: fmt.Sprintf(`"%v"`, v.uid)}, | ||||
| 		{Key: "missing", Value: fmt.Sprintf(`"%v"`, v.missingFromGraph)}, | ||||
| 		{Key: "beingDeleted", Value: fmt.Sprintf(`"%v"`, v.beingDeleted)}, | ||||
| 		{Key: "deletingDependents", Value: fmt.Sprintf(`"%v"`, v.deletingDependents)}, | ||||
| 		{Key: "virtual", Value: fmt.Sprintf(`"%v"`, v.virtual)}, | ||||
| 		{Key: "group", Value: v.gvk.Group}, | ||||
| 		{Key: "version", Value: v.gvk.Version}, | ||||
| 		{Key: "kind", Value: v.gvk.Kind}, | ||||
| 		{Key: "namespace", Value: v.namespace}, | ||||
| 		{Key: "name", Value: v.name}, | ||||
| 		{Key: "uid", Value: string(v.uid)}, | ||||
| 		{Key: "missing", Value: fmt.Sprintf(`%v`, v.missingFromGraph)}, | ||||
| 		{Key: "beingDeleted", Value: fmt.Sprintf(`%v`, v.beingDeleted)}, | ||||
| 		{Key: "deletingDependents", Value: fmt.Sprintf(`%v`, v.deletingDependents)}, | ||||
| 		{Key: "virtual", Value: fmt.Sprintf(`%v`, v.virtual)}, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // NewGonumVertex creates a new gonumVertex. | ||||
| func NewGonumVertex(node *node, nodeID int64) *gonumVertex { | ||||
| // NewDOTVertex creates a new dotVertex. | ||||
| func NewDOTVertex(node *node) *dotVertex { | ||||
| 	gv, err := schema.ParseGroupVersion(node.identity.APIVersion) | ||||
| 	if err != nil { | ||||
| 		// this indicates a bad data serialization that should be prevented during storage of the API | ||||
| 		utilruntime.HandleError(err) | ||||
| 	} | ||||
| 	return &gonumVertex{ | ||||
| 	return &dotVertex{ | ||||
| 		uid:                node.identity.UID, | ||||
| 		gvk:                gv.WithKind(node.identity.Kind), | ||||
| 		namespace:          node.identity.Namespace, | ||||
| @@ -137,36 +151,46 @@ func NewGonumVertex(node *node, nodeID int64) *gonumVertex { | ||||
| 		beingDeleted:       node.beingDeleted, | ||||
| 		deletingDependents: node.deletingDependents, | ||||
| 		virtual:            node.virtual, | ||||
| 		vertexID:           nodeID, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // NewMissingGonumVertex creates a new gonumVertex. | ||||
| func NewMissingGonumVertex(ownerRef metav1.OwnerReference, nodeID int64) *gonumVertex { | ||||
| // NewMissingdotVertex creates a new dotVertex. | ||||
| func NewMissingdotVertex(ownerRef metav1.OwnerReference) *dotVertex { | ||||
| 	gv, err := schema.ParseGroupVersion(ownerRef.APIVersion) | ||||
| 	if err != nil { | ||||
| 		// this indicates a bad data serialization that should be prevented during storage of the API | ||||
| 		utilruntime.HandleError(err) | ||||
| 	} | ||||
| 	return &gonumVertex{ | ||||
| 	return &dotVertex{ | ||||
| 		uid:              ownerRef.UID, | ||||
| 		gvk:              gv.WithKind(ownerRef.Kind), | ||||
| 		name:             ownerRef.Name, | ||||
| 		missingFromGraph: true, | ||||
| 		vertexID:         nodeID, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (m *concurrentUIDToNode) ToGonumGraph() graph.Directed { | ||||
| func (m *concurrentUIDToNode) ToDOTNodesAndEdges() ([]*dotVertex, []dotEdge) { | ||||
| 	m.uidToNodeLock.Lock() | ||||
| 	defer m.uidToNodeLock.Unlock() | ||||
|  | ||||
| 	return toGonumGraph(m.uidToNode) | ||||
| 	return toDOTNodesAndEdges(m.uidToNode) | ||||
| } | ||||
|  | ||||
| func toGonumGraph(uidToNode map[types.UID]*node) graph.Directed { | ||||
| 	uidToVertex := map[types.UID]*gonumVertex{} | ||||
| 	graphBuilder := simple.NewDirectedGraph() | ||||
| type dotEdge struct { | ||||
| 	F types.UID | ||||
| 	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. | ||||
| 	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 { | ||||
| 			continue | ||||
| 		} | ||||
| 		vertex := NewGonumVertex(node, graphBuilder.NewNode().ID()) | ||||
| 		vertex := NewDOTVertex(node) | ||||
| 		uidToVertex[node.identity.UID] = vertex | ||||
| 		graphBuilder.AddNode(vertex) | ||||
| 		nodes = append(nodes, vertex) | ||||
| 	} | ||||
| 	for _, node := range uidToNode { | ||||
| 		currVertex := uidToVertex[node.identity.UID] | ||||
| 		for _, ownerRef := range node.owners { | ||||
| 			currOwnerVertex, ok := uidToVertex[ownerRef.UID] | ||||
| 			if !ok { | ||||
| 				currOwnerVertex = NewMissingGonumVertex(ownerRef, graphBuilder.NewNode().ID()) | ||||
| 				currOwnerVertex = NewMissingdotVertex(ownerRef) | ||||
| 				uidToVertex[node.identity.UID] = currOwnerVertex | ||||
| 				graphBuilder.AddNode(currOwnerVertex) | ||||
| 				nodes = append(nodes, currOwnerVertex) | ||||
| 			} | ||||
| 			graphBuilder.SetEdge(simple.Edge{ | ||||
| 				F: currVertex, | ||||
| 				T: currOwnerVertex, | ||||
| 			}) | ||||
|  | ||||
| 			edges = append(edges, dotEdge{F: currVertex.uid, T: currOwnerVertex.uid}) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	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() | ||||
| 	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...) | ||||
| 	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. | ||||
| @@ -253,32 +281,64 @@ type debugHTTPHandler struct { | ||||
| 	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) { | ||||
| 	if req.URL.Path != "/graph" { | ||||
| 		http.Error(w, "", http.StatusNotFound) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	var graph graph.Directed | ||||
| 	var nodes []*dotVertex | ||||
| 	var edges []dotEdge | ||||
| 	if uidStrings := req.URL.Query()["uid"]; len(uidStrings) > 0 { | ||||
| 		uids := []types.UID{} | ||||
| 		for _, uidString := range uidStrings { | ||||
| 			uids = append(uids, types.UID(uidString)) | ||||
| 		} | ||||
| 		graph = h.controller.dependencyGraphBuilder.uidToNode.ToGonumGraphForObj(uids...) | ||||
| 		nodes, edges = h.controller.dependencyGraphBuilder.uidToNode.ToDOTNodesAndEdgesForObj(uids...) | ||||
|  | ||||
| 	} else { | ||||
| 		graph = h.controller.dependencyGraphBuilder.uidToNode.ToGonumGraph() | ||||
| 		nodes, edges = h.controller.dependencyGraphBuilder.uidToNode.ToDOTNodesAndEdges() | ||||
| 	} | ||||
|  | ||||
| 	data, err := dot.Marshal(graph, "full", "", "  ") | ||||
| 	if err != nil { | ||||
| 	b := bytes.NewBuffer(nil) | ||||
| 	if err := marshalDOT(b, nodes, edges); err != nil { | ||||
| 		http.Error(w, err.Error(), http.StatusInternalServerError) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	w.Header().Set("Content-Type", "text/vnd.graphviz") | ||||
| 	w.Header().Set("X-Content-Type-Options", "nosniff") | ||||
| 	w.Write(data) | ||||
| 	w.Write(b.Bytes()) | ||||
| 	w.WriteHeader(http.StatusOK) | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -17,12 +17,13 @@ limitations under the License. | ||||
| package garbagecollector | ||||
|  | ||||
| import ( | ||||
| 	"sort" | ||||
| 	"bytes" | ||||
| 	"os" | ||||
| 	"path/filepath" | ||||
| 	"testing" | ||||
|  | ||||
| 	"github.com/davecgh/go-spew/spew" | ||||
| 	"gonum.org/v1/gonum/graph" | ||||
| 	"gonum.org/v1/gonum/graph/simple" | ||||
| 	"github.com/google/go-cmp/cmp" | ||||
|  | ||||
| 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||
| 	"k8s.io/apimachinery/pkg/types" | ||||
| @@ -116,11 +117,12 @@ var ( | ||||
| 	} | ||||
| ) | ||||
|  | ||||
| func TestToGonumGraph(t *testing.T) { | ||||
| func TestToDOTGraph(t *testing.T) { | ||||
| 	tests := []struct { | ||||
| 		name      string | ||||
| 		uidToNode map[types.UID]*node | ||||
| 		expect    graph.Directed | ||||
| 		name        string | ||||
| 		uidToNode   map[types.UID]*node | ||||
| 		expectNodes []*dotVertex | ||||
| 		expectEdges []dotEdge | ||||
| 	}{ | ||||
| 		{ | ||||
| 			name: "simple", | ||||
| @@ -129,24 +131,15 @@ func TestToGonumGraph(t *testing.T) { | ||||
| 				types.UID("bravo"):   bravoNode(), | ||||
| 				types.UID("charlie"): charlieNode(), | ||||
| 			}, | ||||
| 			expect: func() graph.Directed { | ||||
| 				graphBuilder := simple.NewDirectedGraph() | ||||
| 				alphaVertex := NewGonumVertex(alphaNode(), graphBuilder.NewNode().ID()) | ||||
| 				graphBuilder.AddNode(alphaVertex) | ||||
| 				bravoVertex := NewGonumVertex(bravoNode(), graphBuilder.NewNode().ID()) | ||||
| 				graphBuilder.AddNode(bravoVertex) | ||||
| 				charlieVertex := NewGonumVertex(charlieNode(), graphBuilder.NewNode().ID()) | ||||
| 				graphBuilder.AddNode(charlieVertex) | ||||
| 				graphBuilder.SetEdge(simple.Edge{ | ||||
| 					F: alphaVertex, | ||||
| 					T: bravoVertex, | ||||
| 				}) | ||||
| 				graphBuilder.SetEdge(simple.Edge{ | ||||
| 					F: alphaVertex, | ||||
| 					T: charlieVertex, | ||||
| 				}) | ||||
| 				return graphBuilder | ||||
| 			}(), | ||||
| 			expectNodes: []*dotVertex{ | ||||
| 				NewDOTVertex(alphaNode()), | ||||
| 				NewDOTVertex(bravoNode()), | ||||
| 				NewDOTVertex(charlieNode()), | ||||
| 			}, | ||||
| 			expectEdges: []dotEdge{ | ||||
| 				{F: types.UID("alpha"), T: types.UID("bravo")}, | ||||
| 				{F: types.UID("alpha"), T: types.UID("charlie")}, | ||||
| 			}, | ||||
| 		}, | ||||
| 		{ | ||||
| 			name: "missing", // synthetic vertex created | ||||
| @@ -154,24 +147,15 @@ func TestToGonumGraph(t *testing.T) { | ||||
| 				types.UID("alpha"):   alphaNode(), | ||||
| 				types.UID("charlie"): charlieNode(), | ||||
| 			}, | ||||
| 			expect: func() graph.Directed { | ||||
| 				graphBuilder := simple.NewDirectedGraph() | ||||
| 				alphaVertex := NewGonumVertex(alphaNode(), graphBuilder.NewNode().ID()) | ||||
| 				graphBuilder.AddNode(alphaVertex) | ||||
| 				bravoVertex := NewGonumVertex(bravoNode(), graphBuilder.NewNode().ID()) | ||||
| 				graphBuilder.AddNode(bravoVertex) | ||||
| 				charlieVertex := NewGonumVertex(charlieNode(), graphBuilder.NewNode().ID()) | ||||
| 				graphBuilder.AddNode(charlieVertex) | ||||
| 				graphBuilder.SetEdge(simple.Edge{ | ||||
| 					F: alphaVertex, | ||||
| 					T: bravoVertex, | ||||
| 				}) | ||||
| 				graphBuilder.SetEdge(simple.Edge{ | ||||
| 					F: alphaVertex, | ||||
| 					T: charlieVertex, | ||||
| 				}) | ||||
| 				return graphBuilder | ||||
| 			}(), | ||||
| 			expectNodes: []*dotVertex{ | ||||
| 				NewDOTVertex(alphaNode()), | ||||
| 				NewDOTVertex(bravoNode()), | ||||
| 				NewDOTVertex(charlieNode()), | ||||
| 			}, | ||||
| 			expectEdges: []dotEdge{ | ||||
| 				{F: types.UID("alpha"), T: types.UID("bravo")}, | ||||
| 				{F: types.UID("alpha"), T: types.UID("charlie")}, | ||||
| 			}, | ||||
| 		}, | ||||
| 		{ | ||||
| 			name: "drop-no-ref", | ||||
| @@ -181,24 +165,15 @@ func TestToGonumGraph(t *testing.T) { | ||||
| 				types.UID("charlie"): charlieNode(), | ||||
| 				types.UID("echo"):    echoNode(), | ||||
| 			}, | ||||
| 			expect: func() graph.Directed { | ||||
| 				graphBuilder := simple.NewDirectedGraph() | ||||
| 				alphaVertex := NewGonumVertex(alphaNode(), graphBuilder.NewNode().ID()) | ||||
| 				graphBuilder.AddNode(alphaVertex) | ||||
| 				bravoVertex := NewGonumVertex(bravoNode(), graphBuilder.NewNode().ID()) | ||||
| 				graphBuilder.AddNode(bravoVertex) | ||||
| 				charlieVertex := NewGonumVertex(charlieNode(), graphBuilder.NewNode().ID()) | ||||
| 				graphBuilder.AddNode(charlieVertex) | ||||
| 				graphBuilder.SetEdge(simple.Edge{ | ||||
| 					F: alphaVertex, | ||||
| 					T: bravoVertex, | ||||
| 				}) | ||||
| 				graphBuilder.SetEdge(simple.Edge{ | ||||
| 					F: alphaVertex, | ||||
| 					T: charlieVertex, | ||||
| 				}) | ||||
| 				return graphBuilder | ||||
| 			}(), | ||||
| 			expectNodes: []*dotVertex{ | ||||
| 				NewDOTVertex(alphaNode()), | ||||
| 				NewDOTVertex(bravoNode()), | ||||
| 				NewDOTVertex(charlieNode()), | ||||
| 			}, | ||||
| 			expectEdges: []dotEdge{ | ||||
| 				{F: types.UID("alpha"), T: types.UID("bravo")}, | ||||
| 				{F: types.UID("alpha"), T: types.UID("charlie")}, | ||||
| 			}, | ||||
| 		}, | ||||
| 		{ | ||||
| 			name: "two-chains", | ||||
| @@ -210,59 +185,38 @@ func TestToGonumGraph(t *testing.T) { | ||||
| 				types.UID("foxtrot"): foxtrotNode(), | ||||
| 				types.UID("golf"):    golfNode(), | ||||
| 			}, | ||||
| 			expect: func() graph.Directed { | ||||
| 				graphBuilder := simple.NewDirectedGraph() | ||||
| 				alphaVertex := NewGonumVertex(alphaNode(), graphBuilder.NewNode().ID()) | ||||
| 				graphBuilder.AddNode(alphaVertex) | ||||
| 				bravoVertex := NewGonumVertex(bravoNode(), graphBuilder.NewNode().ID()) | ||||
| 				graphBuilder.AddNode(bravoVertex) | ||||
| 				charlieVertex := NewGonumVertex(charlieNode(), graphBuilder.NewNode().ID()) | ||||
| 				graphBuilder.AddNode(charlieVertex) | ||||
| 				graphBuilder.SetEdge(simple.Edge{ | ||||
| 					F: alphaVertex, | ||||
| 					T: bravoVertex, | ||||
| 				}) | ||||
| 				graphBuilder.SetEdge(simple.Edge{ | ||||
| 					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 | ||||
| 			}(), | ||||
| 			expectNodes: []*dotVertex{ | ||||
| 				NewDOTVertex(alphaNode()), | ||||
| 				NewDOTVertex(bravoNode()), | ||||
| 				NewDOTVertex(charlieNode()), | ||||
| 				NewDOTVertex(deltaNode()), | ||||
| 				NewDOTVertex(foxtrotNode()), | ||||
| 				NewDOTVertex(golfNode()), | ||||
| 			}, | ||||
| 			expectEdges: []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")}, | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
|  | ||||
| 	for _, test := range tests { | ||||
| 		t.Run(test.name, func(t *testing.T) { | ||||
| 			actual := toGonumGraph(test.uidToNode) | ||||
|  | ||||
| 			compareGraphs(test.expect, actual, t) | ||||
| 			actualNodes, actualEdges := toDOTNodesAndEdges(test.uidToNode) | ||||
| 			compareGraphs(test.expectNodes, actualNodes, test.expectEdges, actualEdges, t) | ||||
| 		}) | ||||
| 	} | ||||
|  | ||||
| } | ||||
|  | ||||
| func TestToGonumGraphObj(t *testing.T) { | ||||
| func TestToDOTGraphObj(t *testing.T) { | ||||
| 	tests := []struct { | ||||
| 		name      string | ||||
| 		uidToNode map[types.UID]*node | ||||
| 		uids      []types.UID | ||||
| 		expect    graph.Directed | ||||
| 		name        string | ||||
| 		uidToNode   map[types.UID]*node | ||||
| 		uids        []types.UID | ||||
| 		expectNodes []*dotVertex | ||||
| 		expectEdges []dotEdge | ||||
| 	}{ | ||||
| 		{ | ||||
| 			name: "simple", | ||||
| @@ -272,24 +226,15 @@ func TestToGonumGraphObj(t *testing.T) { | ||||
| 				types.UID("charlie"): charlieNode(), | ||||
| 			}, | ||||
| 			uids: []types.UID{types.UID("bravo")}, | ||||
| 			expect: func() graph.Directed { | ||||
| 				graphBuilder := simple.NewDirectedGraph() | ||||
| 				alphaVertex := NewGonumVertex(alphaNode(), graphBuilder.NewNode().ID()) | ||||
| 				graphBuilder.AddNode(alphaVertex) | ||||
| 				bravoVertex := NewGonumVertex(bravoNode(), graphBuilder.NewNode().ID()) | ||||
| 				graphBuilder.AddNode(bravoVertex) | ||||
| 				charlieVertex := NewGonumVertex(charlieNode(), graphBuilder.NewNode().ID()) | ||||
| 				graphBuilder.AddNode(charlieVertex) | ||||
| 				graphBuilder.SetEdge(simple.Edge{ | ||||
| 					F: alphaVertex, | ||||
| 					T: bravoVertex, | ||||
| 				}) | ||||
| 				graphBuilder.SetEdge(simple.Edge{ | ||||
| 					F: alphaVertex, | ||||
| 					T: charlieVertex, | ||||
| 				}) | ||||
| 				return graphBuilder | ||||
| 			}(), | ||||
| 			expectNodes: []*dotVertex{ | ||||
| 				NewDOTVertex(alphaNode()), | ||||
| 				NewDOTVertex(bravoNode()), | ||||
| 				NewDOTVertex(charlieNode()), | ||||
| 			}, | ||||
| 			expectEdges: []dotEdge{ | ||||
| 				{F: types.UID("alpha"), T: types.UID("bravo")}, | ||||
| 				{F: types.UID("alpha"), T: types.UID("charlie")}, | ||||
| 			}, | ||||
| 		}, | ||||
| 		{ | ||||
| 			name: "missing", // synthetic vertex created | ||||
| @@ -297,11 +242,9 @@ func TestToGonumGraphObj(t *testing.T) { | ||||
| 				types.UID("alpha"):   alphaNode(), | ||||
| 				types.UID("charlie"): charlieNode(), | ||||
| 			}, | ||||
| 			uids: []types.UID{types.UID("bravo")}, | ||||
| 			expect: func() graph.Directed { | ||||
| 				graphBuilder := simple.NewDirectedGraph() | ||||
| 				return graphBuilder | ||||
| 			}(), | ||||
| 			uids:        []types.UID{types.UID("bravo")}, | ||||
| 			expectNodes: []*dotVertex{}, | ||||
| 			expectEdges: []dotEdge{}, | ||||
| 		}, | ||||
| 		{ | ||||
| 			name: "drop-no-ref", | ||||
| @@ -311,11 +254,9 @@ func TestToGonumGraphObj(t *testing.T) { | ||||
| 				types.UID("charlie"): charlieNode(), | ||||
| 				types.UID("echo"):    echoNode(), | ||||
| 			}, | ||||
| 			uids: []types.UID{types.UID("echo")}, | ||||
| 			expect: func() graph.Directed { | ||||
| 				graphBuilder := simple.NewDirectedGraph() | ||||
| 				return graphBuilder | ||||
| 			}(), | ||||
| 			uids:        []types.UID{types.UID("echo")}, | ||||
| 			expectNodes: []*dotVertex{}, | ||||
| 			expectEdges: []dotEdge{}, | ||||
| 		}, | ||||
| 		{ | ||||
| 			name: "two-chains-from-owner", | ||||
| @@ -328,25 +269,15 @@ func TestToGonumGraphObj(t *testing.T) { | ||||
| 				types.UID("golf"):    golfNode(), | ||||
| 			}, | ||||
| 			uids: []types.UID{types.UID("golf")}, | ||||
| 			expect: func() graph.Directed { | ||||
| 				graphBuilder := simple.NewDirectedGraph() | ||||
| 				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 | ||||
| 			}(), | ||||
| 			expectNodes: []*dotVertex{ | ||||
| 				NewDOTVertex(deltaNode()), | ||||
| 				NewDOTVertex(foxtrotNode()), | ||||
| 				NewDOTVertex(golfNode()), | ||||
| 			}, | ||||
| 			expectEdges: []dotEdge{ | ||||
| 				{F: types.UID("delta"), T: types.UID("foxtrot")}, | ||||
| 				{F: types.UID("foxtrot"), T: types.UID("golf")}, | ||||
| 			}, | ||||
| 		}, | ||||
| 		{ | ||||
| 			name: "two-chains-from-child", | ||||
| @@ -359,25 +290,15 @@ func TestToGonumGraphObj(t *testing.T) { | ||||
| 				types.UID("golf"):    golfNode(), | ||||
| 			}, | ||||
| 			uids: []types.UID{types.UID("delta")}, | ||||
| 			expect: func() graph.Directed { | ||||
| 				graphBuilder := simple.NewDirectedGraph() | ||||
| 				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 | ||||
| 			}(), | ||||
| 			expectNodes: []*dotVertex{ | ||||
| 				NewDOTVertex(deltaNode()), | ||||
| 				NewDOTVertex(foxtrotNode()), | ||||
| 				NewDOTVertex(golfNode()), | ||||
| 			}, | ||||
| 			expectEdges: []dotEdge{ | ||||
| 				{F: types.UID("delta"), T: types.UID("foxtrot")}, | ||||
| 				{F: types.UID("foxtrot"), T: types.UID("golf")}, | ||||
| 			}, | ||||
| 		}, | ||||
| 		{ | ||||
| 			name: "two-chains-choose-both", | ||||
| @@ -390,98 +311,125 @@ func TestToGonumGraphObj(t *testing.T) { | ||||
| 				types.UID("golf"):    golfNode(), | ||||
| 			}, | ||||
| 			uids: []types.UID{types.UID("delta"), types.UID("charlie")}, | ||||
| 			expect: func() graph.Directed { | ||||
| 				graphBuilder := simple.NewDirectedGraph() | ||||
| 				alphaVertex := NewGonumVertex(alphaNode(), graphBuilder.NewNode().ID()) | ||||
| 				graphBuilder.AddNode(alphaVertex) | ||||
| 				bravoVertex := NewGonumVertex(bravoNode(), graphBuilder.NewNode().ID()) | ||||
| 				graphBuilder.AddNode(bravoVertex) | ||||
| 				charlieVertex := NewGonumVertex(charlieNode(), graphBuilder.NewNode().ID()) | ||||
| 				graphBuilder.AddNode(charlieVertex) | ||||
| 				graphBuilder.SetEdge(simple.Edge{ | ||||
| 					F: alphaVertex, | ||||
| 					T: bravoVertex, | ||||
| 				}) | ||||
| 				graphBuilder.SetEdge(simple.Edge{ | ||||
| 					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 | ||||
| 			}(), | ||||
| 			expectNodes: []*dotVertex{ | ||||
| 				NewDOTVertex(alphaNode()), | ||||
| 				NewDOTVertex(bravoNode()), | ||||
| 				NewDOTVertex(charlieNode()), | ||||
| 				NewDOTVertex(deltaNode()), | ||||
| 				NewDOTVertex(foxtrotNode()), | ||||
| 				NewDOTVertex(golfNode()), | ||||
| 			}, | ||||
| 			expectEdges: []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")}, | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
|  | ||||
| 	for _, test := range tests { | ||||
| 		t.Run(test.name, func(t *testing.T) { | ||||
| 			actual := toGonumGraphForObj(test.uidToNode, test.uids...) | ||||
|  | ||||
| 			compareGraphs(test.expect, actual, t) | ||||
| 			actualNodes, actualEdges := toDOTNodesAndEdgesForObj(test.uidToNode, test.uids...) | ||||
| 			compareGraphs(test.expectNodes, actualNodes, test.expectEdges, actualEdges, t) | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func compareGraphs(expected, actual graph.Directed, 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)) | ||||
|  | ||||
| func compareGraphs(expectedNodes, actualNodes []*dotVertex, expectedEdges, actualEdges []dotEdge, t *testing.T) { | ||||
| 	if len(expectedNodes) != len(actualNodes) { | ||||
| 		t.Fatal(spew.Sdump(actual)) | ||||
| 		t.Fatal(spew.Sdump(actualNodes)) | ||||
| 	} | ||||
|  | ||||
| 	for i := range expectedNodes { | ||||
| 		currExpected := *expectedNodes[i].(*gonumVertex) | ||||
| 		currActual := *actualNodes[i].(*gonumVertex) | ||||
| 		currExpected := expectedNodes[i] | ||||
| 		currActual := actualNodes[i] | ||||
| 		if currExpected.uid != currActual.uid { | ||||
| 			t.Errorf("expected %v, got %v", spew.Sdump(currExpected), spew.Sdump(currActual)) | ||||
| 		} | ||||
|  | ||||
| 		expectedFrom := append([]graph.Node{}, expected.From(expectedNodes[i].ID()).(graph.NodeSlicer).NodeSlice()...) | ||||
| 		actualFrom := append([]graph.Node{}, actual.From(actualNodes[i].ID()).(graph.NodeSlicer).NodeSlice()...) | ||||
| 		sort.Sort(gonumByUID(expectedFrom)) | ||||
| 		sort.Sort(gonumByUID(actualFrom)) | ||||
| 		if len(expectedFrom) != len(actualFrom) { | ||||
| 			t.Errorf("%q: expected %v, got %v", currExpected.uid, spew.Sdump(expectedFrom), spew.Sdump(actualFrom)) | ||||
| 		} | ||||
| 		for i := range expectedFrom { | ||||
| 			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)) | ||||
| 			} | ||||
| 	} | ||||
| 	if len(expectedEdges) != len(actualEdges) { | ||||
| 		t.Fatal(spew.Sdump(actualEdges)) | ||||
| 	} | ||||
| 	for i := range expectedEdges { | ||||
| 		currExpected := expectedEdges[i] | ||||
| 		currActual := actualEdges[i] | ||||
| 		if currExpected != currActual { | ||||
| 			t.Errorf("expected %v, got %v", spew.Sdump(currExpected), spew.Sdump(currActual)) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| 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) } | ||||
| func (s gonumByUID) Swap(i, j int) { s[i], s[j] = s[j], s[i] } | ||||
| 	for _, tc := range testcases { | ||||
| 		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 { | ||||
| 	lhs := s[i].(*gonumVertex) | ||||
| 	lhsUID := string(lhs.uid) | ||||
| 	rhs := s[j].(*gonumVertex) | ||||
| 	rhsUID := string(rhs.uid) | ||||
|  | ||||
| 	return lhsUID < rhsUID | ||||
| 			if e, a := string(goldenData), string(b.Bytes()); cmp.Diff(e, a) != "" { | ||||
| 				t.Logf("got\n%s", string(a)) | ||||
| 				t.Fatalf("unexpected diff:\n%s", cmp.Diff(e, a)) | ||||
| 			} | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
|   | ||||
							
								
								
									
										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
	 Kubernetes Prow Robot
					Kubernetes Prow Robot